自定义编译GCC 13.3编译程序移植至CentOS7.5的兼容性配置咨询
问题
在CentOS 7.5系统中,我们从源码编译了GCC 13.3编译器,并使用该编译器通过命令g++ main.cc -std=c++20构建了测试程序,程序可正常运行。但将该程序交付给客户后,客户在仅安装默认GCC 4.8.5的同版本系统运行时,出现如下错误:
/a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /a.out) /a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.32' not found (required by /a.out) /a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /a.out) /a.out: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.29' not found (required by /a.out)
现咨询是否可配置该自定义编译的GCC,使其编译的程序具备可移植性?毕竟devtoolset-11编译的程序无需依赖编译器即可在目标机运行。
解决方案
可以通过调整GCC编译配置或程序编译参数实现可移植性,核心是让生成的程序兼容CentOS 7默认的老版本libstdc++环境:
1. 重新编译GCC时添加兼容配置
自定义编译GCC时,需要手动指定适配老系统的ABI和环境参数,这也是devtoolset能直接兼容的核心原因:
- 添加
--with-default-libstdcxx-abi=gcc4-compatible:强制使用兼容GCC 4.x版本的ABI - 添加
--disable-libstdcxx-dual-abi:关闭双ABI生成,避免依赖新特性的库版本 - 指定
--with-sysroot=/:让GCC编译时基于当前CentOS 7的系统根目录链接老版本依赖
示例配置命令:
./configure --prefix=/usr/local/gcc-13.3 --with-default-libstdcxx-abi=gcc4-compatible --disable-libstdcxx-dual-abi --with-sysroot=/ --enable-languages=c,c++
2. 编译程序时调整链接参数
如果不想重新编译GCC,可直接在编译程序时做兼容处理:
- 静态链接libstdc++:添加
-static-libstdc++参数,将libstdc++的代码打包到可执行文件中,彻底摆脱系统动态库依赖
示例编译命令:g++ main.cc -std=c++20 -static-libstdc++ - 显式指定兼容库路径:如果已编译好兼容的GCC库,编译程序时指定链接路径,并将配套的libstdc++库随程序交付
示例编译命令:
交付时需将g++ main.cc -std=c++20 -Wl,-rpath=/usr/local/gcc-13.3/lib64 -L/usr/local/gcc-13.3/lib64/usr/local/gcc-13.3/lib64下的libstdc++.so.6等库文件一并提供,或告知客户设置LD_LIBRARY_PATH指向该目录。
3. devtoolset兼容原理说明
devtoolset是RedHat针对老系统定制的工具链,编译阶段默认就启用了ABI兼容配置,生成的程序依赖的libstdc++版本刚好匹配CentOS 7的默认环境,所以无需额外操作即可运行。自定义编译GCC时必须手动配置这些参数才能达到同样效果。
内容的提问来源于stack exchange,提问作者d7d1cd
相关产品推荐
相关产品推荐

