指定运行时动态库搜索位置:-rpath链接指令的正确用法(相对路径or绝对路径)

当编译可执行程序时,若采用隐式链接,那么需要在编译时为可执行程序指定运行时动态库搜索地址,即利用rpath选项来告诉链接器在程序执行时到哪里去找它依赖的动态库。例子如下:

-Wl,-rpath,<path/to/lib>

注:有的编译器也支持-Wl,rpath = <path/to/lib>这种用法

那么,这里的路径应该采用相对路径还是绝对路径呢?

答:在rpath中使用相对路径是没有意义的,因为相对路径是相对于当前工作路径,而非相对于可执行程序本身所在的路径!!

举个例子:在home/test/下有个可执行程序mytest,它的依赖库是home/lib/下的mylib,在编译mytest时使用的命令是:

-Wl,-rpath,../lib

也就是告诉mytest,它依赖于一个动态库,动态库的运行时路径是../lib。那么,当cd到test下执行mytest时,可以成功运行;但假如切换到home下再执行/test/mytest,由于此时的工作路径是home,相对于当前路径并没有../lib,所以就找不到动态库了。

正确用法是利用$ORIGIN这个符号:

-Wl,-rpath,$ORIGIN../lib

这里的$ORIGIN代表了可执行文件所在的地址,那么,无论从什么位置唤醒(invoke)可执行程序,它都会从可执行程序所在的路径的../lib位置去找动态库。

事实上,$ORIGIN是一个ELF替代序列,代表了被载入的可执行程序在文件系统中所处的位置。其目的是允许可执行程序去指定一个动态库的相对搜索路径。在编译mytest时,这个符号被保留在mytes中。当我从home下执行/test/mytest时,runtime linker会把$ORIGIN替换为home/test/,那么动态库的位置就变成了home/test/../lib,也就是home/lib

 

后记:为了不被shell解释器误认为是一个变量,你需要使用单引号将$ORIGIN扩起来,像这样:

-Wl,-rpath,‘$ORIGIN’

如果你想在makefile中使用它,那么你还需要写成这样:

-Wl,-rpath,‘$$ORIGIN’

使用两个$$是因为:若只使用一个$,$O连在一起会被make认为是makefile自身定义的变量。

 

对于运行时加载器(或运行时链接器)是怎么去搜索动态库的,可使用man ld.so来查看更详细的说明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值