*.so
库)。例如,我的应用程序a.out
调用了lib.so
库中定义的函数。编译后,我将lib.so
移至我的$HOME
中的新目录。如何告诉
a.out
去那里寻找它?#1 楼
共享库HOWTO解释了所涉及的大多数机制,动态加载程序手册也有更详细的说明。每个unix变体都有自己的方式,但是大多数使用相同的可执行格式(ELF),并且具有类似的动态链接程序¹(源自Solaris)。下面,我将重点介绍Linux的常见行为。(术语注释:系统中加载共享库的部分通常称为“动态链接器”,但有时更确切地说是“动态加载器”。“动态链接器”可以也表示在编译程序时为动态加载程序生成指令的工具,或编译时工具与运行时加载程序的组合。在此答案中,“链接器”是指运行时部分。)简而言之,当寻找动态库(
.so
文件)时,链接器将尝试:环境变量
LD_LIBRARY_PATH
中列出的目录(在OSX上为DYLD_LIBRARY_PATH
); 目录中列出的目录可执行文件的rpath;
系统搜索路径上的目录(至少在Linux上由
/etc/ld.so.conf
加上/lib
和/usr/lib
中的条目组成。rpath存储在可执行文件中(即
DT_RPATH
或DT_RUNPATH
动态属性)。它可以包含绝对路径或以$ORIGIN
开头的路径以指示相对于可执行文件位置的路径(例如,如果可执行文件位于/opt/myapp/bin
中,并且其rpath为$ORIGIN/../lib:$ORIGIN/../plugins
,则动态链接程序将在/opt/myapp/lib
和/opt/myapp/plugins
中查找)。通常,在编译可执行文件时使用r4312079q的-rpath
选项来确定rpath,但之后可以使用ld
对其进行更改。在您描述的场景中,如果您是应用程序的开发人员或打包人员,并打算将其安装在
chrpath
,…/bin
结构中,请与…/lib
链接。如果要在系统上安装预构建的二进制文件,请将库放在搜索路径上的目录中(如果您是系统管理员,则为-rpath='$ORIGIN/../lib'
,否则为添加到/usr/local/lib
的目录),或尝试使用$LD_LIBRARY_PATH
。 br />评论
在某些系统上,/ lib64和/ usr / lib64用于64位二进制文件,而/ lib和/ usr / lib用于32位二进制文件。
–马克·拉卡塔(Mark Lakata)
2015年6月4日18:21
为什么这个正确的答案不谈ldconfig?
–爱概率
18年6月19日在6:50
@LovesProbability因为问题在于可执行文件在哪里寻找库,而这些库不涉及ldconfig。安装库时,ldconfig会参与其中。
–吉尔斯'所以-不再是邪恶的'
18年6月19日在22:26
请注意,*。so库的“系统搜索路径”与$ PATH不同。搜索路径由@enzotib在其答案中给出。要打印出将要搜索的路径,请运行ldconfig -v 2> / dev / null | grep -v ^ $'\ t'。
–安德鲁·贝特(Andrew Bate)
19年6月21日在18:22
对我来说,要运行ldconfig,我需要/ sbin / ldconfig和安德鲁·贝特(Andrew Bate)的其他魔力来使其非root用户运行
–罗伯特·拉格(Robert Lugg)
19-10-9在20:02
#2 楼
在Linux中,该行为已在ld(1)
手册页中明确显示 The linker uses the following search paths to locate required
shared libraries:
1. Any directories specified by -rpath-link options.
2. Any directories specified by -rpath options. The difference
between -rpath and -rpath-link is that directories specified by
-rpath options are included in the executable and used at
runtime, whereas the -rpath-link option is only effective at
link time. Searching -rpath in this way is only supported by
native linkers and cross linkers which have been configured
with the --with-sysroot option.
3. On an ELF system, for native linkers, if the -rpath and
-rpath-link options were not used, search the contents of the
environment variable "LD_RUN_PATH".
4. On SunOS, if the -rpath option was not used, search any
directories specified using -L options.
5. For a native linker, the search the contents of the environment
variable "LD_LIBRARY_PATH".
6. For a native ELF linker, the directories in "DT_RUNPATH" or
"DT_RPATH" of a shared library are searched for shared
libraries needed by it. The "DT_RPATH" entries are ignored if
"DT_RUNPATH" entries exist.
7. The default directories, normally /lib and /usr/lib.
8. For a native linker on an ELF system, if the file
/etc/ld.so.conf exists, the list of directories found in that
file.
If the required shared library is not found, the linker will issue
a warning and continue with the link.
评论
“默认目录,通常是/ lib和/ usr / lib。” ->如何确定我的系统是否正常?
–瑟斯登·斯塔克
2014年12月6日在7:30
问题是关于运行时间,而不是链接时间
– Talespin_Kit
15年3月6日在10:25
#3 楼
我很确定答案是ldconfig
。ldconfig在文件/中创建必要的链接并缓存到在命令行指定的目录中找到的最新共享库。 etc / ld.so.conf以及受信任目录(/ lib和/ usr / lib)中。高速缓存由运行时链接程序ld.so或ld-linux.so使用。 ldconfig在确定哪些版本应更新其链接时检查其遇到的库的标头和文件名。http://linux.die.net/man/8/ldconfig
#4 楼
对于正在运行的应用程序,文件/proc/1234/maps
包含所有实际的动态链接库。 其中
1234
是正在运行的可执行文件的pid。 Linux遵循LD_LIBRARY_PATH和其他变量,正如Gilles在回答中指出的。
评论
很高兴您在第二句话中确认吉尔斯的答案会有所帮助。但是,第一部分完全没有解释如何告诉a.out文件在哪里,只有在已经找到文件的情况下才告诉它们。总而言之,这仅是评论,而不是答案。
–安东
15年10月15日在15:24
评论
一个快速的解决方案是使用g ++ -Wl,-R。这将迫使加载程序在当前文件夹中查找so库。或-Wl,-R $ HOME / path指定其他一些固定文件夹。