目录
1、为什么我们需要make和makefile
2、makefile文件的基本语法
makefile文件的语法和make指令的用法
定义变量
3、PHONY关键字
.PHONY 的语法
为什么需要.PHONY?
1、为什么我们需要make和makefile
make 和 Makefile 是软件开发中用于自动化构建和管理代码编译流程的工具。
当项目包含多个源文件(如 C/C++ 的 .c 和 .h 文件)时,手动编译每个文件并链接成可执行文件非常繁琐。
makefile 可以定义一套规则,告诉编译器如何自动完成编译、链接、清理等操作。
make是一个命令,执行该命令需要当前操作目录下有一个名为makefile或者Makefile的文件。
我们只需输入make命令,即可一键完成整个构建流程,无需手动输入冗长的编译命令。
对于test.c,没有写好makefil时我们需要在命令行中现写gcc命令编译,使用make就可以在makefile中提前写好需要的命令,编译时使用make一键编译,方便其他人直接编译文件。而不是每次编译都要一行一行敲指令。
写好了makefile之后,我们就可以在这个目录下使用make一键编译了。
输入make clean,就是指定执行clean任务,不会执行编译任务,即执行makefile文件中clean后面的指令。
那么我们在makefile里编写的代码是什么意思呢?
test:test.cgcc -o test test.c
clean:rm -f test
其中test:test.c表示一个依赖关系,由冒号隔开,冒号左边的叫目标文件,右边的叫依赖文件,冒号右边也可以是依赖文件列表,可以由多个源文件编译成可执行文件。
gcc -o test test.c就是依赖方法。
clean又是另外一个任务。
2、makefile文件的基本语法
我们首先要理清楚make和makefile文件的概念、功能及它们之间的关系。
make 是一个命令行工具,用于自动化执行代码编译、链接、测试、清理等任务。
makefile 是一个文本配置文件,定义了构建项目的规则和依赖关系。
make | Makefile |
---|---|
是一个命令行工具 | 是一个配置文件 |
负责解析依赖关系和执行命令 | 负责定义依赖关系和命令规则 |
根据 Makefile 的规则工作 | 是 make 工具的“说明书” |
我们可以大致总结一下:
make 是工具,提供构建的逻辑(如何判断是否需要构建)。Makefile 是规则,提供构建的内容(构建什么、依赖什么、如何构建)。
makefile文件的语法和make指令的用法
目标文件:依赖文件列表
依赖方法
只是输入make指令时,默认只会执行makefile中的第一个任务,任务执行成功后不再执行后续任务,像上面我们写了一个编译任务,一个删除任务,执行完了编译任务后,删除任务不再执行。
当然,我们也可以指定任务执行。
像上面我们讲的make clean就是一个指定任务的执行,clean不需要任何依赖文件。
在makefile中,依赖方法的指令内部的目标文件可以用$@代替,依赖文件列表可用$^代替。
test:test.cgcc -o $@ $^
这里的gcc -o $@ $^ 相当于 gcc -o test test.c
定义变量
dst=test
src=test.c$(dst):$(src)gcc -o $(dst) $(src)
这里我们将test赋予dst,test.c赋予src,这样dst的值就是test,src的值就是test.c,使用$(变量名)就可以代替源文件名。
3、PHONY关键字
当我们连续make的时候,会提示我们文件已经是最新的了,那么系统是如何识别的呢?
当我们再次使用make指令时,如果源代码没有被修改过,make不会帮我们再次编译文件,对于一个没有修改过的文件,再一次编译就是纯纯的浪费资源,所以为了提高编译效率,make不会对一个没有被修改过的文件进行再次编译。
系统是怎么知道代码有没有被修改过呢?
从逻辑上讲可执行文件的时间不可能和源文件的时间相同。因为必须要先有源文件才能够有可执行文件,那么就得到了一个结论:源文件的创建时间一定早于可执行文件的创建时间,修改后源文件的最近一次修改时间一定晚于可执行文件的创建时间。
所以,系统只需要对比源文件最晚的修改时间和可执行文件的时间,就可以知道是否要重新编译。
如果源文件的时间晚于可执行文件的时间。说明源文件被修改过了,因此就需要重新编译。
如果源文件的时间早于可执行文件的时间。说明源文件没有修改,不需要重新编译。
查看时间指令
stat 文件名
Access:最近一次访问文件的时间
Modify:最近一次修改文本的时间
Change:最近一次改变文件属性的时间。
如果我们要强制重复执行make命令,忽略之前的test文件,这时候可以使用PHONY指令。
.PHONY 的语法
.PHONY: 目标1 目标2 ...
例如我们在makefile使用了PHONY
此时每次使用make都会强制执行
在makefile中,.PHONY 是一个特殊的关键字,用于声明一个目标是"伪目标"。伪目标不生成任何实际的文件,而是用于执行一系列命令(例如清理临时文件、运行测试、安装程序等)。它的核心作用是避免目标名称与文件名的冲突,并确保每次调用该目标时,其关联的命令都会被执行。
为什么需要.PHONY?
假如我们定义了一个目标任务clean,用来清理文件
clean:rm -f test
如果没有声明 .PHONY,当目录中恰好存在一个名为clean的文件时,make工具会认为clean已经是最新状态(因为clean文件没有依赖项),从而跳过 rm 命令的执行。这样我们就无法执行清理文件的命令了。
通过声明 .PHONY,就可以明确地告诉make,clean 是一个伪目标,不要将其视为文件,从而确保每次运行make clean时,命令都会执行。