man ld.so(8)说,如果库依赖不包括“/”,那么它将按照下面的规则按顺序搜索:
#define _GNU_SOURCE #include <dlfcn.h> int dladdr(void* addr, Dl_info *info);
typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Address at which shared object is loaded */ const char *dli_sname; /* Name of nearest symbol with addresslower than addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
int main() { lib_fun(); return 0; }
#define _GNU_SOURCE #include <stdio.h> #include <dlfcn.h> int lib_fun() { Dl_info dl_info; dladdr((void*)lib_fun, &dl_info); fprintf(stdout, ".so@ %s.\n", dl_info.dli_fname); return 0; }
接下来将生成的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的加载路径)