使 /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.so
与 libcrypto.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)