Centos下GLIBCXX_3.4.20的问题

最近在使用docker-compose构建项目时打包前端代码时使用gulp工具构建时总是提示缺失GLIBCXX_3.4.20,按照网上各种水贴都试了一遍,发现没有效果,最后只能从源码升级GCC,把编译好的libstdc++链接到新的库上。

最近在使用docker-compose构建项目时打包前端代码时出现了下面这个奇怪的问题:

[gulp@4.0.0] link /usr/local/node-v8.11.1-linux-x64/bin/gulp@ -> /usr/local/node-v8.11.1-linux-x64/lib/node_modules/gulp/bin/gulp.js
✔ Installed 17 packages
✔ Linked 0 latest versions
✔ Run 0 scripts
✔ All packages installed (used 17ms(network 14ms), speed 0B/s, json 0(0B), tarball 0B)
module.js:681
  return process.dlopen(module, path._makeLong(filename));
                 ^

Error: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /opt/apps/mo_server-service-vip_ad_param/web/node_modules/node-sass/vendor/linux-x64-57/binding.node)
    at Object.Module._extensions..node (module.js:681:18)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at module.exports (/opt/apps/mo_server-service-vip_ad_param/web/node_modules/node-sass/lib/binding.js:19:10)
    at Object.<anonymous> (/opt/apps/mo_server-service-vip_ad_param/web/node_modules/node-sass/lib/index.js:14:35)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)

初步分析:

  • gulp构建工具已经安装成功,但是在构建项目的时候,出现了这个错误,原因是node-sass需要借助系统libstdc++.so.6中的GLIBCXX_3.4.20版本,而本机没有,所以报错。

于是,该怎么得到这个版本呢?一开始是网上各种搜索资料,结果基本上都是一些水贴,误人子弟,浪费时间。

于是,先确定系统都支持哪些版本:

➜  xxx git:(sre) ✗ docker exec -it 61f013713e38 /bin/bash
[root@61f013713e38 /]# find / -name libstdc++.so.6
/usr/lib64/libstdc++.so.6
[root@61f013713e38 /]# strings /usr/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

好了,到此为止,发现确实没有GLIBCXX_3.4.20,那么到底这个是什么东东呢?

于是,查看在哪个安装包下提供了这个libstdc++.so.6

[root@61f013713e38 /]# yum list | grep libstdc++
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast

libstdc++.x86_64                          4.8.5-11.el7                   @CentOS
compat-libstdc++-33.i686                  3.2.3-72.el7                   base   
compat-libstdc++-33.x86_64                3.2.3-72.el7                   base   
libstdc++.i686                            4.8.5-36.el7                   base   
libstdc++.x86_64                          4.8.5-36.el7                   base   
libstdc++-devel.i686                      4.8.5-36.el7                   base   
libstdc++-devel.x86_64                    4.8.5-36.el7                   base   
libstdc++-docs.x86_64                     4.8.5-36.el7                   base   
libstdc++-static.i686                     4.8.5-36.el7                   base   
libstdc++-static.x86_64                   4.8.5-36.el7                   base

发现最新的只有4.8.5的版本,所以寻找了Linux的国内镜像源,这里是阿里的 https://centos.pkgs.org/7/centos-updates-x86_64/libstdc++-4.8.5-36.el7_6.1.i686.rpm.html

发现里边的最高版本也只有支持到GLIBCXX_3.4.19

所以,是系统不支持?

好了,接下来准备升级更外一层的安装包:gcc,这里不用源码安装是因为个人感觉会有很高几率失败,基于网络,或者其他的一些因素(编译时间无限长),升级之前为4.8.5

[root@61f013713e38 /]# gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

接下来执行升级操作:

yum install centos-release-scl –y
yum install devtoolset-3-toolchain –y
scl enable devtoolset-3 bash

升级完成后:

[root@61f013713e38 /]# gcc --version
gcc (GCC) 4.9.2 20150212 (Red Hat 4.9.2-6)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

看样子是已经成功了。此时,我们再来看一下提供了libstdc++.so.6的相关包信息

[root@61f013713e38 /]# yum list | grep libstdc++
devtoolset-3-libstdc++-devel.x86_64        4.9.2-6.el7            @centos-sclo-rh
libstdc++.x86_64                           4.8.5-11.el7           @CentOS       
compat-libstdc++-33.i686                   3.2.3-72.el7           base          
compat-libstdc++-33.x86_64                 3.2.3-72.el7           base          
devtoolset-3-libstdc++-docs.x86_64         4.9.2-6.el7            centos-sclo-rh
devtoolset-4-libstdc++-devel.x86_64        5.3.1-6.1.el7          centos-sclo-rh
devtoolset-4-libstdc++-docs.x86_64         5.3.1-6.1.el7          centos-sclo-rh
devtoolset-6-libstdc++-devel.x86_64        6.3.1-3.1.el7          centos-sclo-rh
devtoolset-6-libstdc++-docs.x86_64         6.3.1-3.1.el7          centos-sclo-rh
devtoolset-7-libstdc++-devel.x86_64        7.3.1-5.15.el7         centos-sclo-rh
devtoolset-7-libstdc++-docs.x86_64         7.3.1-5.15.el7         centos-sclo-rh
devtoolset-8-libstdc++-devel.x86_64        8.2.1-3.el7            centos-sclo-rh
devtoolset-8-libstdc++-docs.x86_64         8.2.1-3.el7            centos-sclo-rh
libstdc++.i686                             4.8.5-36.el7_6.1       updates       
libstdc++.x86_64                           4.8.5-36.el7_6.1       updates       
libstdc++-devel.i686                       4.8.5-36.el7_6.1       updates       
libstdc++-devel.x86_64                     4.8.5-36.el7_6.1       updates       
libstdc++-docs.x86_64                      4.8.5-36.el7_6.1       updates       
libstdc++-static.i686                      4.8.5-36.el7_6.1       updates       
libstdc++-static.x86_64                    4.8.5-36.el7_6.1       updates

