前言

静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。 ——“百度百科”

库一共分为两种,一为静态库,二为动态库。在实际运用中各有各的优势。

静态库: 当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被 copy 到最终的可执行文件中。 这意味着单个可执行程序的体积会更加庞大,而且在制作过程中要对整个项目进行完整的编译,其优点是运行速度较快且可移植性较好。

动态库: 与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中。 通俗的理解,把一个程序中的多个函数拆分到单个文件中,在主函数中只需要记录需要的函数的引用表,所以单个体积相对较小,但是文件较多,并且在链接动态库时效率会比静态库更加低下。其优点是占用空间较小且便于更新。

——————————————华丽的分割线——————————————

今天先水一篇关于Linux下静态库的制作与使用。

首先先在同一目录下准备三个文件

add.c:存放函数的具体内容和执行过程

1
2
3
4
#include <stdio.h>
int add(int a,int b){
return a+b;
}

add.h:存放需要调用的函数的名词与头

1
int add(int a,int b);

main.c:存放主过程

1
2
3
4
5
6
7
8
9
10
#include "add.h"
#include <stdio.h>

int main(void)
{
int a,b;
scanf("%d %d",&a,&b);
printf("%d\n",add(a,b));
return 0;
}

PS:注意在主函数里运用的add.h是加双引号,且内部为相对路径。

下来正式开始编译静态库。

gcc -c add.c会把add.c编译为add.o

ar -rcs libadd.a add.o将add.o正式封装在libadd.a的静态库中。

PS:静态库名称头部一定以lib开头,结尾扩展名一定为*.a。

至此一个静态库已经编译完成。此时是不是就可以直接编译main.c呢?

这时编译他会提醒你没有add函数的定义,虽然你已经引用了add.h的头文件,但是静态库仍未参与编译过程中。此时的编译命令应该如下:

介绍一下这个编译的参数: gcc main.c -o main.out -L ./ -ladd

1.main.c标明编译源程序 -o为编译项 main.out为编译输出文件,常规参数无需介绍。

2.-L ./ -L(L一定大写)标明后方所跟着的参数是静态库所在的文件夹,./表示当前文件夹

3.-ladd 此命令可以看做两部分 -l表示引用静态库,add为静态库的名称。还记得之前编译的静态库的名称吗——libadd.a。没错Linux里编译调用静态库应去掉开头的lib,去掉结尾的.a就是这个静态库的名称啦。

此时在运行编译出来的可执行程序就正确啦.

总结:静态库可以让一个函数在不同的程序里调用,大大方便了一些大型项目的开发。

在下一篇文章中计划介绍编译自动化工具——makefile