函数链接库的5个特殊秘密

转自:《C专家编程》


1. 动态链接库的扩展名是“.so”,而静态链接库的扩展名是“.a”


2. 例如,你通过-lthread选项,告诉编译链接到libthread.so

换句话说,lib前缀和.so后缀都被省略了


3. 编译器期望在确定的目录找到库

一帮在环境变量LD_LIBRARY_PATH和LD_RUN_PATH中设置,也可以使用-Lpathname这个编译器选项来指定。出于安全性、性能和创建、运行独立性方面的考虑,使用环境变量的做法现在已经不提倡。一般还是在链接时使用-Lpathname和-Rpathname来指定。


4. 观查头文件,确认所使用的函数库。

怎样在函数库中观察一个符号:

如果在链接过程中遇到下面这个错误:

ld: undefined symbol

  _xdr_reference

*** Error code 2

make: Fatal error: Command failed for target 'prog'

它提示找不到符号xdr_reference的定义。这里有一种方法,可以通过它找到需要链接的库。基本的想法是使用nm命令在/usr/lib的每个函数库中浏览所有的符号,从中寻找所丢失的符号。在缺省情况下,链接器会在/usr/lib和/usr/ccs/lib中查找,你也应该从这两个地方着手。

% cd /usr/lib

% foreach i (lib?*)

?  echo $i

?  nm $i | grep xdr_reference | grep -v UNDEF

?  end


这会在/usr/lib目录中的所有函数库上运行"nm"程序,它显示函数库中已知的符号列表。通过grep设定需要搜索的符号,并过滤掉标记为“UNDEF”的符号(在该函数库中有引用,但不是在此处定义)。


5. 与提取动态库中的符号相比,静态库中的符号提取方法限制更严。

        在动态链接和镜头链接的语义上有一个巨大差别,archive(静态库)与共享对象(动态库)的动作不同。在动态链接中,所有的库符号进入输出文件的虚拟地址空间中,所有的符号对于链接在一起的所有文件都是可见的。相反,对于静态链接,在处理archive时,它只是在archive中查找载入器当时所知道的未定义符号。因此,使用静态链接的过程中,引入静态链接库的顺序是很重要的。如果相同的符号在两个不同的静态链接库中都有定义,那么静态库出现的顺序不同,编译的结果就可能不同。

        如果在自己的代码之前引入静态库,又会带来一个问题。因为此时尚未出现未定义的符号,所以它不会从库中提取任何符号。接着,当用户程序生成的目标文件被链接时,它的所有对函数库的引用都将是未实现的!因此,在进行编译时,始终将-l函数库选项放在编译命令选项的最右边。

你可能感兴趣的:(command,Path,library,reference,编译器,archive)