CentOS7.9升级gcc版本

1,141 阅读3分钟

因为项目需要用到node18版本,在安装node18的时候,服务器报如下错误:

bin/node: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by bin/node) 
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by bin/node) 
bin/node: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by bin/node)

根据报错提醒首先分别查看一下服务器上CXXABIGLIBCXX的版本:

[root@zkzn139 ~]# strings /lib64/libstdc++.so.6 |grep CXXABI_
**CXXABI_** 1.3
**CXXABI_** 1.3.1
**CXXABI_** 1.3.2
**CXXABI_** 1.3.3
**CXXABI_** 1.3.4
**CXXABI_** 1.3.5
**CXXABI_** 1.3.6
**CXXABI_** 1.3.7
**CXXABI_** TM_1
[root@zkzn139 ~]# strings /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**_DEBUG_MESSAGE_LENGTH

发现CXXABIGLIBCXX的最高版本分别是:1.3.73.4.19,不符合上面报错信息中所提示的1.3.93.4.21

网上搜了一下这两个报错信息是gcc版本低导致的,需要升级一下gcc的版本,有两种升级方式,一种是通过yum方式升级,另一种是参照官网的方式升级,我先尝试了yum的方式,发现CentOS7.9支持的最高版本就是1.3.7= =,鉴于目前这台服务器上没有其他的项目,所以决定使用官网的方式,强制升级gcc版本。(注意!!!风险很大!!!最好先备份好,不然容易死机

首先从官网选择合适的版本进行下载:

cd /opt
wget https://ftp.gnu.org/gnu/gcc/gcc-8.5.0/gcc-8.5.0.tar.gz --no-check-certificate 
tar -xzvf gcc-8.5.0
cd gcc-8.5.0 
./contrib/download_prerequisites #这一步会下载一些依赖项

下载完成后,出现下面的提示就说明已经成功了:

gmp-6.1.0.tar.bz2: OK 
mpfr-3.1.4.tar.bz2: OK 
mpc-1.0.3.tar.gz: OK 
isl-0.18.tar.bz2: OK 
All prerequisites downloaded successfully.

有时候会报错如下图,是因为服务器没有安装bzip2导致的,直接yum -y install bzip2安装即可;

image.png

如果yum安装报错:

Loading mirror speeds from cached hostfile Could not retrieve mirrorlist 
http://mirrorlist.centos.org?arch=x86_64&release=7&repo=sclo-rh 
error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; 未知的错误"

是由于没有配置yum源,需要重新配置一下:

rm -f /etc/yum.repos.d/*
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
yum clean all
# 然后重新使用yum下载即可

完成上一步后开始一步步的执行编译和安装,这里需要注意一下,这行很重要!!! --prefix=HOME/local是修改了默认安装路径!!!!!修改后的安装路径是HOME/local是修改了默认安装路径!!!!!修改后的安装路径是HOME/local,需要在这里找到安装的gcc.

mkdir build #一定要创建一个新的文件夹
cd build/ 
../configure --disable-multilib --enable-languages=c,c++ --prefix=$HOME/local #配置!!!这行很重要!!! --prefix=$HOME/local是修改了默认安装路径!!!!!
make  #构建
make install #安装
export LD_LIBRARY_PATH=$HOME/local/lib64 #最后记得一定要配置path

其中在 make -j4 这一步,如果失败了可以试试直接make,时间可能会更长一些,整个过程大概执行了三四个小时吧。 如果make也不行,报错gmp有关的,可以删除build文件夹,从./contrib/download_prerequisites这一步重新开始下载,然后在创建build,进入build中重新make.

如果出现以下报错,这时候直接执行yum install gcc gcc-c++然后重新make.

make[2]: Leaving directory `/usr/local/gcc-10.1.0/build' 
make[1]: *** [stage1-bubble] 错误 2 
make[1]: Leaving directory `/usr/local/gcc-10.1.0/build' 
make: *** [all] 错误 2

安装完成以后,使用gcc -v检查下版本,如果版本还是老版本的话,需要做一下软链接:

cd /usr/bin # 可以先使用whereis gcc 查询下gcc的位置,分别使用 ./gcc -v 测试一下版本,看看用的是哪个。
mv gcc gcc_old # 给旧的进行备份
ln -s /root/local/bin/gcc /usr/bin/gcc # -s 后第一个链接是你安装的新版本gcc地址,后者是系统默认地址做一下软连接

除了gcc以外,还有g++也需要配置,使用g++ -v检查下版本,如果版本还是老版本的话,也需要做一下软链接:

cd /usr/bin # 可以先使用whereis g++ 查询下g++的位置,分别使用 ./g++ -v 测试一下版本,看看用的是哪个。
mv g++ g++_old # 给旧的进行备份
ln -s /root/local/bin/g++ /usr/bin/g++ # -s 后第一个链接是你安装的新版本g++地址,后者是系统默认地址做一下软连接

最后再使用上面的命令检查一下当前gcc/g++版本,会发现已经升级成功了,但是这时又发现了一个问题就是,每次只要退出了命令行在重新登陆以后,就会发现gcc版本又回退了,还会报错:

/usr/lib64/libstdc++.so.6: version "CXXABI_1.3.9" not found

找了一下发现是因为/usr/lib64/libstdc++.so.6动态库还没有配置正确的版本的源,使用ls 命令查看该文件可以看到动态库是一个软链接:

#ls -l /usr/lib64/libstdc++.so.6
lrwxrwxrwx 1 root root 19 Aug 24 12:28 /usr/lib64/libstdc++.so.6 -> libstdc++.so.6.0.13

需要手动更新动态库,动态库位于gcc编译目录下,可以在遍历目录下查找:

#cd **/gcc-8.5.0/build/ # build是编译时创建的目录
#find . -name "libstdc++.so.*"
./prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24
./prev-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
./stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24
./stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6
./x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24
./x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6

有三个不同版本的库目录,prev 开头的应该是预览版本,stage1 不知道是什么版本,用第三个就好了。

>/bin/cp -f x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6* /usr/lib # 拷贝过去
>rm -f /usr/lib64/libstdc++.so.6 # 移出旧链接
> ln -s /usr/lib/libstdc++.so.6.0.24 /usr/lib64/libstdc++.so.6 # 创建新链接

然后此时退出命令行工具后再次登录,查看gcc版本也还是升级后的了。

如果此时输入命令行gcc -v发现还是低一点的版本,此时就需要检查一下全局各个gcc版本和服务器的环境变量PATH了。

先检查一下全局有多少个gcc版本,使用whereis g++ 查询下g++的位置,然后cd到各个目录,分别使用 ./g++ -v 检查一下该目录下gcc的版本

>whereis gcc
gcc: /usr/bin/gcc /usr/lib/gcc /usr/libexec/gcc /opt/rh/devtoolset-8/root/usr/bin/gcc /usr/share/man/man1/gcc.1.gz

可以看到好几个目录下都存在,可以进入各自的上一级目录查看eg:/usr/bin,执行./gcc -v看看自己安装的版本在哪个目录下,以及当前的版本在哪个目录下。

>which gcc
#很可能会看到一下输出
>/opt/rh/devtoolset-8/root/usr/bin/gcc

然后检查PATH,echo $PATH

会看到以下输出:

/opt/rh/devtoolset-8/root/usr/bin:/usr/local/bin:/usr/bin:...

这里可以清楚看到 /opt/rh/devtoolset-8/root/usr/bin 排在前面,如果想要gcc使用自己的版本这时候只需要配置一下环境变量就行,而且尽量要保证不影响其他的用户和环境变量,这时候最好使用别名:

1、在你的 ~/.bashrc 或 ~/.bash_profile 添加以下内容:
# 优先使用 /usr/bin 的 gcc 和 g++
alias gcc='/usr/bin/gcc'
alias g++='/usr/bin/g++'
执行source让配置生效:
~/.bashrc
验证gcc(还可以顺带验证一下g++)
[root@iZ2]# which gcc
alias gcc='/usr/bin/gcc'
/usr/bin/gcc

[root@iZ2]# gcc -v
使用内建 specs。
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/root/local/libexec/gcc/x86_64-pc-linux-gnu/8.5.0/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:../configure --disable-multilib --enable-languages=c,c++ --prefix=/root/local
线程模型:posix
gcc 版本 8.5.0 (GCC)

到此为止所有的相关安装和配置均已结束,可以正常使用8.5.0版本的gcc了。