在一个系统较老的centos(6.9)上编译安装gcc4.8.5,系统源里面带的是4.7.2,对C++11中的特性支持不完整,所以需要手动编译一份新版本。
以为会很简单,直接下载源码,根据readme配置相关依赖源码,然而最后还是编译的时候报错,所以记录下来。
GCC源码及源码依赖
安装基本编译依赖:
1 2
| sudo yum groupinstall "Development tools" sudo yum install glibc-devel.i686 glibc-i686
|
注意后面那两个包如果不安装会有错误fatal error: gnu/stubs-32.h: No such file or directory
。
GCC官网下载你所需要的版本源码,我用的是GCC 4.8.5大概500多Mb的压缩包:https://gcc.gnu.org/
除了GCC源码之外,它还需要以下依赖的源码,这里附上我用的版本号:
其中前3个依赖也可以通过GCC源码包中的脚本./contrib/download_prerequisites
自动帮你下载好,如果你的网络环境跟我一样(公司内网),那就自己去下面那个链接里面下载。
所需要的依赖源码在这里都可以找到:https://gcc.gnu.org/pub/gcc/infrastructure/,如果版本不对,可以自己去网上搜索一个老一些版本。
1 2 3 4 5 6
| MPFR=mpfr-2.4.2 GMP=gmp-4.3.2 MPC=mpc-0.8.1
isl-0.11.1.tar.bz2 cloog-0.18.0.tar.gz
|
确认isl
使用0.12
的版本会出错。
把这些源码解压到gcc源码要目录并重命名为相应不带版本后缀的文件夹名称,过程命令如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| $ cd ~ $ wget https://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz $ wget https://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 $ wget https://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 $ wget https://gcc.gnu.org/pub/gcc/infrastructure/isl-0.11.1.tar.bz2 $ wget https://gcc.gnu.org/pub/gcc/infrastructure/cloog-0.18.1.tar.gz $ wget http://ftp.gnu.org/gnu/gcc/gcc-4.8.5/gcc-4.8.5.tar.gz $ tar -xzvf gcc-4.8.5.tar.gz $ cd gcc-4.8.5 $ tar -zxvf ../mpc-1.0.3.tar.gz $ tar -jxvf ../mpfr-3.1.4.tar.bz2 $ tar -jxvf ../gmp-6.1.0.tar.bz2 $ tar -jxvf ../isl-0.11.1.tar.bz2 $ tar -zxvf ../cloog-0.18.1.tar.gz $ mv mpc-1.0.3 mpc $ mv mpfr-3.1.4 mpfr $ mv gmp-6.1.0 gmp $ mv isl-0.11.1 isl $ mv cloog-0.18.1 cloog
|
环境配置完成
编译安装
下面正常编译即可,通常不会有什么问题
1 2 3 4
| $ ./configure --prefix=/opt/gcc-4.8.5/ $ make -j8 $ make -k check $ sudo make install
|
如果./configure
不配置安装路径,会安装到默认路径,有可能会覆盖你当前的版本,如果没有特殊需要,可以直接覆盖安装,后面会省很多事。
配置版本选择
通过update-alternatives
命令添加版本切换:
首先重命名当前版本的
1 2
| $ sudo mv /usr/bin/gcc /usr/bin/gcc-4.4.7 $ sudo mv /usr/bin/g++ /usr/bin/g++-4.4.7
|
添加配置选择入口:
1 2 3 4 5
| $ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.4.7 $ sudo update-alternatives --install /usr/bin/gcc gcc /opt/gcc-4.8.5/bin/gcc
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.4.7 $ sudo update-alternatives --install /usr/bin/g++ g++ /opt/gcc-4.8.5/bin/g++
|
然后根据需要切换版本即可:
1 2
| $ sudo update-alternatives --config gcc $ sudo update-alternatives --config g++
|
想删除:
1
| $ sudo update-alternatives --remove gcc /usr/bin/gcc-4.4.7
|
问题
虽然我们的编译器已经可以切换到新版本了,但有些编译出来的库依赖在查找时依然是旧版本的库,例如有可能新编译的库运行时会报
1
| /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by...
|
查看该库会发现少了我们需要的版本:
1
| $ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
|
我这里的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_FORCE_NEW GLIBCXX_DEBUG_MESSAGE_LENGTH
|
而新库内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| $ strings /opt/gcc-4.8.5/lib64/libstdc++.so.6 | grep GLIBCXX GLIBCXX_3.4 GLIBCXX_3.4.1 GLIBCXX_3.4.2 GLIBCXX_3.4.3 GLIBCXX_3.4.4 GLIBCXX_3.4.5 GLIBCXX_3.4.6 GLIBCXX_3.4.7 GLIBCXX_3.4.8 GLIBCXX_3.4.9 GLIBCXX_3.4.10 GLIBCXX_3.4.11 GLIBCXX_3.4.12 GLIBCXX_3.4.13 GLIBCXX_3.4.14 GLIBCXX_3.4.15 GLIBCXX_3.4.16 GLIBCXX_3.4.17 GLIBCXX_3.4.18 GLIBCXX_3.4.19 GLIBCXX_FORCE_NEW GLIBCXX_DEBUG_MESSAGE_LENGTH
|
需要将新版本的库加入到系统查找路径:
1 2
| $ sudo echo `/opt/gcc-4.8.5/lib/../lib64` >> /etc/ld.so.conf $ sudo ldconfig
|
其实刚才那个库是向下兼容的,也可以直接用软链接来解决。
参考
- https://stackoverflow.com/questions/7412548/error-gnu-stubs-32-h-no-such-file-or-directory-while-compiling-nachos-source
- https://wiki.mikejung.biz/Gcc_CentOS
- https://gcc.gnu.org/