Linux中的动态库和静态库(.a/.la/.so/.o)
- Linux中的动态库和静态库(.a/.la/.so/.o)
- C/C++程序编译的过程
- .o文件(目标文件)
- 创建atoi.o
- 使用atoi.o
- .a文件(静态库文件)
- 创建atoi.a
- 使用atoi.a
- .so文件(共享库文件)
- 创建atoi.so
- 使用atoi.so
- .la文件(libtool archive)
- libtool的使用
- 1. 创建 Libtool 对象文件
- 2. 创建 Libtool 库
- 3. 安装 Libtool 库
- 4. 使用 Libtool 库
- 5. 卸载 Libtool 库
- libtool的使用
在windows下,一般可以通过文件的后缀名来识别文件的类型。在Linux下大致上也是可以的。但是要明确的一点是,在linux下,文件的后缀与文件的类型是没有必然的联系的。这只是约定俗称的习惯罢了。
在linux 下进行C/C++开发,一般都是使用的gcc
编译器,所以本文的讲解以gcc
为主。
.o
文件,即目标文件。一般通过.c
或者.cpp
文件编译而来,相当于VC
编译出来的obj
文件.so
文件,shared object 共享库(对象),相当于windows下的dll。.a
文件,archive 归档包,即静态库。其实质是多个.o
文件打包的结果,相当于VC
下的.lib
文件.la
文件,libtool archive 文件,是libtool自动生成的共享库文件。
下面对这四种文件进行逐个说明。
C/C++程序编译的过程
先说一下C/C++编译的几个过程。
- 预处理,展开头文件,宏定义,条件编译处理等。通过
gcc -E source.c -o source.i
或者cpp source.c
生成。 - 编译。这里是一个狭义的编译意义,指的是将预处理后的文件翻译成汇编代码的过程。通过
gcc -S source.i
生成。默认生成source.s
文件。 - 汇编。汇编即将上一步生成的汇编代码翻译成对应的二进制机器码的过程。通过
gcc -c source.s
来生成source.o
文件。 - 链接。链接是将生成目标文件和其引用的各种符号等生成一个完整的可执行程序的过程。链接的时候会进行虚拟内存的重定向操作。
上面四个步骤就是C/C++程序编译的几个基本步骤。前面三个步骤都是很简单,大多时候会合并为一个步骤。只有第四个步骤链接
是复杂一点的。很多时候我们编译比较大的项目,报错的往往是在链接的时候缺少某些库,或者某些符号找不到定义,重定义等。
.o
文件(目标文件)
.o
文件就是C/C++源码编译的结果。即上面所说的C/C++编译过程中的前三步。一般开发中很少将这三步分开来做,通常的做法是一步生成。
这里举个例子,我们来写一个函数int atoi(const char* str)
。
头文件atoi.h
.#ifndef ATOI_H
.#define ATOI_H
int atoi(const char* str);
.#endif //! ATOI_H
源文件atoi.c
.#include <stdio.h>
.#include "atoi.h"
int atoi(const char* str)
{
int ret = 0;
if(str != NULL){
sscanf(str,"%d",&ret);
}
return ret;
}
创建atoi.o
直接使用命令gcc -c atoi.c -o atoi.o
或gcc -c atoi.c
来生成目标文件。
上面我们函数中调用了sscanf
这个C标准库中的函数,那么它在.o
文件中会记录这个存在,我们可以使用readelf
工具来查看一下。
o@Neo-kylin:~/lib_a_so$ ls
atoi.c atoi.h
o@Neo-kylin:~/lib_a_so$ gcc -c atoi.c
o@Neo-kylin:~/lib_a_so$ ll
总用量 20
drwxr-xr-x 2 o o 4096 10月 10 15:11 ./
drwxrwxr-x 5 1000 1000 4096 10月 10 14:32 ../
-rw-rw-r-- 1 o o 140 10月 10 15:07 atoi.c
-rw-rw-r-- 1 o o 75 10月 10 15:07 atoi.h
-rw-rw-r-- 1 o o 1536 10月 10 15:11 atoi.o
o@Neo-kylin:~/lib_a_so$ readelf -s atoi.o
Symbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS atoi.c
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1
3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
4: 0000000000000000 0 SECTION LOCAL DEFAULT 4
5: 0000000000000000 0 SECTION LOCAL DEFAULT 5
6: 0000000000000000 0 SECTION LOCAL DEFAULT 7
7: 0000000000000000 0 SECTION LOCAL DEFAULT 8
8: 0000000000000000 0 SECTION LOCAL DEFAULT 6
9: 0000000000000000 60 FUNC GLOBAL DEFAULT 1 atoi
10: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __isoc99_sscanf
这就是.o
文件了。它保存了编译的时候引用到的符号(函数,全局变量等),这些符号,在链接的时候需要使用到。
使用atoi.o
使用atoi.o
的地方有很多,就不一一列举了。这里先不说怎么用,后面生成.a
文件的时候用到了。
.a
文件(静态库文件)
静态库是多个.o
文件的打包的结果,前面已经说过了,其实不一定非要多个文件,一个.o
文件也可以打包为.a
文件。
这一步使用ar
工具来操作。ar
工具是用来创建, 修改和提取archives归档文件