我试图理解g ++如何选择它链接的libstdc ++版本以及当#34;系统"该库的版本不同。
我使用gcc / g ++ 4.1.2,根据ABI Guidelines doc,包括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版本并使用了它,因为它以与运行时可执行文件相同的方式解析库路径? g ++可以做到这一点,即使libstdc ++不是它自己的"版?在g ++ 4.1.2(6.0.8)中libstdc ++版本的目的是什么?它是否在这个过程中被使用了?
任何见解都表示赞赏。
答案 0 :(得分:9)
GCC根据目录搜索列表选择所有库。你可以这样看:
gcc -print-search-dirs
列表通常更喜欢特定于编译器版本的库(如果有的话)。
但是,链接时选择可能与运行时选择不同。
如果链接器命令包含-rpath
选项(某些工具链供应商可能包含非标准的选项),则动态链接器将使用该选项在运行时查找正确的库。否则系统将使用其默认库。
如果两个库不匹配,那么可能会发生不好的事情。 C库(通常是glibc)一直小心保持兼容性。 C ++库并不总是有这种奢侈品。近年来它更安全,但许多人仍然建议不混合和匹配。
答案 1 :(得分:1)
默认情况下,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。