文章目录
- 1. 介绍
- 2. C语言编译
- 2.1 预处理
- 2.2 生成汇编语言
- 2.3 编译目标文件
- 2.4 编译为可执行文件
- 3. .a静态库的编译与链接
- 案例
- 4 .so 动态库的编译与链接
1. 介绍
编译C语言的相关后缀
.a 文件
是一个静态库
文件.c
文件是c语言的源文件.h
c语言的头文件.i
是预处理文件.o
目标文件.s
汇编语言的文件.so
动态库或者共享库或者称为运行时库
.c
文件在github中可以看到另一种后缀,比如.cc
或者是其他的后缀,但是常用的还是.c
后缀。在makefile 学习(1):C/C++ 编译过程, 我们讲到编译过程包括4个步骤
: (1)预处理,(2)转换为汇编语言,(3) 生成目标文件(4) 链接为可执行文件。
2. C语言编译
2.1 预处理
main.c
文件:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello World\n");
return 0;
}
- 执行命令:
# 不会生成.i文件
gcc -E main.c
虽然进行了预处理编译,但是没有输出.i
文件,需要-o
指定下输出
gcc -E main.c -o main.i
可以看到了生成了预处理main.i
,打开可以看到.i
文件对应的是脚本
2.2 生成汇编语言
执行命令:
gcc -S main.c
可以看到生成汇编语言main.s
,内容如下:
熟悉汇编语言的童学对生成的内容应该很熟悉
如果想指定输出的文件名,可以利用-o
选项:
gcc -S main.c -o test.s
2.3 编译目标文件
- 执行命令:
gcc -c main.c # 没有指定输出名,默认为main.o
gcc -c main.c -o xxx.o #生成 xxx.o
编译多个.c文件
gcc -c main.c add.c minus.c # 生成main.o add.o minus.o
2.4 编译为可执行文件
gcc main.c -o exec #exec 可执行文件名
生成了可执行文件exec
, 然后运行可执行文件./exec
就能输出对应结果
3. .a静态库的编译与链接
在实际的项目中,我们会写很多带有功能性源文件
(比如特定的运算,放在不同的.c文件中),供其他脚本调用。如果不希望.c
文件源码被外部看到或者不想拷贝一堆.c
,而是直接输出库文件
,供外部的可执行文件链接,此时就需要编译静态库
或者动态库
。
案例
- 在
add.c
中实现两个数相加,在minus.c
文件中实现两个数相减。 在main.c
中调用add.c
和minus.c
中的函数,进行加减运算 - 实现将
add.c
和minus
生成库文件
add.c
的代码
int add(int a, int b)
{
return a+b;
}
minus.c
的代码
int minus(int a, int b)
{
return a-b;
}
main.c
#include <stdio.h>
int add(int a,int b);
int minus(int a,int b);
int main(int argc, char ** argv[])
{
int a = 10;
int b = 5;
int c;
c = add(a,b);
printf("a+b = %d\n",c);
c = minus(a,b);
printf("a-b = %d\n",c);
return 0;
}
(1)编译目标文件
- 首先编译目标文件
add.o
和minus.o
gcc -c add.c minus.c
(2)编译静态库
生成静态库语法:
ar -r [lib自定义库名.a] [.o] [.o] ...
- 将
add.o
和minus.o
编译为 静态库
ar -r liboperation.a add.o minus.o
可以看到生成了 liboperation.a
静态库文件
(3)连接静态库
- 方法1:
生成静态库后,就可以将静态库连接到源文件main.c
gcc main.c liboperation.a -o exec # 生成可执行文件exec
./exec # 执行可执行文件
- 方法2
把main.c
也编译为目标文件,然后利用gcc 把3个目标文件链接起来 - 生成 main.o
gcc -c main.c
- 3个目标文件链接,生成可执行文件
gcc main.o add.o minus.o -o exec
./exec
4 .so 动态库的编译与链接
动态库的编译与静态库的编译,其实是一样的。
- (1)编译二进制.o文件 (需要加上 -fpic)
语法
gcc -c -fpic [.c/.cpp] [.c/.cpp] ...
编译 add.o
, minus.o
目标文件
gcc -c -fpic add.c minus.c
- (2)编译动态库 (需要加上 -share)
语法
gcc -shared [.o][.o] ... -o [lib自定义库名.so]
生成动态库liboperation.so
gcc -shared add.o minus.o -o liboperation.so
- (3)链接动态库到可执行文件
语法
gcc [.c/.cpp] -o [自定义可执行文件名] -l(库名) -L(库路径) -Wl,-rpath =[库路径]
链接可执行文件
gcc main.c -loperation -o exec -L/home/yuanwushui/project/tensorrt-integrate/1.C/src
编译成功了可执行文件,这里还有一些小细节并没有说,比如-Wl
,-rpath
等,这些都将在后续makefile章节进行讲解