【问题标题】:How does linker select dynamic library among those compiled with different compilers链接器如何在使用不同编译器编译的动态库中选择动态库
【发布时间】:2012-09-24 11:12:58
【问题描述】:

我有一个 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++ 编译器编译的动态库链接,而不是与使用 @ 编译的动态库链接987654334@。当然,我知道我可以简单地在makefile 中使用多个条件语句来为每个使用的工具链设置带有库二进制文件的确切目录,但这有点不方便。我在徘徊,链接器是否足够聪明,可以识别它应该使用哪个确切的共享库文件,或者它只是使用在系统LIBRARY_PATH 中找到的第一个匹配项?

【问题讨论】:

    标签: c++ linker dynamic-linking


    【解决方案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
    

    【讨论】:

    • 简单而完整的解释。谢谢。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2011-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-28
        • 1970-01-01
        相关资源
        最近更新 更多