1、makefile的介绍
makefile其实是一个文件,记录了代码如何编译的详细信息、描述了整个工程的编译链接等规则,只需要把makefile文件写好,通过make(是一个命令工具
,是一个解释makefile中指令的命令工具,一般都有,如果没有。可以 sudo apt install make 安装一个)就可以完成自动编译。
之前写操作系统项目MIT 6.S081时就是有这么一个makefie文件,但是当时不会用。(学完系统编程可以继续做一下那个项目)
makefile的语法:
-
target(目标文件):文件1 文件2(依赖文件列表) //依赖关系
-
<Tab>gcc -o 欲建立的执行文件 目标文件1 目标文件2 ///依赖方法
target就是我们创建目标文件的名称,文件1文件2就是我们所需要执行的文件,也就是目标文件所能执行起来的依赖,所以也叫依赖文件。 下面一行就是实现依赖文件。后面讲到也可以。而且,如果有很多依赖文件,难道也需要一个一个写,那当然是有更加简单的表示方法。
2、make/makefile的运用
当我们在写一个test.c的文件时,如果需要运行,只需要 gcc test.c -o test, 但是如果我们把整个运行过程写入makefile里面,那么就只需要make 就行,程序就会自动执行。
mytest就为创建的文件名,test.c为依赖文件名,gcc实现依赖方法,
有些依赖是这样来写的,这样其实也好理解,把每一个依赖都分开来写,以便于之后哪个文件修改了但是不需要所有的文件都跟着执行。
完成一件事,必须得有正确的依赖关系 + 正确的依赖方法
3、make的工作流程
1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello_demo”这个文件,并把这个文件作为最终的目标文件。
3、如果hello_demo文件不存在,或是hello_demo所依赖的后面的 .o
文件的文件修改时间要比hello_demo这个文件新,那么,他就会执行后面所定义的命令来生成hello_demo这个文件。
4、如果hello_demo所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。
5、当然,我们的C文件和H文件都存在,于是make会生成 .o 文件,然后再用 .o
文件生命make的终极任务,也就是执行文件hello_demo了。
4、makefile变量和写法
变量分为:用户自定义变量,自动变量,预定义变量,环境变量。
用户自定义变量:
$@ 当前规则的目标文件
$< 当前规则的第一个依赖文件
$^ 当前规则的所有依赖文件,以逗号分隔
$? 规则中日期新于目标文件的所有相关文件列表,逗号分隔
获取变量值:$(变量名)//这个后面用的比较多。
示例: 用自动变量:TEST_file2文件夹。
# 定义目标文件和可执行文件
OBJS = test.o add.o//(有些时候会看到:=的写法,也是没有错的,=时延迟赋值,就是在用到的时候赋值,:=是立即赋值,定义时立即计算)
EXE = test.exe
$(EXE):$(OBJS)
gcc $^ -o $@
test.o:test.c
gcc -c $<//$<代表第一个依赖文件,也就是test.c的依赖文件
add.o:add.c
gcc -c $<
.PHONY:rebuild clean//伪目标:不实际生成文件哈,只是一个命令集合
(伪目标通过确保特定命令在每次调用时都执行,避免与文件名冲突,并组织常见任务,提高了Makefile的可读性和维护性。常见的伪目标包括clean
、rebuild
、install)
rebuild:clean $(EXE)//重新构建目标:先清理,再构建
clean://清理生成的文件
rm -rf $(EXE) $(OBJS)
##像makefile里面的文件的执行过程是根据依赖文件和文件名的更新时间来判断它是否会执行。这点还是比较重要的,这个可以让你知道自己写的makefile或者看别人的makefile怎么运行的。写好makefile对后期成为一个好的程序员有很大的帮助。