静态库是指在我们的应用中,有一些公共代码是需要反复使用,就把这些代码编译为“库”文件;在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中的这种库。
静态库
在程序开发工作中,经常会遇到我们的程序需要链接外部库的做法。
比如想要在我们的C工程中调用SQLite数据库的相关接口进行数据库操作,那么我们首先需要做的事情是获取SQLite的源码,然后将SQLite源码编译成静态库libsqlite.a,最终我们在程序中包含SQLite的头文件并调用相关接口,并且在编译的时候链接libsqlite.a静态库。
最终生成的可执行文件就会包含我们自己写的程序和SQLite数据库功能。
静态库可以理解成程序的集合,包含了常用的公共代码部分(glibc)或者实现了专用的功能(SQLite)。这样我们在编写程序时就不需要重复实现相关的功能,直接包含头文件并连接需要的库即可。大大减少了我们编码的工作量。
静态库的制作
本节看一下如何制作一个静态库。
这里我们实现一个公共的加法操作函数tadd(int a, int b);首先实现tadd()函数及其头文件tadd.h:
// tadd.cint tadd(int a, int b){ return ((a) + (b));}
// tadd.h#ifndef __TADD_H__#define __TADD_H__int tadd(int a, int b);#endif
将tadd.c编译为目标文件:
$ gcc -c tadd.c -o tadd.o
这里只是将tadd.c编译为tadd.o,gcc 的 -c 选项指的是对于源文件只编译但是不进行连接。所以tadd.o只是一个编译好的二进制目标文件,并不是链接好的可执行文件。
接下来我们将会使用这个编译好的目标文件,将该文件打包为静态库。
$ ar rcs libtadd.a tadd.o
ar工具可以将目标文件打包成静态库,ar打包之后的文件就可以在程序中进行链接使用。
测试
现在我们写一个测试代码对刚才生产的静态库进行测试:
// prog.c#include #include "tadd.h"int main(){ int a = 122; int b = 8; int c = tadd(a, b); printf("a + b = %d\n", c); return 0;}
编译方法:
$ gcc prog.c -o prog -L./ -ltadd
prog.c是测试的C文件,会在该文件中调用tadd()函数,-L参数表示需要链接的静态库文件的路径,-ltadd参数表示需要链接libtadd.a静态库。
这里我们把libtadd.a和tadd.h两个文件放在和prog.c的同级目录。
执行结果:
$ a + b = 130