最简单的处理:gcc -o text x.c (完成了对文件的预处理、编译、汇编、链接),但该处理方法每次执行都会对所有文件进行重新编译再链接,会造成编译时间过长,所以仅适用于少量文件。当文件过多时,应该分别编译最后在进行链接。比如:
这样的话,当我们修改了其中部分文件时,只需要对修改的文件进行重新编译,最后再把所有文件进行链接即可,这就省去了对未修改文件的重复处理。
通过比较时间的方法来判断文件是否被修改
makefile规则:
目标文件:依赖文件
命令
将上述编译方法改为makefile
当文件过多时,为了简化代码,我们引入通配符
$@ :目标 $<:第一个依赖文件 $^ : 所有依赖文件
makefile自动化变量
假想目标:当使用make时,若后面没有目标,默认第一个目标(即文件中的第一个目标),如需要执行非第一个目标的命令时需要 make 目标,但如果目标名与文件名重复,那么此时就无法执行目标,所以需要将目标定义为假想目标,此时它便不会判断是否存在与目标名相同的文件并处理
上述编译方法仅编译了.c类型的依赖文件,但实际项目中还会存在.h文件,但并非所有.o文件都具有.h类型依赖文件,所以首先我们需要找到对应依赖文件
可见c.o依赖于c.c 以及系统中一系列头文件 和 c.h文件
将以上信息存放于c.d文件中,在编译时依赖该文件则相当于依赖了所有与其有关的.h文件
该操作既将对应头文件写入了c.d,同时对c.o进行
以下代码仅需修改需要生成的.o文件,即可在linux系统内使用vi编辑器直接修改.h文件
即时变量与延时变量:
第一行为空,第二行为abc
= 的作用:
例如定义变量 name = aaa , curname = $(name) , name = bbb.
当我们执行 @echo curname:$(curname)时 显示的是 bbb ,也就是说 = 的作用是找到整个程序中最后一次对变量的赋值
:= 的作用
例如定义变量 name = aaa , curname := $(name) , name = bbb.
当我们执行 @echo curname:$(curname)时 显示的是 aaa ,也就是说 := 的作用是找到该行代码前的最后一次对变量赋值
?= 的作用
如果 curname 在前面代码中未被赋值,那么将其赋值,否则不赋值(即依旧沿用从前的赋值)
+= 的作用
追加赋值,即在之前赋值的基础上加上当前赋值
makefile函数
a:对list中的每一个变量执行text操作
如下,将a,b ,c文件均转化为.o文件,其中f为变量
b:取出变量中符合pattern格式的值 或取出变量中不符合pattern格式的值
d:将指定文件中的某类型文件全部替换为指定类型文件,如下将.c文件替换为.d文件
添加CFLAGS:
其作用为将所有的警告都当成错误,同时可以指定编译器默认搜索的头文件目录