文章目录
一、Makefile基本语法
1.1 语法规范
目标文件1:依赖文件1
(Tab键)根据依赖文件1生成目标文件1的命令
目标文件2:依赖文件2
@echo "使用依赖文件2生成目标2,@表示不显示命令本身的执行过程"
- 表示忽略执行过程中的错误
1.2 伪目标
# 保证每一次执行make clean都是有效的
.PHONY:clean
clean:
rm *.o *.elf
1.3 预定义变量
CC := 编译器名称,默认为gcc
CFLAGS := 编译选项
RM := 删除文件的命令,默认为rm -f
1.4 自定义变量
OBJ := test1.o test2.o
1.5 变量赋值
1.5.1 递归的方式赋值变量(VAR=var)
# 使用该方式定义变量,变量后面改变会影响前面的值的改变
a = var1
b = $(a).c
a = var2
echo:
@echo $(a) $(b)
# 此时会输出 var2 var2.c
1.5.2 立即赋值的方式赋值变量(VAR:=var)
# 使用该方式定义变量,变量后面改变不会影响前面的值的改变
a := var1
b := $(a).c
a := var2
echo:
@echo $(a) $(b)
# 此时会输出 var2 var1.c
1.5.3 追加的方式赋值变量(VAR+=var)
a := var1
a += var2
echo:
@echo $(a)
# 此时会输出 var1 var2
1.5.4 有选择的方式赋值变量(VAR?=var)
# 如果变量在前面没有被赋值,就给它赋值成var
# 如果变量在前面已经赋值了,就使用前面的值
# a := var1
a ?= var2
echo:
@echo $(a)
# 会根据是否注释前面a的赋值,确定输出的内容
二、Makefile高级语法
2.1 自动变量与通配符
# 自动变量
$@ 表示目标文件
$< 表示第一个依赖文件
$^ 表示所有的依赖文件(去重)
$+ 表示所有的依赖文件(包括重复文件)
$* 表示目标文件去除后缀
# 通配符
%.o 表示所有的以.o结尾的文件
%.c 表示所有的以.c结尾的文件
2.2 Makefile嵌套使用
# 即在根Makefile的子目录下还可以使用子Makefile
OBJ := test1.o test2.o
CC := gcc
export OBJ CC
# 即在子Makefile中也可以使用 OBJ CC
2.3 Makefile条件指令
ifeq ('arg1', 'arg2')
ifeq 'arg1' 'arg2'
ifeq "arg1" "arg2"
ifeq "arg1" 'arg2'
ifeq 'arg1' "arg2"
# 同理
ifneq ('arg1', 'arg2')
ifdef ('arg1', 'arg2')
ifndef ('arg1', 'arg2')
else
endif
# 举例
ifeq ($(CC), gcc)
$(CC) -o foo $(OBJS) $(gcc_libs)
else
$(CC) -o foo $(OBJS) $(normal_libs)
三、Makefile函数
# 函数使用语法
$(FUNCTION_NAME args)
3.1 wildcard函数
# 函数功能:展开指定目录下的文件
SRC = $(wildcard ./test/*.c ./src/*.c)
# 说明:
# 变量SRC表示test和src目录下的所有c文件
3.2 notdir函数
# 函数功能:去掉路径
SRC_FILES = $(notdir $(SRC))
# 说明:
# 变量SRC_FILES表示SRC去掉路径后的文件名
3.3 dir函数
# 函数功能:获取目录
SRC_DIR = $(dir $(SRC))
# 说明:
# 变量SRC_DIR表示SRC中的目录
3.4 patsubst函数
# 函数功能:替换文件后缀
$(patsubst %.c, %.o, $(SRC))
# 说明:
# 将变量SRC中的*.c文件名替换成*.o
3.5 foreach函数
# 函数功能:遍历字符串,并处理每个字符串
$(foreach item, $(INCLUDE), -I$(item))
# 说明:
# 将变量INCLUDE的所有项都添加一个-I前缀
3.6 strip函数
# 函数功能:去空格函数
$(strip str)
# 说明:
# 去掉 str字串中开头和结尾的空字符
四、实例
CC := gcc
CFLAGS := -g -Wall
LDFLAGS :=
LIBS_DIR :=
OUT_DIR := out
SRC_DIR := test
INC := ./inc
SRC := $(foreach item, $(SRC_DIR), $(wildcard $(item)/*.c))
EXP_SRC := $(wildcard $(EXP_DIR)/*.c)
OBJS := $(patsubst %.c, %.o, $(SRC))
OBJS += $(patsubst %.S, %.o, $(SRC))
CFLAGS += $(foreach item, $(INC), -I$(item))
LDFLAGS += $(foreach item, $(LIBS), -L$(item))
all: $(OBJS)
@echo "compile test files..."
%.o: %.c
@echo "compile file $^...$(notdir $^)"
@mkdir -p $(OUT_DIR)
$(CC) $^ $(CFLAGS) -o $(OUT_DIR)/$(notdir $@)
%.o: %.S
@echo "compile file $^..."
@mkdir -p $(OUT_DIR)/$(dir $^)
$(CC) -c $^ $(CFLAGS) -o $(OUT_DIR)/$@
.PHONY:clean
clean:
rm -rf $(OUT_DIR)