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)容也沒有!注意還不是說只有它認為有問題的代碼部分無法保存,而是從那個地方起后面的都無法保存!無奈,只能把無法保存的代碼截圖貼上了,真是夠氣人的!