最后编译其他程序
创建库存档是为了能在其他程序中使用它,当你把存档安装到标准目录后,就可以用-l
开关编译代码:
现在知道为什么要把存档命名为libXXX.a了吧。-l
选项后的名字必须与存档名的一部分匹配。如果你的存档叫libawesome.a,可以用-lawesome
开关编译程序。
如果想把存档放在其他地方呢?比如/my_lib。你可以用-L
选项告诉编译器去哪个目录查找存档:
gcc test_code.c -L/my_lib -lhfsecurity -o test_code
百宝箱
为什么不同机器库目录的内容相差这么多?因为不同操作系统提供了不同的服务。每个.a文件都是一个独立的库,有的库用来连接网络,有的用来创建GUI程序。
我们找几个.a文件来试用一下
nm
命令。每个模块都列出了很多名字,它们是一些已经编译好了的函数,你可以在程序中使用它们:
nm
命令会告诉你每个.o目标文件的名字,然后列出所有目标文件中的名字,如果某个名字前出现了T
,就说明它是目标文件中某个函数的名字。
Make冰箱贴
安保人员在使用新版安全库编译银行程序时遇到了问题。他把自己的源代码和encrypt
、checksum
的源代码放在了同一个目录下,他想在这个目录中创建libhfsecurity.a存档,然后用它来编译程序,你能帮他补全makefile吗?
注意:bank_vault
程序用了下面的#include
语句:
Make冰箱贴解答
安保人员在使用新版安全库编译银行程序时遇到了问题。他把自己的源代码和encrypt
、checksum
的源代码放在了同一个目录下,他想在这个目录中创建libhfsecurity.a存档,然后用它来编译程序,你将帮助他补全makefile。
注意:bank_vault
程序用了下面的#include
语句:
要点
使用尖括号(
<>
),编译器就会从标准目录中读取头文件。常见的标准头文件目录有/usr/include和C:\MinGW\include。
一个库存档中有多个目标文件。
可以用
ar –rcs libarchive.a file0.o file1.o…
创建存档。库存档名应以lib开头,以.a结尾。
如果想链接一个叫libfred.a的存档,就使用
-lfred
选项。在
gcc
命令中,-l
标志应该在源代码文件后出现。
这里没有蠢问题
问:我怎样才能知道计算机上哪些目录是标准库目录?
答:你需要查看编译器文档。在大多数类Unix操作系统中,标准库目录有/usr/lib和/usr/local/lib。
问:我想把库存档放到/usr/lib目录下,但计算机不许我那么做,为什么?
答:出于安全考虑,操作系统为了防止你一不小心破坏某个库,会禁止你往标准目录中写文件。
问:
ar
命令的存档格式在所有系统中都是一样的吗?答:不是,虽然不同平台之间存档格式区别不大,但存档中目标代码的格式在不同操作系统中可谓天差地别。
问:创建库存档以后能不能查看里面的内容?
答:可以,
ar –t <文件名>
会列出存档中的目标文件。问:存档会像可执行文件那样把目标文件链接在一起吗?
答:不会,目标文件以独立文件的形式保存在存档中。
问:我可以把任何类型的文件放在存档中吗?
答:不可以,
ar
命令会先检查文件类型。问:我能从存档中提取某个目标文件吗?
答:可以的,你可以使用
ar –x libhfsecurity.a encrypt.o
命令把encrypt.o文件从libhfsecurity.a中提取出来。问:为什么要叫“静态”链接?
答:因为一旦链接以后就不能修改。静态链接就好比在咖啡中加入牛奶,混在一起就不能再分开。
问:我能用Head First安全库保护银行数据的安全吗?
答:最好不要这么做。
链接器有约
本周访谈:
你到底是做什么的?
Head First:链接器,非常感谢你能抽出时间来参加我们的节目。
链接器:我很高兴来到这里。
Head First:你有没有觉得开发人员忽视了你?他们压根不知道你是干嘛的。
链接器:我不太善于交际,很多人不会通过ld
命令直接与我对话。
Head First:ld
?
链接器:ld
正是鄙人。
Head First:屏幕上显示了很多选项。
链接器:确实如此。我有很多选项,它们代表链接程序的不同方法,这就是为什么一些人只用gcc
命令。
Head First:编译器也能链接文件吗?
链接器:编译器会制定链接方案,然后调用我。我会默默地把它们链接起来,你完全不知道我的存在。
Head First:我还有一个问题……
链接器:什么?
Head First:我知道这个问题很愚蠢,但你到底是做什么的?
链接器:我把编译后的代码缝合起来,有点儿像电话接线员做的工作。
Head First:不明白。
链接器:老式电话接线员会把两个地方的电话线路连接起来,这样两边的人才能通话,目标文件也是如此。
Head First:怎么说?
链接器:一个目标文件可能需要调用另一个目标文件中的函数,我会把这个文件中的函数调用与那个文件中的函数链接在一起。
Head First:那你一定很有耐心。
链接器:我喜欢做这种事,没事的时候我会绣十字绣。
Head First:真的啊?
链接器:开玩笑的。
Head First:谢谢你,链接器。