Ubuntu 22.04 下编译 gcc 4.9.4

内容分享3周前发布
1 0 0

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 本是想着根据 AMD CPU的架构提高下性能,谁知道会造成后面类似 xgcc: error: unrecognized command line option -V xgcc: fatal error: no input files 错误提示,不过这只是表象,这句本身实则并不是错误而是在用编译出的 xgcc 尝试可用的版本参数 -v, -V 等,但却很迷惑人。最终错误在哪儿也没完全清楚,感觉似乎是编译出的gcc用 -march=znver3 参数时出的问题。总之,不要用这个参数就是了,于是 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,不过发现这同样会带来后面的一些问题,由于后面还会使用较高标准。而且我们发现 host-x86_64-linux/gcc 下的 Makefile 里根本没有使用我指定的 -std 选项,估计也是这个缘由吧。实则这个这在这一处出现,可以直接切换到 host-x86_64-linux/gcc 目录下,把出错的那个命令加上 -std=c++03 参数后重新执行一下就行了。然后再回到顶层目录接着 make 即可。

问题三

接下来出现的一系列编译错误和 https://blog.csdn.net/tuibianhuaisheng/article/details/115399019 这里的情况几乎一样

(1) ucontext

./md-unwind-support.h: 在函数‘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

Ubuntu 22.04 下编译 gcc 4.9.4

参考 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

Ubuntu 22.04 下编译 gcc 4.9.4

根据数字 931 把文件 sanitizer_common/sanitizer_platform_limits_posix.cc 中的第 931 行注释掉。

(4) handler_stack 问题

最初的错误忘了保留了,网上找到了类似的如下

Ubuntu 22.04 下编译 gcc 4.9.4

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

  • sanitizer_common/sanitizer_linux.h 文件中 struct sigaltstack; 这行去掉,之后两处出现的 struct sigaltstack 都换成 void
  • sanitizer_common/sanitizer_linux.cc 文件中两处出现的 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 问题

Ubuntu 22.04 下编译 gcc 4.9.4

在文件 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 最后还加上了系统的 路径,否则 times.h 等文件会找不到。

吐槽一下

简书也真够坑人的,不知道什么缘由,贴的代码无法保存。编辑的时候预览没问题,不过查看历史版本,某段代码之后就根本不保存,发布完这部分内容也没有!注意还不是说只有它认为有问题的代码部分无法保存,而是从那个地方起后面的都无法保存!无奈,只能把无法保存的代码截图贴上了,真是够气人的!

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...