zoukankan      html  css  js  c++  java
  • GCC连接用户自定义的动态库的路径问题

    gcc在链接时通常用到的链接选项“-l”和“-L”分别用来指明需要链接的动态库名字及搜索路径,但是当使用的“-l”选项指定的库还有另外的依赖关系时,“-L”选项的参数无法提供对依赖库路径的包含。

    假设我们有如下文件和自定义库文件:

        ./main.c     

        ./lib/libtest.so

        ./lib/libtest2.so

    其中 main.c依赖libtest.so

    libtest.so又依赖libtest2.so

    当我们如下编译链接时:

      gcc -o test main.o -ltest -L./lib

    编译器按照如下顺序寻找库文件:

    • 首先会去找-L指定的参数目录
    • 再找gcc的环境变量LIBRARY_PATH指定的参数
    • 再找内定默认目录 /lib:/usr/lib: /usr/local/lib

    在以上目录中找到需要的库文件之后,编译器将找到库文件的信息传递给链接器进行链接。

    接着在调用链接器时,由于libtest.so又依赖libtest2.so,所以链接器接着去寻找libtest2.so文件,寻找顺序如下:

    • 所有由'-rpath-link'选项指定的搜索路径
    • 所有由'-rpath'指定的搜索路径
    • 如果'-rpath'和'rpath-link'选项没有被使用, 会搜索环境变量'LD_RUN_PATH'的内容(它也只对本地连接器起作用)
    • 对于一个本地连接器,环境变量'LD_LIBRARY_PATH'的内容被搜索.
    • 对于一个本地ELF连接器,共享库中的`DT_RUNPATH'和`DT_RPATH'操作符会被需要它的共享库搜索. 如果'DT_RUNPATH' 存在了, 那'DT_RPATH'就会被忽略.
    • 缺省目录, 常规的,如'/lib'和'/usr/lib'.
    • 对于ELF系统上的本地连接器, 如果文件'/etc/ld.so.conf'存在, 这个文件中有的目录会被搜索.

    如果需要的共享库没有被找到, 那连接器会发出一条警告信息

      ld: warning: libtest2.so  need by libtest.so  not found (try using -rpath or -rpath-link)

    说明链接器链接时,并未找到libtest.so需要的lianlibtest2.so文件。

    这就说明链接器链接时寻找依赖库的路径里不包含“-L"指定的路径,“-L”只是单纯的增加一个寻找指定库文件的路径。

    显然如果指定的库文件还依赖另外的库文件(例如libtest2.so),“-L"已经完成使命,则不会在寻找-L指定的目录。

    ld --help 也可以看到关于“-L”的解释 

          -L DIRECTORY, --library-path DIRECTORY
                                       Add DIRECTORY to library search path

     遇到这种情况,有几种方法

    1. 在环境变量LD_LIBRARY_PATH中添加搜索路径(不建议使用,因为是全局变量)
    2. 在/etc/ld.so.conf'.d/目录中增加conf文件(ldconfig)
    3. 根据链接器警告提示,使用'-rpath'跟'-rpath_link'
    4. 其他(我不知道的....)

     这里学习一下'-rpath'跟'-rpath_link'的用法,

    ld --help中关于-rpath和-rpath-link的解释是:

      -rpath PATH                   Set runtime shared library search path
      -rpath-link PATH             Set link time shared library search path

    即在连接时,链接器需要依赖库时还会去搜索-rpath-link指定的路径。

    -rpath为设置程序运行时搜索依赖库的路径,可以设置相对路径。

    编译器中使用-rpath和-rpath-link 的格式如下:

      gcc -Wl,rpath=/home/test:../lib:/usr/lib64

    -Wl(小写L),<选项>               将逗号分隔的 <选项> 传递给链接器

    不使用-Wl 编译器无法识别-rpath等选项。

    -rpath和-rpath-link可以指定多个目录,目录与目录之间用冒号分割

    参考:http://blog.csdn.net/youhaipeng/article/details/8213702

    参考:http://www.laogu.com/wz_2754.htm

  • 相关阅读:
    flex布局
    cookie设置、获取、删除
    使用Object对象的toString()方法自定义判断数据类型方法
    git使用汇总
    闭包和面向对象
    闭包
    java8之一文彻底弄懂lambda表达式
    正确理解MESI协议
    二叉树中的节点删除-----按照最底层最右边的节点收缩
    按层次插入二叉树
  • 原文地址:https://www.cnblogs.com/makeup1122/p/2973974.html
Copyright © 2011-2022 走看看