假设我有一个共享库文件libdemo.so
,其中libdemo.so
是最后一个链接器。
如果我想构建可执行文件,并且库文件在当前工作目录中,我将其与-L. -ldemo
标志链接。
但是当我运行可执行文件时,除非我指定库路径LD_LIBRARY_PATH=.
,否则可执行文件找不到该链接。那么为什么需要额外的LD_LIBRARY_PATH
设置呢?标志用于链接时库路径,环境变量应该是运行时库路径。
或者,如果我构建可执行文件并使用-Wl,-rpath,.
指定运行时库路径,我可以省略-L. -ldemo
。
我知道这与链接时和运行时有关,但我不清楚它们之间的区别。例如,当不使用-rpath
时,如果可执行文件需要-L. -ldemo
来查找库文件,那么LD_LIBRARY_PATH
实际上做了什么?当使用后一种方法时,如果指定-rpath
意味着将目录位置复制到运行时库路径中,为什么这也允许省略-L. -ldemo
?
如果链接时库路径和运行时库路径不同,那么后一种方法在构建时不需要链接时库路径?链接时库路径和运行时库路径之间有什么区别?
答案 0 :(得分:1)
因为链接是由两个不同的链接器实例完成的。
当你编译&链接您的程序,像/usr/bin/ld
这样的链接器检查外部引用并构建您的可执行文件,添加外部引用libdemo.so
。
运行程序时,运行时链接程序/lib64/ld-linux-x86-64.so.2
(或通常说ld.so
)会加载所有需要的共享对象。有几个原因-L
未保存:
libdemo.so
没有必要位于编译期间的同一路径上(因为您可以将二进制文件复制到另一台主机上,该路径是内部构建路径等)。ld.so
通常会寻找非root用户无法写入的“可信”路径列表但是,有些情况下保存-L
会很有用(例如,软件安装到/opt
),因此某些的Unix引入了RPATH。
答案 1 :(得分:0)
经过一些研究(阅读教科书),我找到了我正在寻找的答案。
基本上,由于可执行文件不再包含目标文件的副本,因此需要某种方法来识别它所需的共享库。在链接阶段,共享库的名称嵌入在可执行文件中,但尚未指定特定位置。所以-L. -ldemo
实际上只是提供库文件的名称。请注意,在问题中,我说在设置-L. -ldemo
时未指定-rpath
。那是因为在那个命令中我实际上直接传递了库的名称libdemo.so
。如果我没有这样做,那么用-L. -ldemo
指定它是必要的。
随后提供运行时库路径以指定执行时的确切位置。