# 这里的先决条件,要么是存在的文件、要么是一个target
targets: prerequisites
command
command
command
⚠️ command前需要有一个Table
# target-a会被执行
target-a:
command
target-b:
command
# 通过这里定义的all一次性执行三个没有独立的target
all: one two three
one:
touch one
two:
touch two
three:
touch three
clean:
rm -f one two three
all: f1.o f2.o
# 这里的$@代表的是每一个target
f1.o f2.o:
echo $@
# Equivalent to:
# f1.o:
# echo f1.o
# f2.o:
# echo f2.o
<targets> : <normal-prerequisites> | <order-only-prerequisites>
[tab] <commands>
只有第一次构造 targets 时,才会使用 order-only-prerequisites。后面即使 order-only-prerequisites 发生改变,也不会重新构造 targets。只有 normal-prerequisites 中的文件发生改变时,才会重新构造 targets。这里,符号 “|” 后面的 prerequisites 就是 order-only-prerequisites
通过order-only-prerequisites可以帮忙预先创建目录和准备一些前置的文件,但这些条件即使后面发生了变化也不用触发target重新生成。下面这个例子就通过了order-only-prerequisites来创建目录,后面即使目录发生变化(目录内的内容发生变化)也不再导致target重新创建
BUILDDIR:=build
all: $(BUILDDIR)/test.o
clean:
rm -rf $(BUILDDIR)
$(BUILDDIR):
mkdir -p $(@)
$(BUILDDIR)/%.o: %.c | $(BUILDDIR)
gcc -o $@ -c $<
=的定义变量,不会在定义的时候展开,而是在使用的使用展开,而:=则是定义的时候展开、?=只有变量没有定义的时候才会设置。
files := file1 file2
some_file: $(files)
echo "Look at this variable: " $(files)
touch some_file
# Recursive variable. This will print "later" below
# 在执行的时候才会展开later_variable
one = one ${later_variable}
# Simply expanded variable. This will not print "later" below
# later_variable这里还没有定义,因此是空
two := two ${later_variable}
later_variable = later
all:
echo $(one)
echo $(two)