1、赋值=,:=,?=,+=
1)=
- 使用”=”进行赋值,变量的值是整个makefile中最后被指定的值。
- 即当变量A被重复赋值时,A = 最后一次的值=new;
A = test
A = new - 同上,若Makefile中存在使用变量B引用变量A的场合,无论该行代码在哪里,B始终=new
B = $(A)
A = g++
B = $(A)
A = CC
all:
@echo $(A)
@echo $(B)
- 输出
CC
CC
2):=
- 使用”:=”进行赋值,变量的值是当前位置的值。
A = test
A = new - 同上,若Makefile中存在使用变量B引用变量A的场合,根据代码位置,B=test或者new
B = $(A)
A = g++
B := $(A)
A = CC
all:
@echo $(A)
@echo $(B)
- 输出
CC
g++
3)?=
- 使用”?=”进行赋值,如果该变量没有被赋值,则赋予等号后的值。对于等号后面的值,遵循=的规则。
B = gcc
A = g++
B ?= $(A)
A = CC
all:
@echo $(A)
@echo $(B)
- 输出
CC
gcc
4)+=
- 使用”+=”进行赋值,将等号后的值追加到变量后。
B = gcc
A = g++
B += $(A)
A = CC
all:
@echo $(A)
@echo $(B)
- 输出
CC
g++ CC
2、内建变量$@,$^,$<
符号 | 含义 |
---|---|
$@ | 目标文件 |
$^ | 所有的依赖文件 |
$< | 列表中的第一个依赖文件 |
DIRS = test test.c test.cpp
all: $(DIRS)
@echo '$$@' = $@
@echo '$$^' = $^
@echo '$$<' = $<
- 执行:gmake
- 输出:
$@ = all
$^ = test test.c test.cpp
$< = test
3、内建变量MAKECMDGOALS
MAKECMDGOALS记录用户执行make命令指定的参数列表。
但是不包含指定的形式KEY=VALUE的外部变量
all:
@echo $(MAKECMDGOALS)
@echo $(B)
- 执行:gmake mode=32 all
- 输出:all
4、使用Shell命令
- Makefile中,只能在target中调用Shell命令;在其它位置调用是无效的;
- Makefile中,每一行Shell语句,都是通过线程来执行的。
- Makefile中,Shell语句会先输出到屏幕上,再输出执行结果。使用
@
符号,可以关闭回显。 - 若需要在同一个线程中执行Shell命令,必须使用
\
,使Makefile可以在一个进程中执行多行Shell命令。 - 示例
DIRS = test1 test2 test3
all:
@echo "##### build start #####"
@for i in $(DIRS); \
do \
(cd $$i && $(MAKE)); \
done
@echo "##### build end #####"
5、使用-号忽略错误消息
Makefile中,通常使用rm命令执行clean目标。 当rm对象不存在时,通常会输出错误消息。
因此我们可以使用-
号,屏蔽一些不重要的错误。
OBJ := $(SRC:.c=.o) $(SRCXX:.cpp=.o)
clean:
-$(RM) -rf $(OBJ) $(TARGET)
6、伪目标.PHONY
Makefile中,对任意指定的目标,会在当前目录检查目标文件是否需要更新。
当目录中已存在最新的clean文件时,期待的rm操作就无法正确执行。
针对这种情况,Makefile引入了.PHONY规则。
当一个目标被声明为.PHONY时,无论是否存在目标文件,总是执行目标。
OBJ := $(SRC:.c=.o) $(SRCXX:.cpp=.o)
.PHONY: clean
clean:
-$(RM) -rf $(OBJ) $(TARGET)