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

链接器如何在使用不同编译器编译的动态库中选择动态库 我有一个C++项目,目前没有链接到任何外部动态库。我正在考虑将来使用一些需要构建的boost库(不仅仅是header库)。目前,在开发阶段,我使用三种不同的工具链构建我的项目:g++、LLVM/Clang++和Intel C++,平台是Linux。这些编译器AFAIK是二进制兼容的,例如,g++编译的应用程序可以使用英特尔C++编译的动态库,c++,linker,dynamic-linking,C++,Linker,Dynamic Linking,我已经构建了boost二进制文件,并将它们安装到不同的文件夹中。e、 g.build\u gcc,build\u icc。然后我将这些文件夹的路径添加到系统LIBRARY\u PATH。问题是:如果我现在使用g++或Intel C++构建项目,并链接一些动态库,例如write -lboost_math_tr1 在makefile中,如果来自不同编译器的二进制文件彼此兼容,链接器如何决定要链接的确切库文件 这个问题的动机很简单:Intel C++是一个优化编译器,因此如果我用它构建东西,我希望它

我已经构建了boost二进制文件,并将它们安装到不同的文件夹中。e、 g.
build\u gcc
build\u icc
。然后我将这些文件夹的路径添加到系统
LIBRARY\u PATH
。问题是:如果我现在使用
g++
Intel C++
构建项目,并链接一些动态库,例如write

-lboost_math_tr1
makefile
中,如果来自不同编译器的二进制文件彼此兼容,链接器如何决定要链接的确切库文件


这个问题的动机很简单:
Intel C++
是一个优化编译器,因此如果我用它构建东西,我希望它们与使用
Intel C++
编译器编译的动态库相关联,而不是与使用
g++
编译器编译的动态库相关联。当然,我知道我可以简单地使用
makefile
中的多个条件语句为每个使用的工具链设置带有库二进制文件的确切目录,但这有点不方便。我想知道,链接器是否足够聪明,能够识别出它应该使用的确切共享库文件,还是仅仅使用在系统
library\u PATH
中找到的第一个实例?

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

您需要将这些库添加到
$library\u PATH
(链接)和
$LD\u library\u PATH
(运行时)而不是
$PATH
。我觉得您可以在
生成文件中设置这些变量,一次设置一个,以决定链接所针对的二进制文件。

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

确认如下内容:

$ 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,动态链接的美妙之处在于能够将动态库与更好的动态库交换,而无需重新编译。 因此,您可以针对g++版本进行链接,但如果性能不佳,请在目标主机上安装icc版本(在g++版本之前搜索的位置),您的应用程序将神奇地使用它(只要它们兼容)

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

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

简单而完整的解释。谢谢