关于Linux动态库搜索路径

来源:互联网 发布:大型企业网络搭建 编辑:程序博客网 时间:2024/06/07 05:39

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的参数是一个不可能存在的路径。


原创粉丝点击