linux下静态库动态库的编译和使用
静态库
1.静态库的编译
有时候我们需要把文件编译成库让我们使用,比如我们用的libc库,库要怎么制作呢,我们一起来看一下
测试目录结构如下
在main.c中调用a.c 和b.c 中的函数,main.c内容如下:
#include <stdio.h>
#include "a.h"
#include "b.h"
int main()
{
printf("Hello world\n");
a();
b();
return 0;
}
所以我们需要把a.c和b.c 编成静态库,让main调用即可
$ gcc -c a.c b.c
把中间文件 a.o、b.o 打包成静态库 libab.a
$ ar rs libab.a a.o b.o
库文件名都是以lib开头的,静态库以.a作为后缀,表示Archive。ar命令类似于tar命令,起一个打包的作用,但是把目标文件打包成静态库只能用ar命令而不能用tar命令。选项r表示将后面的文件列表添加到文件包,如果文件包不存在就创建它,如果文件包中已有同名文件就替换成新的。s是专用于生成静态库的,表示为静态库创建索引,这个索引被链接器使用。ranlib命令也可以为静态库创建索引,以上命令等价于:
$ ar r libstack.a stack.o push.o pop.o is_empty.o
$ ranlib libstack.a
然后我们把main.c和libab.a编译链接在一起
gcc main.c -L. -lab -I . -o main
-L选项告诉编译器去哪里找需要的库文件,-L.表示在当前目录找。-lab告诉编译器要链 接libab库,-I选项告诉编译器去哪里找头文件。注意,即使库文件就在当前目录,编译器默认 也不会去找的,所以-L.选项不能少。编译器默认会找的目录可以用-print-search-dirs选项查看。编译器会在这些搜索路径以及-L选项指定的路径中查找用-l选项指定的库,比如-lab,编译器会首先找有没有共享库libab.so,如果有就链接它,如果没有就找有没有静态库libab
.a,如果有就链接它。所以编译器是优先考虑共享库的,如果希望编译器只链接静态库,可以指定-static选项
注意 :
如果我们把main.c 编成了.o文件再去链接ab静态库的话,链接的时候要注意顺序,要把.o写在前面,如下:
$ gcc -c main.c
$ gcc main.o -L. -lab -I . -o main
如果写在后面了会链接不到:
$ gcc -L. -lab -I . main.o -o main
------------------------------------------------------
main.c:(.text+0x16):对‘a’未定义的引用
main.c:(.text+0x20):对‘b’未定义的引用
collect2: error: ld returned 1 exit status
2. 动态库
组成共享库的目标文件和一般的目标文件有所不同,在编译时要加-fPIC选项,例如:
$ gcc -fPIC -c a.c b.c
f后面跟一些编译选项,PIC是其中一种,表示生成位置无关代码(Position Independent Code)
生成动态库
$ gcc -shared -o libab.so a.o b.o
使用动态库
我们首先要把库文件放在/usr/lib目录下,程序运行的时候会自动去这个目录下找相关的库
cp sudo cp libab.so /usr/lib
main.c链接库文件生成main
$ gcc main.c -L. -lab -I. -o main
更多精彩内容欢迎关注小熊嵌入式