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可以执行了,并打印出了运行结果。
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 ,而方法二仅根据库文件中的信息创建软连接。
sudo ldconfig -p
/lib/ld.so 动态库文件加载器
/etc/ld.so.conf 记录ldconfig默认的库目录搜索路径
/etc/ld.so.cache 记录已经生成的库文件链接关系
Linux下动态共享库加载时的搜索路径详解