使 /etc/ld.so.conf 中的 ld 忽略目录

Posted

技术标签:

【中文标题】使 /etc/ld.so.conf 中的 ld 忽略目录【英文标题】:Make ld ignore directory from /etc/ld.so.conf 【发布时间】:2018-10-15 14:07:31 【问题描述】:

TL,DR:

我是否有办法(无 root 访问权限)使链接器(由 gcc 调用)在通过 ldconfig 缓存后不知道 /etc/ld.so.conf 中包含的目录的内容?

详细说明:

我正在尝试(但失败)在没有 root 访问权限的自定义 Linux 发行版上编译 HTCondor。由于各种原因(见下文),我认为我遇到的问题与这台机器上安装了两个版本的libssl和两个版本的libcrypto有关。出于兼容性原因,其中每个的较新版本 (1.0.0) 位于 /usr/lib64,旧版本 (0.9.8) 保留在 /usr/local/lib64/etc/ld.so.conf 包含这两个路径,因此链接器知道这两个路径。

在编译过程中出现错误

../condor_utils/libcondor_utils_8_7_9.so: undefined reference to `ERR_remove_thread_state'

由于某种原因,libcondor_utils_8_7_9.solibcrypto.so.0.9.8 相关联,而 ERR_remove_thread_state 是在 1.0.0 中引入的。它在源代码中只出现一次:

#if OPENSSL_VERSION_NUMBER < 0x10000000L
    ERR_remove_state( 0 );
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
    ERR_remove_thread_state( 0 );
#endif

所以预处理器似乎根据版本 1.0.0 做出决定。

This 的问题让我意识到了this 的博文,因此我尝试使用以下脚本替代cpp

#!/bin/bash
/usr/bin/gcc -Wl,-rpath-link="/usr/lib64",-rpath="/usr/lib64" "$@"

不幸的是,没有用。

为了它,我还尝试在上面的源代码 sn-p 中注释前处理指令以强制选择ERR_remove_state。这导致链接器警告我 libssl.so.1.0.0 可能与 libssl.so.0.9.8 冲突,并且不出所料地产生另一个“未定义引用”错误。

编辑:

结果证明问题与链接器无关。看我的回答。但是,出于好奇,我将把这个问题留着,看看是否有人在其原始公式中找到了解决方案。

【问题讨论】:

链接时可以传递各个库的绝对路径 @user463035818 哦,伙计。这可能是一个解决方案。完全忘记了。会尝试让你知道。谢谢。 "libcondor_utils_8_7_9.so 链接到 libcrypto.so.0.9.8..." - 请提交针对 Condor 的错误报告。 OpenSSL 0.9.8 很古老,有太多问题需要花时间详述。它应该在您的组织中未通过验收测试:o 我认为你应该倒带一点,展示你是如何编译和链接你的库和程序的。我们需要查看编译器和链接器的实际参数。 LD 将在运行时愉快地链接到错误的库。您可能会很幸运,并且能够使用 RPATH 构建您的应用程序。即链接器选项-Wl,-R,/usr/local/lib64 -Wl,--enable-new-dtags。您需要同时使用它们,并确保使用-I /usr/local/include 进行编译并使用-L /usr/local/lib64 链接。 @user463035818 你的想法是对的。看我的回答。 【参考方案1】:

@user463035818 和 @jww 的 cmets 为我指明了解决我的具体问题的正确方向,结果发现这与链接器没有直接关系。

Condor 使用 cmake 作为构建系统,因此显然尝试在 cmake 级别解决此问题更有意义(此处为 n00b)。在 cmake 所做的所有事情的深处,它会找到两个版本的库并出于某种原因将它们混合在一起。根据this 的主要答案CMakeLists.txt 使用特定版本调用find_library 解决了这个问题,尽管它在我的嘴里留下了肮脏的解决方法的坏味道。

根据docs,在查找库时让 cmake 忽略某个目录应该不难。不过我没试过。

【讨论】:

以上是关于使 /etc/ld.so.conf 中的 ld 忽略目录的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统中“动态库”和“静态库”那点事儿 /etc/ld.so.conf 动态库的后缀为*.so 静态库的后缀为 libxxx.a ldconfig 目录名

Linux(程序设计):06---动态函数库与静态函数库(ldconfigldd命令与/etc/ld.so.conf)

ubuntu系统添加环境变量的方法(转)

linux管理共享库

ubuntu/Linux下cannot find lib....so.x 无法找到动态链接库

慎用ldconfig命令