动态库的链接和链接选项-L,-rpath-link,-rpath

链接动态库

如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录,然后按照/etc/ld.so.conf里面的配置搜索绝对路径。同时,Linux也提供了环境变量LD_LIBRARY_PATH供用户选择使用,用户可以通过设定它来查找除默认路径之外的其他路径,如查找/work/lib路径,你可以在/etc/rc.d/rc.local或其他系统启动后即可执行到的脚本添加如下语句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路径优先于系统默认路径之前查找(详细参考《使用LD_LIBRARY_PATH》)。

不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》 )。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。

链接选项和路径

现代连接器在处理动态库时将链接时路径(Link-time path)和运行时路径(Run-time path)分开,用户可以通过-L指定连接时库的路径,通过-R(或-rpath)指定程序运行时库的路径,大大提高了库应用的灵活性。比如我们做嵌入式移植时#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉编译好的zlib库),将target编译好后我们只要把zlib库拷贝到开发板的系统默认路径下即可。或者通过-rpath(或-R )、LD_LIBRARY_PATH指定查找路径。

链接器ld的选项有 -L,-rpath 和 -rpath-link,看了下 man ld,大致是这个意思:

-L: “链接”的时候,去找的目录,也就是所有的 -lFOO 选项里的库,都会先从 -L 指定的目录去找,然后是默认的地方。编译时的-L选项并不影响环境变量LD_LIBRARY_PATH,-L只是指定了程序编译连接时库的路径,并不影响程序执行时库的路径,系统还是会到默认路径下查找该程序所需要的库,如果找不到,还是会报错,类似cannot open shared object file。

-rpath-link:这个也是用于“链接”的时候的,例如你显示指定的需要 FOO.so,但是 FOO.so 本身是需要 BAR.so 的,后者你并没有指定,而是 FOO.so 引用到它,这个时候,会先从 -rpath-link 给的路径里找。

-rpath: “运行”的时候,去找的目录。运行的时候,要找 .so 文件,会从这个选项里指定的地方去找。对于交叉编译,交叉编译链接器需已经配置 --with-sysroot 选项才能起作用。也就是说,-rpath指定的路径会被记录在生成的可执行程序中,用于运行时查找需要加载的动态库。-rpath-link 则只用于链接时查找。

链接搜索顺序

直接man ld。The linker uses the following search paths to locate required shared libraries:

       1.  Any directories specified by -rpath-link options.
       2.  Any directories specified by -rpath options.  The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option.
       3.  On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH".
       4.  On SunOS, if the -rpath option was not used, search any directories specified using -L options.
       5.  For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH".
       6.  For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist.
       7.  The default directories, normally /lib and /usr/lib.
       8.  For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file.
       If the required shared library is not found, the linker will issue a warning and continue with the link.

gcc和链接选项的使用

在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl(是字母l,不是1,我曾多次弄错),以区别不是编译器的选项。

if the linker is being invoked indirectly, via a compiler driver (e.g. gcc) then all the linker command line options should be prefixed by -Wl, (or whatever is appropriate for the particular compiler driver) like this:

<!-- lang: shell -->
gcc -Wl,--start-group foo.o bar.o -Wl,--end-group

This is important, because otherwise the compiler driver program may silently drop the linker options, resulting in a bad link.

转载于:https://my.oschina.net/shelllife/blog/115958

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: k来指定程序运行时动态的搜索路径。这两个选项可以在编译链时使用,用于指定程序运行时动态的搜索路径。其中,-rpath选项用于指定程序运行时动态的搜索路径,-rpath-link选项用于指定程序编译链动态的搜索路径。这两个选项可以帮助程序在运行时正确地加载所需的动态,从而避免出现动态加载失败的情况。 ### 回答2: -rpath-rpath-link是两种用于设置运行时共享搜索路径的选项。在Linux系统中,当程序运行时需要动态共享(例如,libc.so,libpthread.so等),它会在默认的搜索路径(如/lib、/usr/lib等)中查找这些。 但有时我们需要在程序运行时指定其他路径来查找共享,例如我们自己编译的。这时就需要用到-rpath-rpath-link选项-rpath选项用于指定在运行时共享搜索路径中添加一个目录。例如,如果我们的文件在/usr/lib/mylib目录下,那么我们可以使用以下命令编译程序: gcc -o myprog myprog.c -L/usr/lib/mylib -lmylib -Wl,-rpath=/usr/lib/mylib 这样,当myprog程序在运行时需要加载libmylib.so时,它会在默认路径下查找,但会优先查找/usr/lib/mylib目录。 -rpath-link选项类似于-rpath,不同的是它只影响动态文件,而不会影响程序本身的搜索路径。例如: gcc -o myprog myprog.c -L/usr/lib/mylib -lmylib -Wl,-rpath-link=/usr/lib/mylib 这样,当myprog程序在运行时需要加载它的动态libmylib.so时,它会在默认路径下查找,但会优先查找/usr/lib/mylib目录。 需要注意的是,-rpath-rpath-link选项只影响当前编译的程序,对其他程序没有影响。如果我们需要让所有程序都在指定目录下查找动态,可以把目录添加到/etc/ld.so.conf文件中,然后运行ldconfig更新共享缓存。 综上所述,-rpath-rpath-link选项是用于设置程序运行时共享搜索路径的重要选项,可以让我们灵活地管理自己编译的文件。 ### 回答3: -rpath-rpath-link是GCC编译器中的一个非常有用的选项,它可以帮助我们在编译链时指定运行时的搜索路径。 -rpath选项可以让我们指定一个目录,在该目录中寻找动态,这样我们就可以避免在程序使用时出现“找不到”的错误。当我们使用-rpath选项时,我们需要在链时指定该选项,否则编译器会默认使用系统的路径。 -rpath-link选项-rpath类似,它可以指定链时使用的路径,但它只在链时起作用,不会影响程序运行时的搜索路径。这个选项通常用于将链脚本中的目录告诉运行时链器,从而指导它在搜索时使用正确的路径。 总的来说,使用-rpath-rpath-link选项,可以帮助我们在程序的编译和链过程中,指定正确的路径,避免运行时出现找不到的错误。 当然,使用这些选项需要我们在编写Makefile或使用自动化构建工具时,正确地指定路径,确保程序能够正确地编译和链。只有在使用-rpath-rpath-link选项时,我们才能更好地控制和管理搜索路径,确保我们的程序能够正确地运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值