You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.
这一篇博文很长,我分成下上下两篇。
内容来自已经不存在的 LinuxSir 社区(RIP)的 LFS 板块,当时很多东西我并不懂,只是觉得很有趣所以复制粘贴到我的笔记软件里了。
几年之后我对 Linux 熟悉一些,也用过 Gentoo 很久并一直认为这是我最喜欢的 Linux 发行版。虽然我对源码编译很感兴趣,但是知之甚少。偶然再看到这篇博客很多东西有种豁然开朗的感觉。再想回去 LinuxSir 社区,发现它早已不复存在。
我现在仍然觉得这两篇博文很有趣,并且打算还保留它们。如果原作者看到的话,有什么问题请和我联系。
以下时原文,有少量改动。
如果不出意外的话,会出现
say.so => not found
. 这时的./test
是不能运行的. 但至少说明程序运行时是需要这个库的. 那为什么找不到这个库呢? 那就让我们看看系统是怎样寻找这些库的吧.首先是
ld-linux.so.2
这个不能不说,它太重要了,以至于也决定了后面的搜索方式.先是程序内部决定的.
strings test
还好我们这个test程序不大,不用过滤输出,好,你看见什么,
/lib/ld-linux.so.2
,say.so
,libc.so.6
, 对, 用到的库!但我们发现不同,有的有路径,有的没有,先不管没有路径的怎么寻找,有路径的肯定是能找到了,那好,我们让
say.so
也有了路径.我们发现原来的输出中原来的
say.so
已经变成了./say.so
. 运行一下./test2
, 可以运行了! 好,找到库了,这里用的相对路径,无疑,我们将say.so
移动到非当前文件夹.那test
就又不能运行了.这样无疑是把我们用到的库硬编码进了程序里.我不喜欢硬编码,太死板.那不硬编码系统怎么找到我们需要的文件呢.在程序没有把库地址硬编码经进去的前提下,系统会寻找
LD_LIBRARY_PATH
环境变量中的地址.如果系统在这一步也没发现我们需要的库呢.
/etc/ld.so.cache
这个由ldconfig
生成的文件,记载着在/etc/ld.so.conf
文件中指明的所有库路径加上/lib
,/usr/lib
里的所有库的信息.其实以上这句话只是在大多数情况下是正确的, 是否是这个文件由
ld-linux.so.2
决定. 如过你的LFS中的第一遍工具链/tools
还在的话,strings /tools/lib/ld-linux.so.2 |grep etc
输出很可能是
/tools/etc/ld.so.cache
. 那么它用的哪个文件我们就清楚了吧.可这个路径前面的
/tools
到底和什么有关呢?首先我们可能会想到与ld-linux
所在的位置有关. 还好我们有3套glib
, 感谢LFS, 现在我们拿第二遍的工具链下手. 假设我们的LFS在/lfsroot
很奇怪的是输出竟然是
/etc/ld.so.cache
! 那这到底和什么有关呢,没错就是我们编译时候的--prefix
有关.现在再看这个
/etc/ld.so.conf
, 和/lib
,/usr/lib
这些默认ldconfig
路径. 也都要加上个这个prefix了.验证一下吧.
那要是
ld.so.cache
里也没有记载这个库的地址怎么办呢.最后在默认路径里找.这个路径一般是
/lib
,/usr/lib
, 但也不全是.strings /tools/lib/ld-linux.so.2 |grep /lib
还是要加个prefix.
现在我们反过来思考,不用程序中硬编码的
/lib/ld-linux.so.2
做动态加载器了.这也可以?!是的!虽然不一定成功.为了说明顺序,我们做如下很危险的实验:
ldconfig /lfsroot/lib; ldconfig -p
会出现很多内容,但不要试着过滤,因为这时的系统应该很多程序不能运行了.先踏下心来观察.你会发现很多库出现两次
/lfsroot/lib
, 和/lib
而且/lfsroot/lib
在前, 说明ldconfig
先处理参数给出的地址,最后是默认地址.但顺序也不一定,应该还和编译glibc
时我们的参数--enable-kerne
l有关(我根据种种表现猜测).加上
export LD_LIBRARY_PATH=/lib
环境变量在前面,不能运行的程序又能运行了,说明LD_LIBRARY_PATH
变量的优先级优于ld.so.cache
应该什么都不出现,可大部分程序能运行.说明
ld-linux.so.2
决定的默认路径起了作用(注意,这里的ldconfig
的默认路径没有作用)恢复系统正常.
The text was updated successfully, but these errors were encountered: