我有一个C ++项目,目前没有链接任何外部动态库。我正在考虑将来使用一些需要构建的boost库(不仅仅是header)。目前,在开发阶段,我使用三个不同的工具链构建我的项目:g++
,LLVM/Clang++
和Intel C++
,平台为Linux
。这些编译器AFAIK彼此是二进制兼容的,例如, g ++ - 编译的应用程序可以使用英特尔C ++编译的动态库。
我已经构建了boost二进制文件并将它们安装到不同的文件夹中。例如build_gcc
,build_icc
。然后我将这些文件夹的路径添加到系统LIBRARY_PATH
。问题是:如果我现在使用g++
或Intel C++
构建我的项目并链接一些动态库,例如写
-lboost_math_tr1
在makefile
中,如果来自不同编译器的二进制文件彼此兼容,链接器如何决定链接哪个确切的库文件?
问题的动机很简单:Intel C++
是一个优化编译器,所以如果我用它构建东西,我希望它们与用Intel C++
编译器编译的动态库链接,而不是与一个用g++
编译的。当然,我知道我可以在makefile
中使用多个条件语句来为每个使用过的工具链设置具有库二进制文件的确切目录,但这有点不方便。我在徘徊,链接器是否足够聪明,可以识别它应该使用哪个确切的共享库文件,或者它只是使用系统LIBRARY_PATH
中找到的第一个匹配项?
答案 0 :(得分: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
答案 1 :(得分:0)
PATH环境变量用于查找可执行文件,而不是用于查找库。每个编译器都有一组标准位置,它查找库,以及使用-L显式指定的位置。它不关心哪个编译器创建了库。
答案 2 :(得分:0)
您需要将这些库添加到$LIBRARY_PATH
(链接)和$LD_LIBRARY_PATH
(运行时)而不是$PATH
。我觉得您可以一次在Makefile
中设置这些变量,以决定要链接哪个二进制文件。