走进Linux世界:make和makefile
嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的
passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let’s go!
我的博客:yuanManGan
我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记 闲言碎语小记坊 进阶数据结构 走进Linux的世界 题山采玉 领略算法真谛
自动化构建工具make,makefile
文章目录
- 自动化构建工具make,makefile
- (一) 如何形成可执行程序?
- 1. 预处理
- 2. 编译
- 3. 汇编
- 4. 链接
- (二) make和makefile
- 1. 见一见make/makefile
- 2. 谈make命令和makefile ---- 依赖关系和依赖方法
- 3. 详细学习makefile的基本用法
- 4. 语法细节梳理
(一) 如何形成可执行程序?
当我们写了一个普通的打印 hello world 的 test.c 程序的时候,我们如果在vs2022下简单的按一下F5就可以在屏幕上打印hello world,因为vs2022是集成环境,他帮你进行了很多事情。
废话少说,要形成一个可执行程序需要进行一下操作:
1. 预处理
2. 编译
3. 汇编
4. 链接
如果想在Linux下直接生成可执行程序可以使用以下代码:
gcc -o obj src
接下来就慢慢讲一下过程:
1. 预处理
我们预处理阶段,编译器会进行以下操作
- 头文件展开
- 宏替换
- 条件编译
- 去注释
如果我们只想对文件进行预处理操作,可以采取以下代码:
gcc -E obj -o src
比如我想预处理 test.c 文件,可以
gcc -E test.c -o test.i
test.c:
经过预处理之后:
test.i:
前面800多行是对stdio头文件的展开
2. 编译
将c语言转化为汇编语言
同样的代码:
gcc -S test.i -o test.s
test.s
3. 汇编
将汇编语言翻译为二进制文件(.o可重定位目标二进制文件)
gcc -c test.s -o test.
注意test.o文件不能直接被运行缺少链接过程
test.o
4. 链接
将多个目标文件(.o/.obj)和所需的库文件(包括系统库、第三方库)合并为一个可执行程序,同时解决目标文件之间的符号引用(如函数调用、变量引用)。
gcc test.o -o test.exe
test.exe
(二) make和makefile
如果有单个的程序我们大可使用gcc来形成可执行程序,那100个1000个呢?我们难道还得一个一个打吗?
这时就可以借助自动化构建工具了,我们这里讲解make
怎么使用。
我们的 make 本质上是一条命令,而 makefile 是一个文件。
1. 见一见make/makefile
我们先创建一个名为 makefile 的文件
注意文件名只能是 makefile 和 Makefile
然后退出来
make
2. 谈make命令和makefile ---- 依赖关系和依赖方法
依赖关系就好比月底的你和你的父亲,你们存在依赖关系,你月底了想找你爹要钱,你就是目标文件,你的父亲就是依赖文件列表,你向父亲要钱就是依赖的方法。
3. 详细学习makefile的基本用法
我们可以把关系搞复杂一定,我们进行预处理,编译,汇编,链接这几个过程,这个时候makefile文件就成了:
这里产生了一堆 hello.i/s/o/exe 的文件,我们如何清除这些呢?
这个.PHONY:
先忽略,clean:
后面怎么没有依赖文件,我们可以没有依赖文件,但必须有目标文件和方法,比如你自己不依赖任何人都能吃饭。
clean
的方法就是一条shell命令
我们make+目标名
就可以使用它的方法,我们如果默认make
就是第一个依赖方法。
.PHONY: 目标文件
表示该目标为伪目标,本质是该方法总是被执行。
我们make
之后为什么不能再make
呢?
比如我们有100个文件你只修改了一个文件,你难道为了这一个文件,又要再重新编译其他999个文件吗。所以普通文件有一个Modify
,可以使用stat
来查询
那这几个时间都和什么有关呢?
Modify:
文件的内容
Change:
文件的属性
Access:
查看文件
我们发现我们往文件里面写入了东西,不仅Modify
时间变了,Change
时间也变了,这是为什么呢?
我们的文件属性还包括文件的大小和时间,你往文件里写入东西,不仅改变了文件的大小,还改变了
文件的Modify
时间,所以Modify
时间的改变往往会伴随着Change
时间的改变。
那另一个时间呢?
当我们cat
文件时它可能
会变化,那为什么是可能呢?
你想我们对文件进行的操作最多的是什么呢?那当然是查看了,但我们查看操作更改的时间会刷新到硬盘中,我们频繁的刷新硬盘会导致OS整体的效率低下,所以当刷新一定次数,或者一段时间之后才会更新Access
时间。
所以当Modify
时间发生修改后才能重新make
,clean
操作将他变成伪目标后可以防止当外部有一个clean
文件时,它会总是执行Makefile
里面的clean
4. 语法细节梳理
我们可以这将目标文件和依赖文件这样替换,是不是很像c语言中的宏替换。
$@
表示目标文件也就是BIN
$^
表示依赖文件列表也就是SRC
如果你不想把你的命令显示到屏幕上可以在命令前加一个@
在我们工程中我们实际上会遇到很多.c文件
@<
表示第一个依赖文件