链接详解--共享库
一. 共享库生成
组成共享库的目标文件和一般目标文件有所不同,在编译时要加-fPIC选项(生成与位置无关代码 Position Independent code)。
$gcc -c -fPIC stack/stack.c stack/push.c stack/pop.c stack/is_empty.c
一般目标文件称为Relocatable(可重定位文件),在链接时可以把目标文件中各段的地址做重定位。
制作共享库:
$gcc -shared -o libstack.so stack.o push.o pop.o is_empty.o
ldd查看可执行文件依赖于哪些共享库:
$ldd main
共享库的搜索路径:
$gcc main.c -g -L. -lstack -Istack -o main
$./main
./main:error while loading shared libraries:libstack.so:cannot open shared object file:No such file or directory.
共享库的搜索路径由动态链接器决定,从ld.so(8) Man page可以查到共享库路径的搜索顺序:
1. 首先在环境变量LD_LIBRARY_PATH所记录的路径中查找。
2. 然后从缓存文件/etc/ld.so.cache中查找。这个缓存文件由ldconfig命令读取配置文件/etc/ld.so.conf之后生成。
3. 如果上述步骤都找不到,则到系统默认的路径中查找,/usr/lib,然后是/lib。
添加搜索路径方法:
1. $export LD_LIBRARY_PATH=. ./main
临时性,不推荐。
2. 把动态库绝对路径添加到/etc/ld.so.conf中(每个路径一行),然后运行ldconfig。(推荐)
ldconfig除了处理/etc/ld.so.conf中配置的目录之外,还处理一些默认目录,如/lib,/usr/lib等,
处理之后生成/etc/ld.so.cache缓存文件,动态链接器就从这个缓存中搜索共享库。
3. 把共享库拷贝到/usr/lib或/lib目录。
库链接顺序问题:
1. http://adam8157.info/blog/2010/09/libraries-link-order/
2. 链接时库的顺序问题
3. undefined reference to: xxx
4. 剖析共享程序库
二. 共享库查看
查看动态链接库的所有函数:
nm yourlib.so
查找某一函数是否存在以及函数入口地址:
nm -D yourlib.so | grep -w yourFunction
三. 共享库命名
按照共享库的命名惯例,每个共享库有三个文件名:real name,soname和linker name。
soname是一个符号链接的名字,只包含共享库的主版本号,主版本号一致即可保证库函数的接口一致,
因此应用程序的.dynamic段只记录共享库的soname,只要soname一致,这个共享库就可以用。
使用共享库可以很方便地升级库文件而不需要重新编译应用程序,这是静态库没有的优点。
注:libc的版本号有一点特殊,libc-2.8.90.so的主版本号是6而不是2或2.8。
linker name仅在编译链接时使用,gcc的-L选项应该指定linker name所在的目录。
有的linker name是库文件的一个符号链接,有的是一段链接脚本(libc.so)。
示例:
real name:/lib/i386-linux-gun/libc-2.15.so
softname: /lib/i386-linux-gun/libc.so.6
linker name: /usr/lib/i386-linux-gun/libc.so
gcc -shared -Wl,soname,libstack.so.1 -o libstack.so.1.0 stack.o push.o pop.o is_empty.o
这样编译生成的库文件是libstack.so.1.0,是real name,soname是libstack.so.1。
需要首先创建linker name:
ln -s libstack.so.1.0 libstack.so
程序编译需要linker name,程序执行需要soname,最终指向real name。
四、Linux库和包名
一般地,dev为相关开发库包。
curses--cursor optimization光标优化--libncurses5-dev 现在常用的是new curses(ncurses)。
在ubuntu中,zlib是zlib1g,相应的zlib-devel叫zlib1g-dev。默认的安装没有zlib1g-dev。
sqlite库对应sqlite3, libsqlite3-dev。