关于共享库的学习可以参看: 《程序员的自我修养》
1. 为什么需要SONAME?
Linux中提供了一个工具叫做“ldconfig”,当系统中安装或更新一个共享库时,就需要运行这个工具,它会遍历所有的默认共享目录,比如/lib、/usr/lib等,然后更新所有的软连接,是他们指向最新版的共享库; 如果安装了新的共享库,那么ldconfig会为其创建相应的软连接。如果新版本的共享库文件被意外删除了,则软连接将自动更新到较低版本的共享库文件。
但是,如果你的共享库没有指定SONAME ,则ldconfig将无法自动更新软连接。
2. 如何查看共享库的SONAME
1 |
readelf -d libphpor.so.1.0.0 | grep SONAME |
如图:
3. 不是所有的共享库都(必须)有SONAME,如何指定SONAME呢?
1 |
# gcc -shared -Wl,-soname,libphpor.so.1 -o libphpor.so.1.0.0 phpor.c |
注意:使用 -Wl,-soname,your_soname 指定 你的SONAME
4. 使用了ldconfig后,编译新的程序还是找不到共享库(-lphpor),为什么?
ldconfig 只是为我们创建了满足程序运行的软连接,没有创建供程序编译使用的软连接;需要手动创建软连接:
1 2 |
#cd /lib #ln -s libphpor.so.1 libphpor.so |
程序编译之后,就和该软连接没有关系了,程序将只依赖指定的SONAME了
5. 相关命令的演示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
[root@login ~]# gcc -shared -Wl,-soname,libphpor.so.1 -o libphpor.so.1.0.0 phpor.c [root@login ~]# vim phpor.c [3]+ Stopped vim phpor.c [root@login ~]# gcc -shared -Wl,-soname,libphpor.so.1 -o libphpor.so.1.0.1 phpor.c [root@login ~]# gcc -shared -Wl,-soname,libphpor.so.2 -o libphpor.so.2.0.0 phpor2.c [root@login ~]# cp libphpor.so.1.0.0 /lib/ [root@login ~]# ldconfig [root@login ~]# ll /lib/libphpor* lrwxrwxrwx 1 root root 17 Jul 29 20:02 /lib/libphpor.so.1 -> libphpor.so.1.0.0 -rwxr-xr-x 1 root root 4396 Jul 29 20:02 /lib/libphpor.so.1.0.0 [root@login ~]# gcc -lphpor -o test_phpor test_phpor.c /usr/bin/ld: cannot find -lphpor collect2: ld returned 1 exit status [root@login ~]# cd /lib [root@login lib]# ln -s libphpor.so.1 libphpor.so [root@login lib]# cd - /usr/home/junjie2 [root@login ~]# gcc -lphpor -o test_phpor test_phpor.c [root@login ~]# ./test_phpor hello world v1.0.0 [root@login ~]# echo "update to v1.0.1" update to v1.0.1 [root@login ~]# cp libphpor.so.1.0.1 /lib/ [root@login ~]# ldconfig [root@login ~]# ll /lib/libphpor* lrwxrwxrwx 1 root root 13 Jul 29 20:03 /lib/libphpor.so -> libphpor.so.1 lrwxrwxrwx 1 root root 17 Jul 29 20:04 /lib/libphpor.so.1 -> libphpor.so.1.0.1 -rwxr-xr-x 1 root root 4396 Jul 29 20:02 /lib/libphpor.so.1.0.0 -rwxr-xr-x 1 root root 4396 Jul 29 20:04 /lib/libphpor.so.1.0.1 [root@login ~]# ./test_phpor hello world v1.0.1 [root@login ~]# ldd test_phpor libphpor.so.1 => /lib/libphpor.so.1 (0x0086f000) libc.so.6 => /lib/tls/libc.so.6 (0x005f2000) /lib/ld-linux.so.2 (0x005d3000) [root@login ~]# echo "update to v2.0.0" update to v2.0.0 [root@login ~]# cp libphpor.so.2.0.0 /lib/ [root@login ~]# ldconfig [root@login ~]# ll /lib/libphpor* lrwxrwxrwx 1 root root 13 Jul 29 20:03 /lib/libphpor.so -> libphpor.so.1 lrwxrwxrwx 1 root root 17 Jul 29 20:04 /lib/libphpor.so.1 -> libphpor.so.1.0.1 -rwxr-xr-x 1 root root 4396 Jul 29 20:02 /lib/libphpor.so.1.0.0 -rwxr-xr-x 1 root root 4396 Jul 29 20:04 /lib/libphpor.so.1.0.1 lrwxrwxrwx 1 root root 17 Jul 29 20:06 /lib/libphpor.so.2 -> libphpor.so.2.0.0 -rwxr-xr-x 1 root root 4508 Jul 29 20:06 /lib/libphpor.so.2.0.0 [root@login ~]# echo "ldconfig can not update the /lib/libphpor.so ,only create /lib/libphpor.so.2, and it can not effect test_phpor" ldconfig can not update the /lib/libphpor.so ,only create /lib/libphpor.so.2, and it can not effect test_phpor [root@login ~]# ./test_phpor hello world v1.0.1 [root@login ~]# cd /lib/ [root@login lib]# unlink /lib/libphpor.so [root@login lib]# ln -s libphpor.so.2 libphpor.so [root@login lib]# ll /lib/libphpor* lrwxrwxrwx 1 root root 13 Jul 29 20:09 /lib/libphpor.so -> libphpor.so.2 lrwxrwxrwx 1 root root 17 Jul 29 20:04 /lib/libphpor.so.1 -> libphpor.so.1.0.1 -rwxr-xr-x 1 root root 4396 Jul 29 20:02 /lib/libphpor.so.1.0.0 -rwxr-xr-x 1 root root 4396 Jul 29 20:04 /lib/libphpor.so.1.0.1 lrwxrwxrwx 1 root root 17 Jul 29 20:06 /lib/libphpor.so.2 -> libphpor.so.2.0.0 -rwxr-xr-x 1 root root 4508 Jul 29 20:06 /lib/libphpor.so.2.0.0 [root@login lib]# cd - /usr/home/junjie2 [root@login ~]# ./test_phpor hello world v1.0.1 [root@login ~]# gcc -lphpor -o test_phpor test_phpor.c [root@login ~]# ./test_phpor hello world v2.0.0 |
6. 可以使用静态库生成共享库,不能使用共享库来编译出静态链接文件
gcc的 -static 的使用:(下面有些乱七八糟了,还没明白怎么回事儿)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@login ~]# gcc -static -o test_phpor_s test_phpor.c ./libphpor.so.1.0.0 [root@login ~]# export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH [root@login ~]# ./test_phpor_s bash: ./test_phpor_s: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory [root@login ~]# ldd test_phpor_s /usr/bin/ldd: ./test_phpor_s: /usr/lib/libc.so.1: bad ELF interpreter: No such file or directory [root@login ~]# readelf -d test_phpor_s Dynamic section at offset 0x6205c contains 21 entries: Tag Type Name/Value 0x00000001 (NEEDED) Shared library: [libphpor.so.1] 0x00000001 (NEEDED) Shared library: [libc.so.6] 0x0000000c (INIT) 0x804c30c |
7. 如何生成一个静态链接的共享库?
8.如何使用共享库生成一个静态链接文件?