链接详解--共享库

一. 共享库生成

组成共享库的目标文件和一般目标文件有所不同,在编译时要加-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。

posted @ 2015-10-14 20:19  yuxi_o  阅读(494)  评论(0编辑  收藏  举报