C++使用现代编译器编译的项目,但链接到过时的libstdc++
C++ project compiled with modern compiler, but linked against outdated libstdc++
考虑在Centos 7
虚拟机或容器中生成和交付C++项目的情况。Centos 7
的默认gcc
为4.8
。为了让开发者能够使用现代C++,较新版本的gcc
(例如6.3
(被安装到 Centos 7 中,作为 CI 服务器运行。这提供了-std=c++14
支持。
[builder@f7279ae9f33f build (master %)]$ /usr/bin/c++ -v 2>&1 | grep version
gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
[builder@f7279ae9f33f build (master %)]$ /opt/rh/devtoolset-6/root/usr/bin/c++ -v 2>&1 | grep version
gcc version 6.3.1 20170216 (Red Hat 6.3.1-3) (GCC)
export CXX=/opt/rh/devtoolset-6/root/usr/bin/c++
make all -j4
...
这是编译和链接命令的简短示例:
[ 78%] Building CXX object CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o
/opt/rh/devtoolset-6/root/usr/bin/c++ -Ducsdos_EXPORTS -I/home/builder/src/dos/libucsdos/./src -I/home/builder/src/dos/libucsdos/./include -I/home/builder/src/dos/libucsdos/build/schema/cpp -I/home/builder/src/dos/libucsdos/build/schema -isystem /usr/local/include -O2 -g -DNDEBUG -fPIC -frtti -pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-declarations -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused -std=gnu++14 -o CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o -c /home/builder/src/dos/libucsdos/src/merge_operator_string.cpp
[ 80%] Linking CXX shared library libucsdos.so
/usr/bin/cmake3 -E cmake_link_script CMakeFiles/ucsdos.dir/link.txt --verbose=1
/opt/rh/devtoolset-6/root/usr/bin/c++ -fPIC -O2 -g -DNDEBUG -shared -Wl,-soname,libucsdos.so.0 -o libucsdos.so.0.3.23 CMakeFiles/ucsdos.dir/src/c.cpp.o CMakeFiles/ucsdos.dir/src/crdt_2p_set.cpp.o CMakeFiles/ucsdos.dir/src/crdt_pn_counter.cpp.o CMakeFiles/ucsdos.dir/src/errors.cpp.o CMakeFiles/ucsdos.dir/src/merge_index_document.cpp.o CMakeFiles/ucsdos.dir/src/merge_index_segment.cpp.o CMakeFiles/ucsdos.dir/src/merge_operator_string.cpp.o -Wl,-rpath,/usr/local/lib: schema/libschema.a /usr/lib64/librocksdb.so /usr/lib64/libjemalloc.so /usr/local/lib/libgrpc++_reflection.so /usr/local/lib/libgrpc++.so /usr/local/lib/libgrpc.so -ldl -lgrpc++ /usr/lib64/libprotobuf.so -lpthread /usr/lib64/libprotobuf-lite.so
无论如何,生成的工件似乎与系统默认版本的libstdc++
相关联:
[builder@f7279ae9f33f build (master %)]$ ldd libucsdos.so | grep libstdc++.so.6
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2a4a054000)
很容易发现/lib64/libstdc++.so.6
版本是4.8.5
:
[builder@f7279ae9f33f build (master %)]$ yum whatprovides "/lib64/libstdc++.so.6"
libstdc++-4.8.5-28.el7_5.1.x86_64 : GNU Standard C++ Library
Repo : @Updates
Matched from:
Filename : /lib64/libstdc++.so.6
此构建环境配置是否有效?
无论如何,生成的工件似乎与 libstdc++ 的系统默认版本相关联:
是的。devtoolset-6-gcc-c++
包提供了 GCC 的自定义版本,该版本使用特殊的链接器脚本而不是用于libstdc++.so
的动态库。这意味着它生成的二进制文件不依赖于较新的libstdc++.so.6
,并且可以在其他没有安装 devtoolset 的 CentOS 机器上运行(即它们只有 GCC 4.8 中较旧的 libstdc++ 库(。
此构建环境配置是否有效?
是的。你所看到的是完全正常的,以及它应该如何工作。
GCC 6.4.0 中较新的C++运行时的片段会静态链接到您的二进制文件中,而在运行时,它只依赖于每个 CentOS 系统已安装的旧libstdc++.so
。
这就是GCC开发工具集版本的重点。
相关文章:
- 为什么C++可执行文件在与较新的libstdc++.so链接时运行得更快?
- 当其他链接库链接 stdc++ 为动态时,如何将 libstdc++ 链接设置为静态?
- 如何使用LLVM LLD链接libstdc++
- I686-ELF的跨编译和链接libstdc (在Ubuntu上使用G 16.04)
- 如何使用libc libstdc 混合的链接库
- 将libstdc 静态链接起来是一个很好的做法
- 'libstdc++'库的链接在嵌入式 Linux 中被破坏
- Eclipse CDT链接选项-静态libgcc-静态libstdc++不影响Windows上的行为
- 获取指向成员std::string::size的指针无法与libc++链接,但可以与libstdc++一起使用
- 我有libstdc++6-dev,但仍然有stl链接错误
- CodeBlocks:如何动态链接libstdc++
- 使用clang的静态链接libstdc++
- 与使用 GCC 3.4.6 (libstdc++.so.6.0.13) 生成的 gmock 库链接会产生"undefined reference to... @GLIBCXX_3.4.9"错误
- 在动态链接库libstdc++-6.dll中找不到过程入口点_gxx_personality_v0.错误
- 如何链接GCC中的libc和libstdc++的调试版本
- 从源代码构建GCC 5.4;这样构建的可执行文件试图链接不兼容的libstdc++,但运行失败
- CentOS 5.8与gcc 4.4.7链接libstdc++ 6.0.8.这怎么可能
- 在动态链接库libstdc++-6.dll中无法找到过程入口点_gxx_personality_v0
- 如何静态链接libstdc++
- 在 RHEL 5.7 上链接 libstdc++ 问题