Linux中修改程序的run path
对于动态库的加载,不同的操作系统有不同的搜索策略。在windows下,程序会优先加载同路径中的动态库,这是一个非常方便的特性。而在linux下,需要单独配置 LD_LIBRARY_PATH
以实现上述类似特性。曾经困扰我很长一段时间的就是linux平台的动态库加载问题,最常出现的问题是程序启动时找不到所需要的动态库。在得知修改run path可以调整程序搜索动态库的路径时,一切都迎刃而解了。
使用 ldd
查看动态库加载信息
可以使用 ldd
查看是否能够成功找到程序所需要的动态库。在搜索成功的情况下会将动态库的绝对地址显示出来。
ldd <exec-file>
有时会有多个名称相同的动态库时在不同的路径中,通过这条命令也能够查看程序在运行时加载的是哪个动态库。
使用 chrpath
修改可执行程序的run path信息
linux程序的run path是ELF信息的一部分,保存了该程序在加载动态库时的搜索路径。chrpath是一个能够查看和修改run path的程序。我在包管理器中并没有搜索到这个软件包,最终通过编译源码的方式安装成功。
查看run path信息
chrpath -l <exec-file>
修改run path信息
chrpath -r '/target/path' <exec-file>
通过设置 LD_LIBRARY_PATH
增加动态库的查找路径
LD_LIBRARY_PATH
提供了一种额外的动态库搜索路径,它是一个环境变量,这个设置是对终端生效的。
可以在终端的配置文件中增加以下配置项,使程序在加载动态库搜索当前工作目录。
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
tips:需要注意的是,在linux下进行路径之间分隔符使用的是英文冒号。
rpath
和 LD_LIBRARY_PATH
的比较
rpath
和 LD_LIBRARY_PATH
都能提供额外的动态库搜索路径,这里主要谈谈它们之间的区别。
rpath
是对单个可执行程序生效的,对其他可执行程序没有影响。并且,它不依赖于工作目录和运行环境,这点非常重要,因为有时程序并不是由终端启动的,这样它的工作目录和环境是不可控的。
LD_LIBRARY_PATH
是对终端生效的,影响的是所有由该终端启动的程序。可以通过脚本包裹的方式使其仅对脚本中的程序生效。以下是示例脚本:
#!/bin/bash
LD_LIBRARY_PATH="$(pwd)/lib"
export LD_LIBRARY_PATH
./exec_app