共享库的搜索
共享库的搜索出了系统默认路径外,还可以通过下面方法指定。首先通过环境变量指定:
环境变量 |
---|
LIBRARY_PATH 编译期查找动态链接库路径, 导出给Makefile或者在Makefile开头指定; |
LD_LIBRARY_PATH 运行期查找动态链接库的路径,会在系统默认路径之前查找; |
还可以通过GCC参数指定:
编写Makefile一个好的习惯是先-L指定路径,在-l指定对应库的名字,防止同名的so找错了位置。
GCC参数 |
---|
-L 链接的时候去找的目录; |
-rpath 指定的路径会被记录在生成的可执行程序中,用于程序运行时; |
-rpath-link 用于链接时, 比如依赖的某个so库文件依赖了另一个so,而着另一个so没有显示指定,那么链接时会从 -rpath-link 给的路径找; |
搜索路径可以 man ld 查看:
The linker uses the following search paths to locate required shared libraries:
- Any directories specified by -rpath-link options.
- 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.- 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”.
- On SunOS, if the -rpath option was not used, search any directories specified using -L options.
- For a native linker, search the contents of the environment variable “LD_LIBRARY_PATH”.
- 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.- The default directories, normally /lib and /usr/lib.
- 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.
查看一个可执行文件依赖动态库的搜寻路径过程:
使用 LD_DEBUG 环境变量,命令写在同一行直接可被后面程序继承环境变量,不用再 export ,如下面看 test 可执行文件的动态库加载过程:
root@ubuntu:/media/sf_VMshare/so# LD_DEBUG=libs ./test
使用ldd -u
可以看出程序不需要链接的so,使用-Wl,--as-needed
编译选项就可以去除不需要链接的so. 如果ldd显示某些so not found,可以导出LD_LIBRARY_PATH后再试试。
出现链接问题可以用前面的方法调试,搜索的顺序如下
- 编译期指定的路径,如-Wl,-rpath,库的路径;
- LD_LIBRARY_PATH 指定的动态库搜索路(对setuid/setgid的程序无效,并且可以被链接器选项–library-path覆盖)
- DT_RUNPATH指定的动态库搜索路径(-Wl,–enable-new-dtags)
- /etc/ld.so.conf 中指定的动态库搜索路径 (通常有 /usr/local/lib)
- 默认路径 /lib 和 /usr/lib