2012-10-03 79 views
0

我有一个C++项目,当前没有链接任何外部动态库。我正在考虑在将来需要构建一些boost库(而不是仅标头)。目前,在开发阶段,我使用三种不同的工具链构建我的项目:g++,LLVM/Clang++Intel C++,平台为Linux。这些编译器AFAIK彼此是二进制兼容的,例如, g ++编译的应用程序可以使用英特尔C++编译的动态库。链接器如何选择使用不同编译器编译的动态库

我已经构建了boost二进制文件并将它们安装到不同的文件夹中。例如build_gccbuild_icc。然后我将这些文件夹的路径添加到系统LIBRARY_PATH。问题是:如果我现在使用g++Intel C++构建项目并链接一些动态库(例如,写

-lboost_math_tr1 
makefile

,如何链接器决定哪些确切的库文件来链接,如果从不同的编译器的二进制文件相互兼容?

问题的动机很简单:Intel C++是一个优化的编译器,所以如果我建立的东西吧,我希望他们对与Intel C++编译器编译动态库链接,而不是对一个与g++编译。当然,我知道我可以在makefile中简单地使用多个条件语句来为每个使用的工具链设置库二进制文件的确切目录,但这只是有点不方便。我在游荡,链接器是否足够聪明,可以识别它应该使用的确切的共享库文件,还是仅仅使用系统中的第一个匹配项LIBRARY_PATH

回答

1

链接器将不知道。如果第一个找到的库不兼容,它甚至会保留,而不是搜索所有库,直到找到兼容的库。

确认是这样的:

$ cat foo.c 
int main() { 
    return 0; 
} 
$ mkdir bar 
$ touch bar/libm.so 
$ gcc foo.c -o foo -Lbar -lm 
/usr/bin/ld: error: b/libm.so: file is empty 
collect2: error: ld returned 1 exit status 

OTOH,动态链接的美在于能够与一个更好的交流dylib,而无需重新编译。 所以你可以链接到g ++版本,但是如果性能很差,请在目标主机上安装icc版本(在g ++版本之前要搜索的地方),你的应用程序会神奇地使用它(只要它们是兼容的)。

,你也可以使用LD_LIBRARY_PATH变量在运行应用程序时,搜索库在非标准位置:

LD_LIBRARY_PATH=/path/to/super/libs/ ./app-dylinked-with-generic-libs 
+0

简单而完整的解释。谢谢。 – Dmitry

0

PATH环境变量用于查找可执行文件,而不是查找库。每个编译器都有一组标准位置查找库,以及使用-L显式指定的位置。它不会关心哪个编译器创建了库。

0

您需要将这些库添加到$LIBRARY_PATH(链接)和$LD_LIBRARY_PATH(运行时),而不是$PATH。我觉得你可以在你的Makefile中一次设置这些变量来决定链接哪个二进制文件。

+0

感谢并指出,编辑的问题。 – Dmitry