您需要了解的有关 C 静态库的所有信息
介绍
在开始讨论主题之前,让我们简单了解一下 C 程序的编译阶段。
基本上分为四个阶段:
- 预处理
- 汇编
- 集会
- 链接
在本文中,我们将重点介绍静态库及其在程序链接阶段的作用。首先,让我们定义一个库。
什么是图书馆?它有什么用处?
库是代码例程(函数、类、变量等等)的集合,可以在构建程序时调用。这样,我们就不用自己编写代码了,而是可以从已经编写并优化好的库中获取。这就是库的概念来源。我们可以复用来自其他地方的代码块。
基本上,我们有两种类型的库:
- 静态库
- 共享(或动态)库
编写库的主要原因是为了允许代码重用,从而节省大量开发时间。
什么是静态库以及它是如何工作的?
静态库是一个包含目标文件(*.o)集合的文件,这些目标文件在编译的链接阶段链接到程序中,但在运行时并不相关。
如上图所示,编译程序时,编译器会从源文件生成目标文件。生成目标文件后,编译器还会调用链接器。在这种情况下,链接器的作用是将库的代码复制到目标文件中。
基本上,静态库只是目标文件的集合,链接器将其与另一个目标文件合并以形成最终的可执行文件。
通常,它们以“lib”开头,以“.a”或“.lib”结尾(取决于您的平台)。
如何创建静态库?
要创建静态库,我们需要向编译器(在本例中为 GCC)指定,将所有库代码 (*.c) 编译为目标文件 (*.o),而无需进行链接。为此,我们将使用以下命令。
$ gcc -c -Wall -Werror -Wextra *.c
标志描述:
-c:编译和汇编,但不链接。
-Wall、-Werro 和 -Wextra:这些不是必需的,但建议使用它们来生成更好的代码。
请注意,“*.c”与当前工作目录中所有以“.c”为扩展名的文件匹配。
例如,我们取两个 c 文件add.c和mul.c,它们分别用于执行两个整数的加法和乘法,以及一个包含这些函数原型的头文件。下图显示了使用该命令后生成的输出。
一旦有了目标文件,我们就可以将所有目标文件打包成一个静态库。
要创建静态库或向现有静态库添加其他目标文件,我们必须使用 GNU ar(归档器)程序。我们可以使用如下命令:
$ ar -rc libname.a *.o
此命令创建一个名为“libname.a”的静态库,并将目标文件“add.o”和“mul.o”的副本放入其中。“c”标志指示 ar 创建该库(如果该库尚不存在)。“r”标志指示它插入目标文件或用新的目标文件替换库中现有的目标文件。
创建或修改档案后,需要对其进行索引。编译器稍后会使用此索引来加速库中的符号查找,并确保库中符号的顺序在编译过程中不会受到影响。创建或更新索引有两种方法。第一种方法是使用 ranlib 命令。
$ ranlib libname.a
或者在 ar 命令中添加一个额外的标志(-s),它就变成这样:
$ ar -rcs libname.a *.o
下图显示了在我们的示例中这些命令的执行情况。
为了列出我们库中目标文件的名称,我们可以使用带有-t标志的 ar 命令。
如何使用它们?
现在我们的静态库“libname.a”已准备好使用。我们可以在程序中使用它了。只需将库的名称添加到提供给链接器的目标文件中即可。首先,让我们创建一个使用上面创建的静态库的 C 源文件。
现在我们可以使用下面的命令来创建最终的可执行程序:
$ gcc main.c -L. -lname -o main
这将使用目标文件“main.o”以及“name”静态库中所需的任何符号创建一个程序。
标志描述:
-L:指定给定库的路径('.' 指的是当前目录)
-l:指定不带“lib”前缀和“.a”后缀的库名称,因为链接器将这些部分附加回库名称以创建要查找的文件的名称。
我们现在要做的就是运行我们的程序。
以上就是我对静态库的总结!
希望对你有帮助。下一篇博文中,我们将讨论动态库以及它们与静态库的区别。
学习愉快!
鏂囩珷鏉ユ簮锛�https://dev.to/iamkhalil42/all-you-need-to-know-about-c-static-libraries-1o0b