发现已经多出来了一些,比如第一个,那是否可以安装下这个试试呢?

yum update
yum -y install bzip2

然后我们再来看下现在有哪些地方可以提供我们需要的.so

[root@61f013713e38 /]# find / -name "libstdc++.so*"
/opt/rh/devtoolset-3/root/usr/lib/gcc/x86_64-redhat-linux/4.9.2/32/libstdc++.so
/opt/rh/devtoolset-3/root/usr/lib/gcc/x86_64-redhat-linux/4.9.2/libstdc++.so
/usr/lib/libstdc++.so.6
/usr/lib/libstdc++.so.6.0.19
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.pyo
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.pyc
/usr/share/gdb/auto-load/usr/lib64/libstdc++.so.6.0.19-gdb.py
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.19-gdb.pyo
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.19-gdb.pyc
/usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.19-gdb.py
/usr/lib64/libstdc++.so.6
/usr/lib64/libstdc++.so.6.0.19

此时,发现多了一些出来了,我们随机挑一个最新的来看看效果,发现啥也找不到,此时,还是没有找到我们想要的GLIBCXX_3.4.20,接下来我们手动安装gcc7.2

wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-7.2.0/gcc-7.2.0.tar.gz
tar xvzf gcc-7.2.0.tar.gz
cd gcc-7.2.0
./contrib/download_prerequisites #这一步可谓是很坑了,要很长很长时间,速度又慢

输出如下:

2019-04-03 08:32:26 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2 [2383840] -> "./gmp-6.1.0.tar.bz2" [1]
2019-04-03 08:33:01 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 [1279284] -> "./mpfr-3.1.4.tar.bz2" [1]
2019-04-03 08:56:13 URL: ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz [499744] -> "./mpc-1.0.3.tar.gz" [3]

重试了N次后终于算是成功了。

mkdir  gcc-build
cd   gcc-build
../configure --prefix=/usr/local/gcc-7.2.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++

配置完成后make install一下

make #又是一个很耗时间的操作。。。
make install 

终于安装成功了

[root@61f013713e38 bin]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-7.2.0/libexec/gcc/x86_64-pc-linux-gnu/7.2.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../configure --prefix=/usr/local/gcc-7.2.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++
Thread model: posix
gcc version 7.2.0 (GCC)

接下来继续查看有哪些库

[root@61f013713e38 /]# find / -name "libstdc++.so*"
/gcc-7.2.0/gcc-build/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24

我们再来看下是否已经包含有了GLIBCXX_3.4.20

[root@479096fb67a3 web]# strings /gcc-7.2.0/gcc-build/stage1-x86_64-pc-linux-gnu/libstdc++-v3/src/.libs/libstdc++.so.6.0.24 | grep GLIBC
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_3.4.20
GLIBCXX_3.4.21
GLIBCXX_3.4.22
GLIBCXX_3.4.23
GLIBCXX_3.4.24
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.14
GLIBC_2.16
GLIBC_2.17
GLIBC_2.3.2
GLIBCXX_DEBUG_MESSAGE_LENGTH

发现已经有了,真是惊喜。那接下来就简单了

cp libstdc++.so.6.0.24 /usr/lib64
cd /usr/lib64
rm -rf libstdc++.so.6
ln -s libstdc++.so.6.0.24 libstdc++.so.6

最后再执行我们最开始的gulp build,成功!

[root@479096fb67a3 web]# gulp build
[09:57:44] Using gulpfile /opt/apps/web/gulpfile.js
(node:251) ExperimentalWarning: The http2 module is an experimental API.
[09:57:44] Starting 'cssTask'...
开始执行css压缩任务
[09:57:44] Finished 'cssTask' after 14 ms
[09:57:44] Starting 'jsTask'...
开始执行js压缩混淆任务 dist/js
压缩类库js
压缩自己的js文件
压缩模块化的js
压缩注入js
复制null.js
[09:57:44] Finished 'jsTask' after 12 ms
[09:57:44] Starting 'htmlTask'...
开始执行html模版合并和静态文件转移任务
[09:57:44] Finished 'htmlTask' after 4.39 ms
[09:57:44] Starting 'build'...
[09:57:44] Finished 'build' after 30 μs

总觉得Centos不如ubuntu方便,特别是设计到这种需要手动编译的东东。好在最后是完美解决了。

赞赏我吗