关于Linux动态库搜索路径

2013.08.23 updated

一 概念:这里将共享库(shared library)称做了动态库。

在Linux中,ELF格式的可执行文件或动态库有两个域,DT_RPATH,DT_RUNPATH(这个是新版本加入的)。

// 这个方法只写入DT_RPATH域gcc -g -Wall -o prog prog.c -Wl,-rpath,/home/dir1 -ldemo// 这个方法,同时写入DT_RPATH和DT_RUNPATHgcc -g -Wall -o prog prog.c -Wl,--enable-new-dtags -Wl,-rpath,/home/dir1 -ldemo

编译分为几个阶段,其中-W表示在哪个阶段将后面参数加入,-Wl表示在link阶段加入后面参数,-rpath是为linker指定runtime dynamic path参数。

至于为什么后面的要同时写入DT_RPATH和DT_RUNPATH域,是因为之前的版本没有DT_RUNTIME,为了和老版本程序兼容。

二 Linux动态库的搜索路径搜索的先后顺序是:

0> 如果DT_RUNPATH域为空,且DT_RPATH不为空,则搜索DT_RPATH指定的路径列表(多个用冒号隔开);

1>环境变量LD_LIBRARY_PATH指定的动态库搜索路径,多个路径可以用“:”分开;

2> 如果DT_RUNPATH不为空,那么搜索DT_RUNPATH对应的路径列表;

3>在/etc/ld.so.cache文件中指定,这个文件是一个二进制文件,如果想添加,先编辑配置文件/etc/ld.so.conf(这个文件是文本的),然后运行ldconfig生成新的/etc/ld.so.cache;

4>默认的动态库搜索路径/lib;

5>默认的动态库搜索路径/usr/lib。

以下是使用LD_LIBRARY_PATH的建议:

1> 不要全局设置LD_LIBRARY_PATH

2> 如果一定要用动态库的方式发布你的代码,并且允许用户自定义安装路径,那么

用.o文件发布,在安装过程中,重新连接它们到正确的安装路径。在可执行程序中,写一个非常冗长,不存在的路径(-Wl,-rpath),然后安装过程中,用一个二进制编辑器将其中的路径修改为正确的。3> 如果一定要用LD_LIBRARY_PATH,一定要包装起来用,例如,shell脚本。

讲一个我亲身体验的例子。

一个已经安装的软件包A,构建于平台Platform 1.0,所有的平台相关动态库文件位于/opt/lib64/

一个新的软件包B,构建于平台Platform 2.0,所有平台相关动态库位于本软件目录的/lib下

启动软件B,发现运行错误,运行ldd命令,发现连接的动态库不对,应该连本目录的lib,却连到了/opt/lib64/

用设置LD_LIBRARY_PATH的方法启动还是不行,因为路径已经写死到可执行文件里了,用strings命令可以看到二进制里的字符串。

后来查到两种解决办法:

1> 用二进制编辑器将可执行文件内的路径改写,/opt/lib64改成/opt/lib65,这样运行时找不到/opt/lib65,那么LD_LIBRARY_PATH就开始生效了。

2> 编译B之前,将configure.ac中的路径修改一下,使得传递给-Wl,-rpath的参数是一个不可能存在的路径。

要铭记在心;每天都是一年中最美好的日子

关于Linux动态库搜索路径

相关文章:

你感兴趣的文章:

标签云: