Ubuntu 22.04 下編譯 gcc 4.9.4

Ubuntu 22.04 中默認的 gcc 是 11.3,由于一些原因需要安裝一個老版本的 gcc。在 http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.9.4/ 上下載了 gcc 4.9.4,是 gcc4 的最后版本。本以為解壓后直接 ./configure && make 就行,結果遇到了很多問題。首先,應該運行 ./contrib/download_prerequisites 下載依賴的包,它會自動下載如下依賴包并把它們解壓好備用,不用自己額外操作。然后才是 configure 和 make。

cloog-0.18.1.tar.gz
gmp-4.3.2.tar.bz2
isl-0.12.2.tar.bz2
mpc-0.8.1.tar.gz
mpfr-2.4.2.tar.bz2

問題一

最初用的 configure 選項是
./configure --prefix=/opt/gcc-4.9.4 --disable-multilib --enable-languages=c,c++,fortran --build=x86_64-linux CFLAGS=-march=znver3 CXXFLAGS=-march=znver3
結果其中的 -march=znver3 本是想著根據(jù) AMD CPU的架構提高下性能,誰知道會造成后面類似 xgcc: error: unrecognized command line option '-V' xgcc: fatal error: no input files 錯誤提示,然而這只是表象,這句本身其實并不是錯誤而是在用編譯出的 xgcc 嘗試可用的版本參數(shù) -v, -V 等,但卻很迷惑人。最終錯誤在哪兒也沒完全明白,感覺似乎是編譯出的gcc用 -march=znver3 參數(shù)時出的問題??傊灰眠@個參數(shù)就是了,于是 configure 如下

/configure --prefix=/opt/gcc-4.9.4 --disable-multilib  --enable-languages=c,c++,fortran --build=x86_64-linux

其中 --enable-languages 如果不指定會編譯出一大堆語言,沒必要。

問題二

../.././gcc/reload1.c: In function ‘void init_reload()’:
../.././gcc/reload1.c:89:24: error: use of an operand of type ‘bool’ in ‘operator++’ is forbidden in C++17
   89 |   (this_target_reload->x_spill_indirect_levels)
      |   ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~

該錯誤是由于某些語法在 c++17 標準中不在允許,而 gcc 11.3 版本默認好像是用的 C++17 標準,所以有如上錯誤。最初想在 configure 時通過 CXXFLAGS 指定更低的標準比如 -std=c++03,然而發(fā)現(xiàn)這同樣會帶來后面的一些問題,因為后面還會使用較高標準。而且我們發(fā)現(xiàn) host-x86_64-linux/gcc 下的 Makefile 里根本沒有使用我指定的 -std 選項,估計也是這個原因吧。其實這個這在這一處出現(xiàn),可以直接切換到 host-x86_64-linux/gcc 目錄下,把出錯的那個命令加上 -std=c++03 參數(shù)后重新執(zhí)行一下就行了。然后再回到頂層目錄接著 make 即可。

問題三

接下來出現(xiàn)的一系列編譯錯誤和 https://blog.csdn.net/tuibianhuaisheng/article/details/115399019 這里的情況幾乎一樣

(1) ucontext

./md-unwind-support.h: 在函數(shù)‘x86_64_fallback_frame_state’中:
./md-unwind-support.h:65:47: 錯誤: dereferencing pointer to incomplete type
       sc = (struct sigcontext *) (void *) &uc_->uc_mcontext;
                                               ^
make[3]: *** [../.././libgcc/shared-object.mk:14:unwind-dw2.o] 錯誤 1
cd /home/XXXX/software/gcc-4.9.4/x86_64-linux/libgcc

報錯是在第65行,不過要該第61行:
struct ucontext *uc_ = context->cfa; => struct ucontext_t *uc_ = context->cfa;

(2) 致命錯誤: sys/ustat.h

參考 https://reviews.llvm.org/D47165

  • 把文件 sanitizer_common/sanitizer_common_syscalls.inc 中兩處的 #if !SANITIZER_ANDROID改為#if !SANITIZER_LINUX && !SANITIZER_ANDROID
  • 將文件 sanitizer_common/sanitizer_platform_limits_posix.cc 中包含 ustat 的兩行注釋掉。

(3) assertion_failed__931

根據(jù)數(shù)字 931 把文件 sanitizer_common/sanitizer_platform_limits_posix.cc 中的第 931 行注釋掉。

(4) handler_stack 問題

最初的錯誤忘了保留了,網(wǎng)上找到了類似的如下

參考 https://reviews.llvm.org/D35246

  • sanitizer_common/sanitizer_linux.h 文件中 struct sigaltstack; 這行去掉,之后兩處出現(xiàn)的 struct sigaltstack 都換成 void。
  • sanitizer_common/sanitizer_linux.cc 文件中兩處出現(xiàn)的 struct sigaltstack 都換成 void
  • sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc 中的 struct sigaltstack handler_stack; 換成 stack_t handler_stack;。
  • tsan/rtl/tsan_platform_linux.cc 文件中 __res_state *statp = (__res_state*)state; 換成 struct __res_state *statp = (struct __res_state*)state;。

(5) SIGSEGV 問題

在文件 libsanitizer/asan/asan_linux.cc 中添加頭文件 #include <signal.h> 即可。

解決掉上述問題后裝上了 gcc 4.9.4。最后配置一下 module 文件如下:

#%Module1.0
proc ModulesHelp { } {
    puts stderr "GNU C/C++/Fortran Compiler"
    puts stderr "See http://gcc.gnu.org/"
}

#conflict compiler/gcc

set             GCC_HOME                /opt/gcc-4.9.4

prepend-path    PATH                    ${GCC_HOME}/bin
prepend-path    INFOPATH                ${GCC_HOME}/share/info
prepend-path    LIBRARY_PATH            ${GCC_HOME}/lib64:${GCC_HOME}/lib/gcc/x86_64-linux/4.9.4
prepend-path    LD_LIBRARY_PATH         ${GCC_HOME}/lib64:${GCC_HOME}/lib/gcc/x86_64-linux/4.9.4
prepend-path    MANPATH                 ${GCC_HOME}/share/man
prepend-path    C_INCLUDE_PATH          ${GCC_HOME}/include/c++/4.9.4:${GCC_HOME}/include/c++/4.9.4/x86_64-linux:/usr/include/x86_64-linux-gnu
prepend-path    CPLUS_INCLUDE_PATH      ${GCC_HOME}/include/c++/4.9.4:${GCC_HOME}/include/c++/4.9.4/x86_64-linux:/usr/include/x86_64-linux-gnu

注意其中 include 最后還加上了系統(tǒng)的 路徑,否則 times.h 等文件會找不到。

吐槽一下

簡書也真夠坑人的,不知道什么原因,貼的代碼無法保存。編輯的時候預覽沒問題,然而查看歷史版本,某段代碼之后就根本不保存,發(fā)布完這部分內(nèi)容也沒有!注意還不是說只有它認為有問題的代碼部分無法保存,而是從那個地方起后面的都無法保存!無奈,只能把無法保存的代碼截圖貼上了,真是夠氣人的!

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容