手动下载gcc-4.8.5源码在centos6.9上配置多版本GCC

在一个系统较老的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

其实刚才那个库是向下兼容的,也可以直接用软链接来解决。

参考

  1. https://stackoverflow.com/questions/7412548/error-gnu-stubs-32-h-no-such-file-or-directory-while-compiling-nachos-source
  2. https://wiki.mikejung.biz/Gcc_CentOS
  3. https://gcc.gnu.org/