链接动态库

如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。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
2
3
4
5
6
7
8
9
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 thisway is only supported by nativelinkers and cross linkers which have been configured with the --with-sysroot option.
       3.  On an ELF system, fornative linkers, ifthe -rpath and -rpath-link options were not used, search the contents of the environment variable"LD_RUN_PATH".
       4.  On SunOS, ifthe -rpath option was not used, search any directories specified using -L options.
       5.  For a nativelinker, the search the contents of the environment variable "LD_LIBRARY_PATH".
       6.  For a nativeELF linker, the directories in "DT_RUNPATH"or "DT_RPATH"of a shared library are searched forshared libraries needed by it. The "DT_RPATH"entries are ignored if"DT_RUNPATH" entries exist.
       7.  The defaultdirectories, normally /lib and /usr/lib.
       8.  For a nativelinker on an ELF system, ifthe 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 continuewith 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:

?
1
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.

动态库的链接和链接选项-L,-rpath-link,-rpath相关推荐

  1. linux编译动态库未定义,GCC链接库的一个坑:动态库存在却提示未定义动态库的函数...

    背景 在GCC中已经指定链接库,然而编译时却提示动态库函数未定义! 测试出现的错误提示如下: [GMPY@13:48 tmp]$gcc -o test -L. -lmylib test.c /tmp/ ...

  2. IOS动态库打包导入工程报错Library not loaded: @rpath/SwiftFrame.framework/SwiftFrame

    IOS15动态库打包导入工程报错Library not loaded: @rpath/SwiftFrame.framework/SwiftFrame 环境: IOS 15.0 Xcode 13.0 最 ...

  3. linux中动态链接库用扩展名,Linux操作系统下动态库的生成及链接方法是什么?...

    Linux下动态库文件的扩展名为".so"(Shared Object).按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号).这样,线程函数库被称作l ...

  4. linux 动态库 软链接,Linux操作系统下动态库的生成及链接方法

    下动态库文件的扩展名为".so"(Shared Object).按照约定,所有动态库文件名的形式是libname.so(可能在名字中加入版本号).这样,线程函数库被称作 libth ...

  5. 使用VS2017生成的动态库时出现__acrt_iob_func链接错误

    使用VS2013等版本进行程序开发时,若用到VS2017或更高版本编译的动态链接库,编译时会出现一些特殊的链接错误,其中一个错误是关于__acrt_iob_func的: error LNK2001: ...

  6. 【转载】linux静态链接库与动态链接库的区别及动态库的创建

    这篇文章对于动态库的概念及使用介绍的很不错,故收藏了. 一.引言 通常情况下,对函数库的链接是放在编译时期(compile time)完成的.所有相关的对象文件(object file)与牵涉到的函数 ...

  7. 【Android NDK 开发】Android Studio 使用 CMake 导入动态库 ( 构建脚本路径配置 | 指定动态库查找路径 | 链接动态库 )

    文章目录 I . CMake 引入动态库与静态库区别 II . Android Studio 中 CMake 引入动态库流程 III . 指定动态库查找路径 IV . 链接函数库 V . 完整代码示例 ...

  8. 静态库、动态库、静态链接、动态链接、系统运行库混合、MD MT默认库冲突问题

    一.静态库项目 静态库lib:(注意和"静态运行库"区分)   就是.lib文件,一个.c或.cpp会编译成一个.obj,多个.obj可以组合成一个.lib库.lib=多个obj. ...

  9. 链接两个“名字完全一样”的【动态库】,你会怎么处理?

    作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 目录 文章目录 第一个动态库文件 应用程序 第二个动态库文件 错误做法:直接给它改名 正解:patchelf 工具 On ...

  10. C程序编译过程及常见选项--静态库和动态库

    C程序编译过程及常见选项--静态库和动态库 前言 一.gcc详讲 1.1 编译过程 1.2 预处理 1.3 编译(Compilation) 1.4 汇编(Assembly) 1.5 链接(Linkin ...

最新文章

  1. Linux用Openssl为Apache签发证书
  2. 这个为生信学习打造的开源Linux教程真香!!!
  3. flash一个按钮控制动画_flutter闪屏过渡动画,闪光占位动画
  4. 年薪28万 ~60万+,北理工计算机学院可视媒体计算团队诚招博士后
  5. 大四阶段的社会实践的主要目的是_大四寒假社会实践报告1500字范文
  6. java digests.generatesalt_Java DigestUtils.sha1Hex方法代碼示例
  7. cvpr2020 人脸检测与识别_CVPR2020 论文分类下载 「人脸识别+目标检测」
  8. Android WebView 加载超长 JS 数据
  9. POJ 3641 Pseudoprime numbers (miller-rabin 素数判定)
  10. IE8 SysFader:IEXPLORE.EXE应用程序错误解决办法
  11. 基于访客的网络(VBN)
  12. Http请求体被转义
  13. (轉貼) 千頭萬緒 : 學習多執行緒程式設計的好書 (.NET) (Java)
  14. mate30首发鸿蒙系统,华为mate30首发鸿蒙系统,mate20 Pro再降两千元
  15. CDN内容分发网络(上)
  16. Android面试题集锦
  17. (一)protege之使用入门
  18. 扫地机器人哪个牌子好?合格的扫地机器人推荐
  19. 舆情监测系统软件如何选择及系统作用详介
  20. Java 架构师眼中的 HTTP 协议

热门文章

  1. linux游戏调试,LINUX游戏服务器的安装与调试.doc
  2. 无代码调整聚类热图分支顺序
  3. 精选| 2020年8月R新包推荐(第45期)
  4. Cell Research | 单细胞测序技术揭示派杰氏病的致病机制
  5. 两篇Science文章揭示癌症治疗中细胞感应氧气的新机制
  6. 12产品经理要懂的-人性满足思维
  7. anjular.js读取数据库数据调用实例
  8. Vue第一部分(4):表单的双向数据绑定:v-model指令
  9. python爱因斯坦的问题_爱因斯坦的思考题.py
  10. Web笔记-使用jsonp解决跨域请求(CROS)问题