linux cmds - ldconfig

ldconfig命令的大概作用是读取指定文件夹里的所有库文件,并根据库文件中包含的库文件名为其创建软链接文件。

用法一:读取目录directory下的所有/etc/ld.so.conf,根据其中包含的运行时链接的库文件名,为其创建软连接

sudo ldconfig directory

例如,在学习《unix环境高级编程》第七章getrlimit和setrlimit函数时,编译器代码getrlimit.c(位于~/apue.2e/environ下)通不过

dance@dance-desktop:~/apue.2e/environ$ ls
cmd1.c  doatexit    freebsd.mk   hello1.c  macos.mk    solaris.mk  testjmp.c
cmd2.c  doatexit.c  getrlimit.c  linux.mk  opendata.c  testjmp     testjmp.opt
dance@dance-desktop:~/apue.2e/environ$ gcc getrlimit.c -I../include
/tmp/ccp7K0V6.o: In function `pr_limits':
getrlimit.c:(.text+0x11c): undefined reference to `err_sys'
collect2: ld returned 1 exit status
dance@dance-desktop:~/apue.2e/environ$
其原因是找不err_sys函数的实现代码,经过一番搜索,发现其实现代码位于../lib/error.c中

dance@dance-desktop:~/apue.2e/environ$ ls ../lib/error.c
../lib/error.c
dance@dance-desktop:~/apue.2e/environ$ cat ../lib/error.c | grep err_sys
err_sys(const char *fmt, ...)
dance@dance-desktop:~/apue.2e/environ$ 
那么下一步我的想法就是把error.c编译成库文件liberror-1.1.0.so,为清晰表述我把getrlimit.c,error.c,apue.h复制到主目录下的text文件夹下,下面是我编译好的库文件:

dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit.c  liberror-1.1.0.so
dance@dance-desktop:~/test$ file liberror-1.1.0.so 
liberror-1.1.0.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped
dance@dance-desktop:~/test$ 
编译运行,却发现报如下错误:

dance@dance-desktop:~/test$ gcc getrlimit.c -o getrlimit -L$PWD -lerror-1.1.0
dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so
dance@dance-desktop:~/test$ ./getrlimit 
./getrlimit: error while loading shared libraries: liberror.so.1: cannot open shared object file: No such file or directory
dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so

发现可执行文件getrlimit在运行时链接的是liberror.so.1而不是liberror-1.1.0.so。liberror.so.1是我们在生成库文件时指定写入库文件的文件名,也是生成可执行文件getrlimit写入getrlimit的库文件名。

dance@dance-desktop:~/test$ readelf -a liberror-1.1.0.so | grep liberror.so.1
 0x0000000e (SONAME)                     Library soname: [liberror.so.1]
dance@dance-desktop:~/test$ readelf -a getrlimit | grep liberror.so.1
 0x00000001 (NEEDED)                     Shared library: [liberror.so.1]
dance@dance-desktop:~/test$
那么我们怎么创建liberror.so.1呢?有两种方法ln -s和ldconfig,这里只介绍使用ldconfig情况:

dance@dance-desktop:~/test$ ldconfig $PWD
/sbin/ldconfig.real: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
dance@dance-desktop:~/test$ sudo ldconfig $PWD                 //ldconfig执行需要root权限
[sudo] password for dance: 
dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so  liberror.so.1
dance@dance-desktop:~/test$ ./getrlimit
RLIMIT_AS       (infinite)  (infinite)
RLIMIT_CORE              0  (infinite)
RLIMIT_CPU      (infinite)  (infinite)
RLIMIT_DATA     (infinite)  (infinite)
RLIMIT_FSIZE    (infinite)  (infinite)
RLIMIT_LOCKS    (infinite)  (infinite)
RLIMIT_MEMLOCK       65536       65536  
RLIMIT_NOFILE         1024        1024  
RLIMIT_NPROC    (infinite)  (infinite)
RLIMIT_RSS      (infinite)  (infinite)
RLIMIT_STACK       8388608  (infinite)
dance@dance-desktop:~/test$ 
此时发现getrlimit可以执行了,并打印出了运行结果。

用法二:指定readlibraryname,根据其中包含的运行时链接的库文件名,为其创建软连接

sudo ldconfig -l readlibraryname              

例如,我们先删除上面创建的软连接在用此方法重新创建:

dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so  liberror.so.1
dance@dance-desktop:~/test$ rm liberror.so.1                     //删除软连接
dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so
dance@dance-desktop:~/test$ sudo ldconfig -l liberror-1.1.0.so   //重新创建
dance@dance-desktop:~/test$ ls
apue.h  error.c  error.o  getrlimit  getrlimit.c  liberror-1.1.0.so  liberror.so.1
dance@dance-desktop:~/test$ ./getrlimit 
RLIMIT_AS       (infinite)  (infinite)
RLIMIT_CORE              0  (infinite)
RLIMIT_CPU      (infinite)  (infinite)
RLIMIT_DATA     (infinite)  (infinite)
RLIMIT_FSIZE    (infinite)  (infinite)
RLIMIT_LOCKS    (infinite)  (infinite)
RLIMIT_MEMLOCK       65536       65536  
RLIMIT_NOFILE         1024        1024  
RLIMIT_NPROC    (infinite)  (infinite)
RLIMIT_RSS      (infinite)  (infinite)
RLIMIT_STACK       8388608  (infinite)
dance@dance-desktop:~/test$ 

注意:

方法一与方法二的区别在于:方法一会将链接关系写入缓存文件/etc/ld.so.cache ,而方法二仅根据库文件中的信息创建软连接。

用法三:/读取/etc/ld.so.conf中记录的所有目录中的readlibraryname和软链接文件名的对应关系

sudo ldconfig -p

重要文件

/lib/ld.so                 动态库文件加载器
/etc/ld.so.conf       记录ldconfig默认的库目录搜索路径

/etc/ld.so.cache    记录已经生成的库文件链接关系

参考链接:

Linux下动态共享库加载时的搜索路径详解


你可能感兴趣的:(linux,ldconfig,ld.so)