2013-05-08 69 views
7

我想了解g ++如何选择链接到哪个版本的libstdC++,以及库的“系统”版本不同时的含义。编译器libstdC++版本与系统版本

我使用GCC/G ++ 4.1.2,其中根据ABI Guidelines文档,包含的libstdC++ so.6.0.8,果然:根据我的ABI的认识向前

-rwxr-xr-x 1 root root 4397810 May 18 2007 /opt/gcc4.1.2/lib/libstdc++.so.6.0.8 

-compatibility,我可以使用g ++ 4.1.2构建,期望代码可以在系统上运行,而系统的libstdC++版本不会低于6.0.8,但是不能安装在早期版本的系统上,因为那样会有旧版本的ABI 。

在同一台机器有一个旧版本的libstdC++在/ usr/lib中:

-rwxr-xr-x 1 root root 804288 Jul 22 2005 /usr/lib/libstdc++.so.6.0.3 

如果我在此机器上使用克++ 4.1.2编译代码,然后ldd的它,我看到的版本的libstdC++在/ usr/lib中引用的,这是6.0.3:

# ldd test 
. 
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x005b6000) 
. 

这是预期的,如/ usr/lib中首先检查。而且应用程序运行良好。

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

已将g ++ 4.1.2与libstdC++的版本链接,因此它是该版本(6.0.8)的一部分?如果是这样,在运行时,如果可执行文件具有较旧的ABI,那么可执行文件如何在/ usr/lib中使用旧版本?运气?

或者g ++ 4.1.2在链接时拾取了libstdC++(6.0.3)的/ usr/lib版本并使用它,因为它以与可执行文件在运行时相同的方式解析库路径? g ++能做到这一点,即使libstdC++不是它的“自己的”版本? g ++ 4.1.2(6.0.8)中的libstdC++版本的目的是什么?它在这个过程中是否被使用过?

任何洞见赞赏。

+1

编译器/链接器选择6.0.8,运行时加载器选择6.0.3。这可能会结束,也可能不会结束。要告诉运行时加载程序在哪里可以找到这个库,在链接器中使用'-rpath/path/to/folder/with/lib'参数(当从gcc/g ++调用时使用'-Wl,-rpath ...')。顺便说一句,4.1.2古老的几次。 – 2013-05-08 22:50:29

+1

http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html – 2013-05-29 09:20:47

回答

9

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

gcc -print-search-dirs 

列表通常更喜欢具体的编译器版本的库中,如果有一个。

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

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

如果两个库不匹配,那么可能会发生不好的事情。 C库(通常是glibc)一直很小心地保持兼容性。 C++库并不总是有这种奢侈品。近年来更安全,但很多人仍然推荐而不是混合和匹配。

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 /克++ 4.1.2的libstdC++。so.6.0.8将被使用。