本文最后更新于:2 年前
伪目标
.PHONY : clean
PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使用PHONY 目标:避免和同名文件冲突,改善性能。
1 2 3 4 5
| .PHONY : clean clean : -rm edit $(objects)
|
默认语法
$@–目标文件,
$^–所有的依赖文件,
$<–第一个依赖文件。
:= 即时展开右边的变量,= 是在parse所有的makefile之后最后再展开变量值
?= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值,是否即时展开右边的变量,取决于变量是=复制还是:=赋值
静态模式
objects = foo.o bar.o
all: $(objects)
$(objects): %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
上面的例子中,指明了我们的目标从$objects中获取,“%.o”表明要所有以“.o”结尾的目标,也就是“foo.o bar.o”,也就是变量$object集合的模式,而依赖模式“%.c”则取模式“%.o”的“%”,也就是“foo bar”,并为其加下“.c”的后缀,于是,我们的依赖目标就是“foo.c bar.c”。而命令中的“$<”和“$@”则是自动化变量,“$<”表示所有的依赖目标集(也就是“foo.c bar.c”),“$@”表示目标集(也就是“foo.o bar.o”)。
于是,上面的规则展开后等价于下面的规则:
foo.o : foo.c
$(CC) -c $(CFLAGS) foo.c -o foo.o
bar.o : bar.c
$(CC) -c $(CFLAGS) bar.c -o bar.o
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
INC_DIRS := src/ \ src/CC \ src/CM \ src/common \ src/dqu_dfs_common \ src/DRV
SRC_DIRS := src/ \ src/CC \ src/CM \ src/common \ src/dqu_dfs_common \ src/DRV
OUTPUT_DIR := build
TARGET := app_bin
CFLAGS += -Wall -O -g CLIBS += -lpthread -lrt -Lhome/zfr/cross_tool/aarch64-linux-gnu/bin
CC = arm-linux-gnueabihf-gcc CXX = arm-linux-gnueabihf-g++ LD = $(CC)
CUR_DIRS = $(shell pwd) INC_DIRS := $(patsubst %,$(CUR_DIRS)/%,$(INC_DIRS)) SRC_DIRS := $(patsubst %,$(CUR_DIRS)/%,$(SRC_DIRS))
OUTPUT_DIR := $(patsubst %,$(CUR_DIRS)/%,$(OUTPUT_DIR))
VPATH := $(SRC_DIRS)
CFLAGS += $(patsubst %,-I%,$(INC_DIRS))
CFILES := $(foreach dirs,$(SRC_DIRS),$(wildcard $(dirs)/*.c) )
CFILES_NO_DIR := $(notdir $(CFILES))
COBJS := $(patsubst %.c,%.o,$(CFILES_NO_DIR)) COBJS := $(patsubst %,$(OUTPUT_DIR)/%,$(COBJS))
.PHONY: all clean
.IGNORE: clean all: $(OUTPUT_DIR) $(TARGET)
$(TARGET) : $(COBJS) $(CC) -o $@ $^ $(CLIBS)
$(COBJS) : $(OUTPUT_DIR)/%.o:%.c $(CC) -o $@ -c $< $(CFLAGS)
$(OUTPUT_DIR): mkdir -p $(OUTPUT_DIR)
clean: rm $(OUTPUT_DIR)/*.o rm $(TARGET)
|