首页 > *nix应用编程, *nix技术, 应用程序 > 修改程序加载动态库搜寻路径的三种可行方法

修改程序加载动态库搜寻路径的三种可行方法

2013年10月16日 发表评论 阅读评论 4,412 次浏览

1,影响整个系统里所有程序的修改
以ubuntu为例,在/etc/ld.so.conf.d目录下新增一个配置文件,名词任意,比如为mylib.conf:

lenky@Ubuntu:/etc/ld.so.conf.d$ sudo vi mylib.conf
[sudo] password for lenky: 
lenky@Ubuntu:/etc/ld.so.conf.d$ cat mylib.conf
/home/lenky/lib
/usr/lib/otherapp/lib

指定了动态库的加载路径为/home/lenky/lib
执行ldconfig进行更新/etc/ld.so.cache:

lenky@Ubuntu:/etc/ld.so.conf.d$ sudo ldconfig

也就是说/etc/ld.so.cache里保存了系统在执行应用程序加载动态库的默认搜索路径。动态库的搜索是有先后顺序的,先找到谁就使用谁。

2,影响特定环境下所有程序的修改
这利用的是LD_LIBRARY_PATH环境变量,在程序执行而加载动态库时,首先搜索的是LD_LIBRARY_PATH指定的路径,然后再是/etc/ld.so.cache包含的系统默认搜索路径。因此,如果主动指定某环境下的LD_LIBRARY_PATH环境变量,那么就能够影响该环境下的所有应用程序执行时加载动态库的搜索路径。

3,影响单个程序的修改
如果我只想指定某一个程序myexe的动态库搜索路径,比如我要把某个程序分发给用户,但又不知道用户电脑上是否安装了对应的依赖库或依赖库版本是否一致等,那么我干脆就提供这份库,并让我的程序myexe在执行时链接到我所提供的这份库,但又不能影响到用户电脑上的其他程序。
那么根据第2点的变通办法有:
a,创建一个脚本wrapper,在这个脚本里export LD_LIBRARY_PATH或setenv LD_LIBRARY_PATH环境变量,然后执行程序。
b,创建一个程序wrapper,在这个程序export LD_LIBRARY_PATH环境变量,然后exec执行程序。
总之,也就是为执行这个程序myexe而创建一个单独的环境,并在这个环境里设置好LD_LIBRARY_PATH。可以实现既定目的,但会比较麻烦,一种更简单的方法是利用gcc的-rpath参数。
有一段引用:

-rpath=dir
Add a directory to the runtime library search path. This is used
when linking an ELF executable with shared objects. All -rpath
arguments are concatenated and passed to the runtime linker, which
uses them to locate shared objects at runtime.

-L searchdir
–library-path=searchdir
Add path searchdir to the list of paths that ld will search for
archive libraries and ld control scripts.

简而言之,-L指定程序编译时的库搜索路径,而-rpath指定程序执行时的库搜索路径。
指定单个程序执行时的库搜索路径,利用-rpath即可,比如:
-Wl,-rpath,/path/to/foo -L/path/to/foo -lbaz
注意其中的-Wl,这表示它后面的参数是要传递给linker程序ld的。通过这几个参数会让ld会在连接程序时,在程序里写上对应的elf动态段属性RPATH:

lenky@Ubuntu:~/test$ cat t.c 
#include <stdio.h>

int main()
{
	printf("\a");
}
lenky@Ubuntu:~/test$ gcc -o t -Wl,-rpath,/usr/lib,-rpath,/home/lenky/lib,-rpath,/opt t.c 
lenky@Ubuntu:~/test$ readelf -a t | grep RPATH
 0x0000000f (RPATH)                      Library rpath: [/usr/lib:/home/lenky/lib:/opt]

如果在编译时,库也在这几个特定路径,那么需要用-L来指定,以免编译时提示出错。
程序myexe执行时,就可以搜索RPATH内指定的路径了。

参考:
http://stackoverflow.com/questions/8482152/whats-the-difference-between-rpath-and-l
http://stackoverflow.com/questions/6562403/i-dont-understand-wl-rpath-wl
http://en.wikipedia.org/wiki/Rpath

转载请保留地址:http://www.lenky.info/archives/2013/10/2354http://lenky.info/?p=2354


备注:如无特殊说明,文章内容均出自Lenky个人的真实理解而并非存心妄自揣测来故意愚人耳目。由于个人水平有限,虽力求内容正确无误,但仍然难免出错,请勿见怪,如果可以则请留言告之,并欢迎来讨论。另外值得说明的是,Lenky的部分文章以及部分内容参考借鉴了网络上各位网友的热心分享,特别是一些带有完全参考的文章,其后附带的链接内容也许更直接、更丰富,而我只是做了一下归纳&转述,在此也一并表示感谢。关于本站的所有技术文章,欢迎转载,但请遵从CC创作共享协议,而一些私人性质较强的心情随笔,建议不要转载。

法律:根据最新颁布的《信息网络传播权保护条例》,如果您认为本文章的任何内容侵犯了您的权利,请以Email或书面等方式告知,本站将及时删除相关内容或链接。

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.