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 记录已经生成的库文件链接关系
参考链接: