如何在 Linux 上获取 /etc/ld.so.conf 中的路径列表
获取由 /etc/ld.so.conf
配置的路径列表以及其中包含的文件的最可移植和最可靠的方法是什么?手动解析文件似乎不是一个好主意 - 格式可能会在未来的修订中发生变化。
为了让您更好地理解这个问题,我将在下面为您提供具体细节。请注意,尽管有这些细节,但这只是一个通用的编程问题,适用于其他情况。
有一个程序,名为 LuaRocks 。它是 Lua 编程语言的包管理器(有点像 Ruby gems 或 Python Eggs)。 LuaRocks 包被称为“rocks”。
作为一项便利功能,LuaRocks 允许 rock 作者指定 rock 的外部依赖项列表,将其表述为 C 头文件和/或动态库文件列表。 (Linux 上为 .so。)如果指定的文件不存在,则无法安装 rock。
目前,在 Linux 上,LuaRocks 默认情况下通过在两个 硬编码 路径 /usr/lib
和 /usr/local/ 中搜索文件来检查 .so 文件是否存在。库
。
我相信这是不正确的行为,并且它被 打破 Ubuntu 和其他 Debian 发行版中最近的更改。
更新:路径本身并不是硬编码的,而是用户可以在配置文件中配置的。不过,IMO,这不是最好的解决方案。
相反(据我了解),LuaRocks 应该在 /etc/ld.so.conf
指定的路径中查找文件以及包含的文件从它。
(现在请重新阅读上面的问题;-))
What is the most portable and robust way to get the list of paths, configured by /etc/ld.so.conf
and files included from it? Parsing the file manually seems to be not a good idea — the format is likely to change in the future revisions.
To allow better understanding of the question, I will give you specific details below. Note that, despite these details, this is a general programming question, applicable to other situations.
There is a program, called LuaRocks. It is a package manager for Lua programming language (somewhat like Ruby gems or Python eggs). LuaRocks packages are called "rocks".
As a convenience feature, LuaRocks allows a rock author to specify a list of external dependencies for a rock, formulated as a list of C header files and / or dynamic library files. (.so on Linux.) If the specified file does not exist, the rock can't be installed.
Currently, on Linux, LuaRocks by default checks .so file existance by searching for the file in two hardcoded paths, /usr/lib
and /usr/local/lib
.
I believe that this is incorrect behaviour, and it is broken by the recent changes in the Ubuntu and other Debian distributions.
Update: the paths are not hardcoded per se, but are user-configurable in the config file. Still, IMO, not a best solution.
Instead (as I understand it), LuaRocks should look up file in the paths, specified by /etc/ld.so.conf
and files included from it.
(Now please re-read the question above ;-) )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不需要解析 /etc/ld.so.conf 或任何配置文件 - 如果运行“ldconfig”,它将扫描配置的目录并生成缓存文件。
然后,随后当您尝试 dlopen 时,它会通过迭代缓存的库目录自动查找文件。与编译和提供 -lSomeLib 相同,如果您已在 ld.so.conf(.d) 中配置了 -L/my/other/path,则不需要指定 -L/my/other/path
autoconf 通过尝试编译测试来完成此操作链接到共享库的程序,但这只是 dlopen() 调用的功能包装器。
因此,虽然其他方法不一定是“错误的”,但从根本上来说,尝试链接到库或执行 dlopen() 是“最正确”的方法。
考虑一下这一点,如果您尝试链接到未缓存在 /etc/ld.so.cache 中的目录中的库,当您尝试运行该程序时,它将失败,因为它将无法 dlopen()图书馆!
因此,任何“好的”共享库都将位于 /etc/ld.so.cache 中并且可链接/dlopen(),这意味着 gcc 可以使用它进行链接,并且用户生成的库或可执行文件将能够执行时打开它。
您可以通过明确设置环境变量 LD_LIBRARY_PATH 或 LD_PRELOAD_PATH 来规避此问题 - 但每个变量都有其自己的警告,如果可能的话应避免用于“标准”使用。
关于编写共享库的一篇很好的文章涵盖了其中一些问题,对于任何致力于以编程方式使用其他共享库的人来说都是一本很好的读物。 Ulrich Drepper 的《如何编写共享库》。
You shouldn't need to parse /etc/ld.so.conf or any of the config files - if you run 'ldconfig', it will scan the configured directories and generate a cache file.
Then, subsequently when you attempt a dlopen it'll automatically find the files by iterating through the cached library directories. Same thing with compiling and giving -lSomeLib, you shouldn't need to specify -L/my/other/path if you've got it configured in ld.so.conf(.d)
autoconf accomplishes this by attempting to compile a test program that links to the shared library, but that's just a functional wrapper around the dlopen() call.
So, while other methods may not necessarily be 'wrong', at the root of it attempting to link to the library or doing a dlopen() are the 'most right' ways of doing it.
Consider this, if you attempt to link to a library in a directory that ISN'T cached in /etc/ld.so.cache, when you try to run the program it will fail because it won't be able to dlopen() the library!
Hence, any 'good' shared library will be in /etc/ld.so.cache and be linkable/dlopen()able, this means that gcc can use it to link and that the user-generated library or executable will be able to open it when it executes.
You can circumvent this by expressly setting the environment variable LD_LIBRARY_PATH, or LD_PRELOAD_PATH - but each of these has it's own caveats and should be avoided if possible for 'standard' use.
A good write-up on writing shared libraries covers some of these issues, and is a good read for anyone working on programmatic consuming of other-shared libraries. Ulrich Drepper's How to write shared libraries.
根据 FHS,以下是动态库的有效位置:(
并且很可能
~ /lib*/
也是如此。)我的
/etc/ld.so.conf.d/*
中的所有条目都符合这一点。某些条目引用 FHS 目录下的子目录,这可能意味着您可以使用其中的库而无需路径信息。现在我对LuaRocks还不够了解。如果您仅限于 Lua 路径样式的 glob(仅限
?
),则无法匹配这些并且必须解析配置。否则,您可以尝试在这些目录中的任何位置找到它们。这会在不符合 FHS 的系统上中断(唯一选项:解析配置),并且如果配置中未包含目录,安装程序可能会看到链接器找不到的库。
这两个对我来说似乎可以接受,因此我只是忽略配置并查看这些目录。
(另一种可能性可能是尝试链接库,这应该自动使用正确的路径。但是,这是特定于平台的,可能很危险。)
According to the FHS, the following are valid locations for dynamic libraries:
(And most likely
~/lib*/
as well.)All entries in my
/etc/ld.so.conf.d/*
conform to this. Some entries reference subdirectories below the FHS dirs, which probably means that you can use the libraries in there without path information.Now I don't know enough about LuaRocks. If you're limited to Lua-path-style globs (only
?
), you cannot match these and have to parse the configs. Otherwise, you could just try to find them anywhere in these directories.This would break on non-FHS-conforming systems (only option: parse config) and if a directory is not included in the config, the installer might see libraries that the linker cannot find.
These two seem acceptable to me, therefore I'd simply ignore the config and look at these dirs.
(Another possibility could be trying to link the library, this should automagically use the right path. However, this is platform-specific and maybe dangerous.)