5

获取路径列表、配置路径/etc/ld.so.conf和其中包含的文件的最便携和最可靠的方法是什么?手动解析文件似乎不是一个好主意——格式可能会在未来的修订版中发生变化。


为了更好地理解这个问题,我将在下面为您提供具体细节。请注意,尽管有这些细节,但这是一个通用的编程问题,适用于其他情况。

有一个程序,叫做LuaRocks。它是 Lua 编程语言的包管理器(有点像 Ruby gems 或 Python Eggs)。LuaRocks 包被称为“rocks”。

作为一个方便的特性,LuaRocks 允许 Rock 作者为 Rock 指定一个外部依赖项列表,以 C 头文件和/或动态库文件的列表形式表示。(Linux 上的.so。)如果指定的文件不存在,则无法安装rock。

目前,在 Linux 上,LuaRocks 默认通过在两个硬编码路径中搜索文件来检查 .so 文件是否存在,以及 .so/usr/lib文件/usr/local/lib

我相信这是不正确的行为,它被Ubuntu 和其他 Debian 发行版最近的变化所打破。

更新:路径本身不是硬编码的,但用户可以在配置文件中配置。尽管如此,IMO 并不是最好的解决方案。

相反(据我了解),LuaRocks 应该在路径中查找文件,/etc/ld.so.conf由它指定和包含的文件。

(现在请重新阅读上面的问题;-))

4

2 回答 2

7

您不需要解析 /etc/ld.so.conf 或任何配置文件 - 如果您运行“ldconfig”,它将扫描配置的目录并生成缓存文件。

然后,随后当您尝试 dlopen 时,它会通过遍历缓存的库目录自动查找文件。与编译和提供 -lSomeLib 相同,如果在 ld.so.conf(.d) 中配置了 -L/my/other/path,则不需要指定

autoconf 通过尝试编译链接到共享库的测试程序来实现这一点,但这只是 dlopen() 调用的功能包装器。

因此,虽然其他方法不一定是“错误的”,但从根本上来说,尝试链接到库或执行 dlopen() 是“最正确”的方法。

考虑一下这一点,如果您尝试链接到 ISN 未缓存在 /etc/ld.so.cache 中的目录中的库,当您尝试运行该程序时,它将失败,因为它无法 dlopen()图书馆!

因此,任何“好的”共享库都将在 /etc/ld.so.cache 中并且可以链接/dlopen(),这意味着 gcc 可以使用它来链接,并且用户生成的库或可执行文件将能够执行时打开它。

您可以通过明确设置环境变量 LD_LIBRARY_PATH 或 LD_PRELOAD_PATH 来规避这种情况 - 但它们中的每一个都有自己的警告,如果可能,应该避免“标准”使用。

一篇关于编写共享库的好文章涵盖了其中的一些问题,对于任何致力于以编程方式使用其他共享库的人来说都是一本好书。Ulrich Drepper 的如何编写共享库

于 2011-07-11T18:07:00.497 回答
2

根据FHS,以下是动态库的有效位置:

/lib*/
/opt/*/lib*/
/usr/lib*/
/usr/local/lib*/

(而且很可能~/lib*/也是如此。)

我的所有条目都/etc/ld.so.conf.d/*符合这一点。一些条目引用了 FHS 目录下的子目录,这可能意味着您可以在没有路径信息的情况下使用其中的库。

现在我对 LuaRocks 的了解还不够。如果您仅限于 Lua 路径样式的 glob(仅限?),则无法匹配这些并且必须解析配置。否则,您可以尝试在这些目录中的任何位置找到它们。

这会在不符合 FHS 的系统上中断(唯一选项:解析配置),如果配置中不包含目录,安装程序可能会看到链接器找不到的库。

这两个对我来说似乎可以接受,因此我会简单地忽略配置并查看这些目录。

(另一种可能性是尝试链接库,这应该自动使用正确的路径。但是,这是特定于平台的,可能很危险。)

于 2011-07-11T18:02:25.247 回答