一篇带你深入了解程序的翻译过程(gcc指令的使用),快速编写makefile
不努力,未来永远只是个梦
目录
- 一、gcc指令
- 二、makefile编写(初级)
一、gcc指令
在介绍之前我们有一个test.c文件,文件内容如下
#include
int main()
{#define PRINT#ifdef PRINTprintf("PRINT\n");#elseprintf("NO PRINT\n");#endifprintf("hello world\n");//这是一条注释//这是一条注释//这是一条注释printf("hello world\n");
}
在阅读如下内容之前,我们需要有一个概念,gcc是编译器,而vim是文本编辑器
程序的翻译过程分为四个阶段
1.预处理(头文件展开,预处理,去掉注释,条件编译)
使用-E(必须大写!):从现在开始进行程序的翻译,直到预处理结束
gcc -E test.c -o test.i
这里的-o选项是为了生成我们想要制定的名字,
后缀为i是因为预处理生成的文件是以i为后缀(当然不是必须的,这里是规范写法!)
test.i文件内容如下图所示

2.编译(C->汇编)
使用-S(必须大写):从现在开始进行程序的翻译,直到编译做完
下面两条指令都可以使用,第二条基本都可以理解,那么为什么第一条指令也可以呢?原因在于,预处理的下一步不就是编译吗?所以我们可以从上一步直接到下一步,不需要重头开始
gcc -S test.i -o test.s
gcc -S test.c -o test.s
这里编译文件的后缀习惯性为s!
文件内容如图所示

3.汇编(汇编->可重定位目标二进制文件,不可以被执行)
-c(必须小写!):从现在开始进行程序的翻译,直到汇编结束
依旧是两种写法
gcc -c test.c -o test.o
gcc -c test.i -o test.o
文件内容如图所示
这里是乱码,查看不了二进制文件,不过实际就是二进制!
4.链接(将我们自己形成的.obj文件和库文件进行合并,形成可执行程序)
在讲链接这一步之前,我们先看一个指令
gcc test.c -o test

其实一开始我们就可以利用gcc指令去形成可执行程序test(图片上字为绿色的),然后在利用./test去运行这个程序
这时我们不妨验证一个结论,汇编形成的二进制文件可不可以执行?如果可以执行的话,那么我们是不是输入./test.o就可以执行了?

那么我们提升他的权限以后可以运行吗?结果如下:

依旧不行,所以这一步更加验证了之前的结论!二进制文件无法执行
所以我们需要用gcc命令去让他和库文件合并
gcc test.o -o test
这时我们就可以执行了:

二、makefile编写(初级)
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率
make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建
具体操作如下:
1.touch Makefile / vim Makefile
2.打如下指令
test:test.ogcc test.o -o testtest.o:test.sgcc -c test.s -o test.otest.s:test.igcc -S test.i -o test.stest.i:test.cgcc -E test.c -o test.i.PHONY:cleanclean:rm -f test.i test.s test.o test
在读懂这段代码之前,我们需要了解一个概念,依赖方法和依赖关系

所以依赖关系为
上面的文件 test ,它依赖 test.o
test.o , 它依赖 test.s
test.s , 它依赖 test.i
test.i , 它依赖 test.c
依赖方法就是每一条gcc指令
写完makefile以后执行就会高效很多了,执行如下图

这里如果一开始写的是clean的话make执行的就是clean,make会执行makefile的第一条指令,而make test才会执行第二条语句,请读者下来自己去尝试别的写法。
makefile的语句可以简化成如下:
test:test.cgcc test.c -o test
.PHONY:clean
clean:rm -f test.i test.s test.o test
至于为什么,前文已经赘述,这里不再赘述
这个.PHONY是总是执行的,如果我们多次执行make指令,会有如下发现
make clean则会一直执行,不管有没有这个文件

看了这两张图以后.PHONY指令的意思就能理解了吧?
那么make指令是根据什么判断最新的呢?答案是根据修改时间判断
同时我们也可以快速编写这个指令
gcc -o $@ $^
$@表示目标文件 $^表示依赖列表
本篇文章的知识点就介绍到这里
总结:本篇文章我们学习了gcc -E /-S/-c等指令,了解了程序的翻译过程,并且简单介绍了makefile如何编写,make和makefile合起来就构成了自动化工具
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
