C++ 编译器libstdc++;版本与系统版本

C++ 编译器libstdc++;版本与系统版本,c++,linux,compiler-construction,g++,shared-libraries,C++,Linux,Compiler Construction,G++,Shared Libraries,我试图理解g++是如何选择它所链接的libstdc++的哪个版本的,以及当库的“系统”版本不同时它意味着什么 我使用的是gcc/g++4.1.2,据文档所述,它包括libstdc++.so.6.0.8,而且确实: -rwxr-xr-x 1 root root 4397810 May 18 2007 /opt/gcc4.1.2/lib/libstdc++.so.6.0.8 基于我对ABI前向兼容性的理解,我可以使用g++4.1.2进行构建,并期望代码能够在libstdc++版本高于6.0.8

我试图理解g++是如何选择它所链接的libstdc++的哪个版本的,以及当库的“系统”版本不同时它意味着什么

我使用的是gcc/g++4.1.2,据文档所述,它包括libstdc++.so.6.0.8,而且确实:

-rwxr-xr-x  1 root root 4397810 May 18  2007 /opt/gcc4.1.2/lib/libstdc++.so.6.0.8
基于我对ABI前向兼容性的理解,我可以使用g++4.1.2进行构建,并期望代码能够在libstdc++版本高于6.0.8的系统上运行,但不能在较早版本的系统上运行,因为该系统将使用较旧版本的ABI

在同一台计算机上,/usr/lib中有旧版本的libstdc++:

-rwxr-xr-x  1 root root 804288 Jul 22  2005 /usr/lib/libstdc++.so.6.0.3
如果我在这台机器上使用g++4.1.2编译代码,然后对其进行ldd,我会在/usr/lib引用中看到libstdc++的版本,即6.0.3:

# ldd test
.
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x005b6000)
.
这是预期的,因为首先检查了/usr/lib。应用程序运行良好

我的问题是:这里发生了什么

g++4.1.2是否与libstdc++的版本相关联?这是该版本(6.0.8)的一部分?如果是这样的话,当/usr/lib中有较旧的ABI时,为什么可执行文件可以在运行时使用较旧的版本?运气如何

或者g++4.1.2是否在链接时使用libstdc++(6.0.3)的/usr/lib版本,因为它在运行时解析库路径的方式与可执行文件相同?即使libstdc++不是它自己的版本,g++也能做到这一点吗?g++4.1.2(6.0.8)中libstdc++版本的用途是什么?在这个过程中有没有使用过


任何见解都值得赞赏。

GCC根据目录搜索列表选择所有库。你可以这样看:

gcc -print-search-dirs
该列表通常首选特定于编译器版本的库(如果有)

但是,链接时间选择可能与运行时选择不同

如果链接器命令包含
-rpath
选项(某些工具链供应商可能包含非标准选项),则动态链接器将在运行时使用该选项查找正确的库。否则,系统将使用其默认库


如果这两个库不匹配,那么可能会发生不好的事情。C库(通常是glibc)一直都很小心地维护兼容性。C++库并不总是有这样的奢侈。近年来它变得更安全了,但许多人仍然建议不要混合和匹配。

默认情况下,gcc使用/usr/lib路径中的库。
1.gcc/g++4.1.2未链接到libstdc++.so.6.0.8的最新版本。
2.g++4.1.2在链接时获取了libstdc++(6.0.3)的/usr/lib版本

除非显式设置库路径,否则它仍然使用系统默认的libstdc++.so.6.0.3

对于gcc/g++4.1.2,要使用libstdc++.so.6.0.8的最新版本,您必须在编译之前导出库路径

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/gcc4.1.2/lib

现在,当使用gcc/g++4.1.2进行链接时,将使用libstdc++.so.6.0.8。

编译器/链接器选择6.0.8,运行时加载程序选择6.0.3。这可能会也可能不会有好的结局。要告诉运行时加载程序在哪里找到库,请使用链接器的
-rpath/path/To/folder/with/lib
参数(
-Wl,-rpath…
,从gcc/g++调用时)。顺便说一下,4.1.2是古代的好几倍。