最后编译其他程序

创建库存档是为了能在其他程序中使用它,当你把存档安装到标准目录后,就可以用-l开关编译代码:

最后编译其他程序 - 图1

现在知道为什么要把存档命名为libXXX.a了吧。-l选项后的名字必须与存档名的一部分匹配。如果你的存档叫libawesome.a,可以用-lawesome开关编译程序。

最后编译其他程序 - 图2

如果想把存档放在其他地方呢?比如/my_lib。你可以用-L选项告诉编译器去哪个目录查找存档:

  1. gcc test_code.c -L/my_lib -lhfsecurity -o test_code

最后编译其他程序 - 图3百宝箱

为什么不同机器库目录的内容相差这么多?因为不同操作系统提供了不同的服务。每个.a文件都是一个独立的库,有的库用来连接网络,有的用来创建GUI程序。

我们找几个.a文件来试用一下nm命令。每个模块都列出了很多名字,它们是一些已经编译好了的函数,你可以在程序中使用它们:

最后编译其他程序 - 图4

nm命令会告诉你每个.o目标文件的名字,然后列出所有目标文件中的名字,如果某个名字前出现了T,就说明它是目标文件中某个函数的名字。

最后编译其他程序 - 图5Make冰箱贴

安保人员在使用新版安全库编译银行程序时遇到了问题。他把自己的源代码和encryptchecksum的源代码放在了同一个目录下,他想在这个目录中创建libhfsecurity.a存档,然后用它来编译程序,你能帮他补全makefile吗?

注意bank_vault程序用了下面的#include语句:

最后编译其他程序 - 图6

最后编译其他程序 - 图7Make冰箱贴解答

安保人员在使用新版安全库编译银行程序时遇到了问题。他把自己的源代码和encryptchecksum的源代码放在了同一个目录下,他想在这个目录中创建libhfsecurity.a存档,然后用它来编译程序,你将帮助他补全makefile。

注意bank_vault程序用了下面的#include语句:

最后编译其他程序 - 图8

最后编译其他程序 - 图9要点

  • 使用尖括号(<>),编译器就会从标准目录中读取头文件。

  • 常见的标准头文件目录有/usr/includeC:\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安全库保护银行数据的安全吗?

:最好不要这么做。

最后编译其他程序 - 图10链接器有约

本周访谈:

你到底是做什么的?

Head First:链接器,非常感谢你能抽出时间来参加我们的节目。

链接器:我很高兴来到这里。

Head First:你有没有觉得开发人员忽视了你?他们压根不知道你是干嘛的。

链接器:我不太善于交际,很多人不会通过ld命令直接与我对话。

Head Firstld

链接器ld正是鄙人。

Head First:屏幕上显示了很多选项。

链接器:确实如此。我有很多选项,它们代表链接程序的不同方法,这就是为什么一些人只用gcc命令。

Head First:编译器也能链接文件吗?

链接器:编译器会制定链接方案,然后调用我。我会默默地把它们链接起来,你完全不知道我的存在。

Head First:我还有一个问题……

链接器:什么?

Head First:我知道这个问题很愚蠢,但你到底是做什么的?

链接器:我把编译后的代码缝合起来,有点儿像电话接线员做的工作。

Head First:不明白。

链接器:老式电话接线员会把两个地方的电话线路连接起来,这样两边的人才能通话,目标文件也是如此。

Head First:怎么说?

链接器:一个目标文件可能需要调用另一个目标文件中的函数,我会把这个文件中的函数调用与那个文件中的函数链接在一起。

Head First:那你一定很有耐心。

链接器:我喜欢做这种事,没事的时候我会绣十字绣。

Head First:真的啊?

链接器:开玩笑的。

Head First:谢谢你,链接器。