摘自http://blog.csdn.net/saga1979/article/details/14161229

man ld.so(8)说,如果库依赖不包括“/”,那么它将按照下面的规则按顺序搜索:

  • (仅对ELF格式)如果可执行文件包含DT_RPATH标签,并且不包含DT_RUNPATH标签,将从DT_RPATH列出的路径搜索。(DT_RPATH已经被废弃,请用DT_RUNPATH)
  • 如果LD_LIBRARY_PATH在程序运行时被定义,那么将从它包含的路径开始。安全起见,对于set-user-ID或者set-group-ID的程序,这个变量将被忽略。
  • (仅对ELF格式)如果可执行文件包含DT_RUNPATH标签,将从这个标签列出的路径开始搜索。
  • 从 /etc/ld.so.cache(运行ldconfig产生)中查找文件
  • 从/lib以及/urs/lib,按顺序搜索。如果链接时指定-z nodefaultlib,这个步骤将被忽略。
看起来够简洁的,当做休闲,写个程序验证一下。但在这之前,先介绍一个Glibc扩展的函数(POSIX中没有)
 
  1. #define _GNU_SOURCE
  2. #include <dlfcn.h>
  3. int dladdr(void* addr, Dl_info *info);

这个函数解析传入的函数指针(第一个参数),将信息填充到Dl_info的结构体

  1. typedef struct {
  2. const char *dli_fname;  /* Pathname of shared object that contains address */
  3. void       *dli_fbase;  /* Address at which shared object  is loaded */
  4. const char *dli_sname;  /* Name of nearest symbol with addresslower than addr */
  5. void       *dli_saddr;  /* Exact address of symbol named in dli_sname */
  6. } Dl_info;

下面是程序以及需要加载的动态库的代码:

ld_main.c:
  1. int main()
  2. {
  3. lib_fun();
  4. return 0;
  5. }

ld_lib.c:

  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <dlfcn.h>
  4. int lib_fun()
  5. {
  6. Dl_info dl_info;
  7. dladdr((void*)lib_fun, &dl_info);
  8. fprintf(stdout, ".so@ %s.\n", dl_info.dli_fname);
  9. return 0;
  10. }

编译这两个文件:

1、动态库:gcc --shared -fPIC ld_lib.c -o libld_lib.so -ldl
2、主程序:gcc ld_main.c -o ld_main -Wl,-rpath,./  -ldl -lld_lib -L./
 
-Wl,-rpath编译选项将在程序中生成DT_RPATH节点,使用readelf会看到Library rpath被设为当前目录:
 
 

接下来将生成的libld_lib.so拷贝到前面介绍到的搜索路径:

对于LD_LIBRARY_PATH,随便设置:export LD_LIBRARY_PATH=../

对于ld.so.conf提到的路径,在/etc/ld.so.conf.d/下面随便找一个,或者自己建立一个,这里用系统自带的libc.conf

中提到的路径:/usr/local/lib

然后运行(每次都删除程序优先加载的so文件):

(ld.so.conf路径更新文件后需要运行ldconfig更新cache,否则会找不到文件,如上图)。

关于-z nodefaultlib链接选项:

看来它真起作用了

关于DT_RUNPATH,需要用到--enable-new-dtags链接选项:

(linux下程序默认不会从当前路径搜索.so文件,这对于自行开发的分为很多模块,要安装在同一目录的“程序”来说不是个优点。还好可以用DT_RUNPATH指定.so的加载路径)

Linux(gnu)环境动态链接库的搜索路径的更多相关文章

  1. Linux C语言头文件搜索路径

    本文介绍在linux中头文件的搜索路径,也就是说你通过include指定的头文件,linux下的gcc编译器它是怎么找到它的呢.在此之前,先了解一个基本概念. 头文件是一种文本文件,使用文本编辑器将代 ...

  2. Linux下的库文件搜索路径

        对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执行 ...

  3. Linux下的头文件搜索路径

         对于以压缩包发布的软件,在它的目录下通常都有一个配置脚本configure,它的作用确定编译参数(比如头文件位置.连接库位置等),然后生成Makefile以编译程序.可以进入该软件的目录,执 ...

  4. linux动态库默认搜索路径设置的三种方法

    众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...

  5. Linux动态库(.so)搜索路径

    主要内容: 1.Linux动态库.so搜索路径 编译目标代码时指定的动态库搜索路径: 环境变量LD_LIBRARY_PATH指定的动态库搜索路径: 配置文件/etc/ld.so.conf中指定的动态库 ...

  6. Linux动态库搜索路径的技巧

    众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径 ...

  7. linux 查看可执行文件动态链接库相关信息(转)

    转自 http://blog.sina.com.cn/s/blog_67eb1f2f0100mgd8.html ldd <可执行文件名>       查看可执行文件链接了哪些  系统动态链 ...

  8. Linux 指定运行时动态库路径【转】

    转自:http://www.cnblogs.com/cute/archive/2011/02/24/1963957.html 众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/l ...

  9. linux 头文件以及库的路径

    原来在编译的时候可以指定执行时去哪里找需要的lib文件,长知识了 本文详细介绍了Linux 下gcc头文件指定方法,以及搜索路径顺序的问题.另外,还总结了,gcc动态链接的方法以及路径指定,同样也讨论 ...

随机推荐

  1. Jquery时间验证和转换工具

    var TimeObjectUtil; /** * @title 时间工具类 * @note 本类一律违规验证返回false * @author {boonyachengdu@gmail.com} * ...

  2. Seletion Sort

    referrence: GeeksforGeeks The selection sort algorithm sorts an array by repeatedly finding the mini ...

  3. 剑指offer-面试题21.包含min函数的栈

    题目:定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数. 在该栈中,调用min,push及pop的时间复杂度都是O(1). 这一题实际上需要一个辅助栈存储最小值: 1.在模板类定 ...

  4. Lake Counting (POJ No.2386)

    有一个大小为N*M的园子,雨后积起了水,八连通的积水被认为是链接在一起的求出园子里一共有多少水洼? *** *W* *** /** *进行深度优先搜索,从第一个W开始,将八个方向可以到达的 W修改为 ...

  5. jsp用jstl标签比较枚举

    日向博客最近在优化,有这一样一个小问题,我希望在下面的消息中心页面,未读的消息链接显示蓝色,已读的消息显示红色: 这就需要用jstl做一个判断. 之前的代码是这种形式: 消息中心:<br> ...

  6. oracle Can't connect to X11 window server using ':0.0' /Checking monitor: must be configured to display at least 256 colors解决方法

    Can't connect to X11 window server using ':0.0' 解决方法 1. 以oracle 用户登陆X window 或者 2. root 身份执行 # xhost ...

  7. PHP.INI常用设置一览表(持续更新)

    在编程的过程中遇到或发现的问题,会持续的更新: 1. 打破var_dump的显示瓶颈 php开发环境里,安装了xdebug模块后,var_dump()输出的结果将比较易于查看,但默认情况下,var_d ...

  8. Android SQLite的使用1(非原创)

    1.继承SQLiteOpenHelper :public class MyOpenHelper extends SQLiteOpenHelper {} 2.重写下面3个方法 package com.e ...

  9. SQL-LINQ-Lambda 语法对照

    SQL LINQ Lambda  SELECT *FROM Employees from e in Employees  select e Employees .Select (e => e)  ...

  10. 由WSDL文件生成WEB service server端C#程序(转)

    一般一个已经实现功能的WEB Server会发布自己的WSDL文件,供客户端生成代理类. 但有时是先有的server与client交互的接口定义(WSDL)文件,然后由server和client端分别 ...