一、基本规则
目标:依赖
(tab)命令
若想生成目标, 检查规则中的所有的依赖文件是否都存在:
如果有的依赖文件不存在, 则向下搜索规则, 看是否有生成该依赖文件的规则:
如果有规则用来生成该依赖文件, 则执行规则中的命令生成依赖文件;
如果没有规则用来生成该依赖文件, 则报错.
如果所有依赖都存在, 检查规则中的目标是否需要更新, 必须先检查它的所有依赖,
依赖中有任何一个被更新, 则目标必须更新.(检查的规则是哪个时间大哪个最新)
二、变量
makefile有三种类型变量:普通变量,自带变量,自动变量
普通变量:
定义直接用=,使用时$(变量名).如
src =
g++ $(src)
自带变量:
除了使用用户自定义变量, makefile中也提供了一些变量(变量名大写)供用户直接使用, 我们可以直接对其进行赋值:
CC/CXX = gcc/g++ 编译器
CPPFLAGS: 预处理的选项 如-I
CFLAGS/CXXFLAGS: c/c++编译和汇编选项 如-Wall -g -c
LDFLAGS: 链接的选项 如-L -l
自动变量:
$@ 表示规则中的目标
$^ 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项
$< 表示规则中的第一个条件
$? 第一变化的依赖
注意:自动变量只能在规则的命令中使用.
三、模式规则
匹配符%:
在规则的目标定义中包含%
, %
表示一个或多个字符, 在依赖条件中同样可以使用 %
, 依赖条件中的 %
的取值取决于其目标:
比如,如果要生成的目标有和:
%.o: %.cpp
等价于
:
g++ -c -o:
g++ -c -o
四、函数
wildcard函数
wildcard – 查找指定目录下的指定类型的文件
src=$(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
patsubst函数
patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
例子:
src=$(wildcard *.c) 等价于src=
obj=$(patsubst %.c,%.o, $(src))等价于obj=
五、make clean清理
用于清理.o文件和可执行文件,例:
clean:
(tab)rm -f $(obj) test
但如果当前目录下有同名的clean文件,则不执行clean的命令,解决方法为:
1)伪目标声明
.PHONY:clean
声明为伪目标后,makefile将不会检查该目标是否存在或者该目标是否需要更新
2)-rm
在rm前加-表示也许某些文件出现问题,但不要管,继续做后面的事
六:makefile综合案例
src=$(wildcard ./*.c) # 等价于src= ,其中wildcard为查找指定目录下的指定类型的文件
object=$(patsubst %.c,%.o,$(src)) # 等价于obj= ,其中patsubst为匹配替换
target=main
CC=gcc
CPPFLAGS=-I./all:$(target)
$(target):$(object)
$(CC) -o $@ $^%.o:%.c
$(CC) -o $@ -c $< $(CPPFLAGS).PHONY:clean
clean:
-rm -f $(target) $(object)
执行make
时,会按照以下顺序进行检查依赖关系和生成目标文件:
- 首先,
make
会执行wildcard
函数,将当前目录下所有的.c
文件赋值给变量src
,即src=
。 - 接下来,
make
会执行patsubst
函数,将src
中的.c
文件替换为.o
文件,并赋值给变量object
,即object=
。 - 然后,
make
会检查all
规则,发现依赖关系是$(target)
,即main
。 -
make
继续检查$(target)
的依赖关系,发现依赖关系是$(object)
,即 -
make
继续检查的依赖关系,发现依赖关系是
。
-
make
执行命令$(CC) -o -c $(CPPFLAGS)
,生成目标文件。
-
make
继续检查的依赖关系,发现依赖关系是
。
-
make
执行命令$(CC) -o -c $(CPPFLAGS)
,生成目标文件。
- 所有的依赖关系都已经满足,
make
执行命令$(CC) -o main
,生成main
可执行文件。