Linux C/C++ 共享库so的搜索路径和顺序

共享库的搜索

共享库的搜索出了系统默认路径外,还可以通过下面方法指定。首先通过环境变量指定:

环境变量
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:

  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, 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.

查看一个可执行文件依赖动态库的搜寻路径过程:
使用 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后再试试。

出现链接问题可以用前面的方法调试,搜索的顺序如下

  1. 编译期指定的路径,如-Wl,-rpath,库的路径;
  2. LD_LIBRARY_PATH 指定的动态库搜索路(对setuid/setgid的程序无效,并且可以被链接器选项–library-path覆盖)
  3. DT_RUNPATH指定的动态库搜索路径(-Wl,–enable-new-dtags)
  4. /etc/ld.so.conf 中指定的动态库搜索路径 (通常有 /usr/local/lib)
  5. 默认路径 /lib 和 /usr/lib

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值