内容来自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
也有了路径.
gcc test.c ./say.so -o test2
strings test2
我们发现原来的输出中原来的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
strings /lfsroot/lib/ld-linux.so.2
很奇怪的是输出竟然是/etc/ld.so.cache
! 那这到底和什么有关呢,没错就是我们编译时候的--prefix
有关.
现在再看这个/etc/ld.so.conf
, 和/lib
, /usr/lib
这些默认ldconfig
路径. 也都要加上个这个prefix了.
strings /tools/sbin/ldconfig|grep etc
strings /tools/sbin/ldconfig|grep /lib
验证一下吧.
那要是ld.so.cache
里也没有记载这个库的地址怎么办呢.
最后在默认路径里找.这个路径一般是/lib
, /usr/lib
, 但也不全是.
strings /tools/lib/ld-linux.so.2|grep /lib
还是要加个prefix.
现在我们反过来思考,不用程序中硬编码的/lib/ld-linux.so.2
做动态加载器了.这也可以?!是的!虽然不一定成功.
LD_TRACE_LOADED_OBJECTS=y /tools/lib/ld-linux.so.2 /bin/test
LD_TRACE_LOADED_OBJECTS=y /lib/ld-linux.so.2 /bin/test
LD_TRACE_LOADED_OBJECTS=y /lfsroot/lib/ld-linux.so.2 /bin/test
为了说明顺序,我们做如下很危险的实验:
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
unset LD_LIBRARY_PATH
echo >/etc/ld.so.cache
ldconfig -p
应该什么都不出现,可大部分程序能运行.说明ld-linux.so.2
决定的默认路径起了作用(注意,这里的ldconfig
的默认路径没有作用)
ldconfig
恢复系统正常.