Centos/Redhat_7.9升级GCC/GCC-C++

说明:
  GCC/GCC-C++编译器用于编译C/C++语言程序,在编译安装工具时需要用到高版本的gcc版本,可以根据需求安装多版本的gcc并使用Modules去管理,不要盲目升级后直接替换gcc。

查看当前系统gcc版本

[root@cs01 ~]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC
你已经找到了关键文件: ```bash find /opt/rh/gcc-toolset-11 -name "libasan_preinit.o" # 输出: /opt/rh/gcc-toolset-11/root/usr/lib/gcc/x86_64-redhat-linux/11/32/libasan_preinit.o ``` 这个路径说明: - `libasan_preinit.o` **确实存在** - 但它位于 **32位子目录**(`/32/`)中 → 表示它是用于 **32位程序(i686)的 ASan 初始化对象** - 而你的项目正在编译 **64位程序(x86_64)**,链接器会去查找 64 位版本的 `libasan_preinit.o`,但 **该文件在系统中不存在** --- ## 🧩 根本问题定位 > ❌ 缺失的是: > `/opt/rh/gcc-toolset-11/root/usr/lib/gcc/x86_64-redhat-linux/11/libasan_preinit.o` > (即 64 位版本) 而你找到的是 32 位版本(放在 `/32/` 目录下),所以 **链接 64 位可执行文件时无法使用它**。 这导致错误: ``` /opt/rh/gcc-toolset-11/root/usr/bin/ld: cannot find libasan_preinit.o: No such file or directory ``` --- ## ✅ 解决方案 ### ✅ 方案一:【推荐】关闭静态链接 ASan,改用动态链接 这是最稳妥、最兼容的方式。因为 RHEL/CentOS 的 SCL 工具链 **不提供 64 位 `libasan_preinit.o`**,所以不能进行静态链接。 #### 修改构建配置,移除 `-static-libasan` 检查是否在 CMake 或编译命令中添加了: ```cmake target_link_libraries(myapp -static-libasan) # 或 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan") ``` ✅ 改为仅使用动态 ASan: ```cmake add_compile_options(-fsanitize=address -fno-omit-frame-pointer) target_link_libraries(myapp -fsanitize=address) ``` 这样就不会尝试链接 `libasan_preinit.o`,而是依赖运行时共享库 `libasan.so`。 #### 验证 `libasan.so` 是否存在: ```bash find /opt/rh/gcc-toolset-11 -name "libasan.so*" ``` 你应该能看到类似输出: ``` /opt/rh/gcc-toolset-11/root/usr/lib64/libasan.so.6.0.0 /opt/rh/gcc-toolset-11/root/usr/lib64/libasan.so -> libasan.so.6.0.0 ``` 只要这个 `.so` 存在,动态 ASan 就可以正常工作。 --- ### ✅ 方案二:强制让链接器忽略 `libasan_preinit.o`(黑科技) 如果你确定不需要那个文件(比如实际只需要动态支持),可以通过覆盖链接器参数绕过。 #### 方法:设置 `LDFLAGS` 显式指定 `libasan.so` ```bash export LDFLAGS="-l:libasan.so -fsanitize=address" ``` 或者在 `make` 命令中直接传入: ```bash make -j2 LDFLAGS="-l:libasan.so -fsanitize=address" ``` 这会强制链接动态库而不是让链接器自动搜索并尝试加载 `libasan_preinit.o`。 --- ### ✅ 方案三:确认是否真的启用了 `-static-libasan` 运行以下命令查看具体编译链接命令: ```bash make -j2 VERBOSE=1 | grep -A5 -B5 "libasan_preinit\|sanitize" ``` 你会看到类似: ``` /opt/rh/gcc-toolset-11/root/usr/bin/g++ ... -fsanitize=address -static-libasan ... ``` 🔍 如果发现有 `-static-libasan`,这就是罪魁祸首! #### 如何禁用? - 检查 `CMakeLists.txt` 中是否有: ```cmake target_link_libraries(attrclient "-static-libasan") ``` - 或者通过外部变量传入了 `-DSTATIC_LIBASAN=ON` - 删除或注释掉即可 --- ### ✅ 方案四:手动创建一个空的 `libasan_preinit.o`(应急测试用) ⚠️ 注意:这是一个 **欺骗链接器的临时手段**,仅用于验证是否是“找不到文件”导致的问题,不保证程序能正确运行。 ```bash # 创建一个空的目标文件(占位符) echo 'void __asan_init() {}' | \ /opt/rh/gcc-toolset-11/root/usr/bin/g++ -x c -c -o /tmp/libasan_preinit.o - # 复制到期望路径(需要 sudo) sudo mkdir -p /opt/rh/gcc-toolset-11/root/usr/lib/gcc/x86_64-redhat-linux/11/ sudo cp /tmp/libasan_preinit.o /opt/rh/gcc-toolset-11/root/usr/lib/gcc/x86_64-redhat-linux/11/libasan_preinit.o ``` 然后再次运行 `make`,看是否能继续。 > ⚠️ 即使编译通过,程序也可能崩溃,因为初始化函数为空。仅用于排查流程问题。 --- ## 🔍 为什么没有 64 位 `libasan_preinit.o`? Red Hat 官方文档明确指出: > The AddressSanitizer runtime in devtoolset/gcc-toolset does **not support static linking** for x86_64 targets. 也就是说: - 32 位有 `libasan_preinit.o` 是为了兼容旧项目 - 64 位 **故意不提供**,因为静态链接 ASan 在生产环境中几乎不用,且容易出错 参考 Red Hat Knowledge Base: [https://access.redhat.com/solutions/4972101](https://access.redhat.com/solutions/4972101) --- ## ✅ 推荐最终做法总结 | 步骤 | 操作 | |------|------| | 1️⃣ | 确认当前是否启用 `-static-libasan` | | 2️⃣ | 移除所有 `-static-libasan` 和静态链接相关标志 | | 3️⃣ | 使用动态 ASan:`-fsanitize=address` + 动态链接 | | 4️⃣ | 确保 `libasan.so` 存在且可访问 | | 5️⃣ | 重新构建 | ```bash source /opt/rh/gcc-toolset-11/enable cd build && rm -rf * cmake .. # 确保不加 -static-libasan make -j2 ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值