格式
目标 ... : 依赖 ...
命令1
命令2
. . .
期中的所有命令都会打印到终端,对于不想打印的命令,可以使用@去除回显
@$(RM) $(OBJS_DIR)/*.o
变量
$(变量名)
定义变量:OBJECT = main.o file1.o file2.o
使用变量:$(OBJECT)
一些特殊变量:
$^ 表示所有的依赖文件
$@ 表示生成的目标文件
$< 代表第一个依赖文件
赋值
- 使用
=
DIR_A = A
DIR_B = $(DIR_A) B
DIR_A = AA
这里DIR_B最后将会变成AAB
- 使用
:=
DIR_A := A
DIR_B := $(DIR_A) B
DIR_A := AA
这里DIR_B最后将会变成AB
- 使用
?=
如果该变量没有被赋值,则等于新的值
DIR := old_value
DIR ?= new_value
这里的DIR
还是old_value
函数
- wildcard函数,匹配指定的文件
SRC = $(wildcard DIR/*.c)
取出DIR
里的.c文件
- patsubst函数,文件名的匹配和替换
OBJ = $(patsubst %.c, %.o, $(SRC))
意思是将SRC
中所有的.c 替换为.o 最后赋值给OBJ变量
- foreach dir函数,可以对目录里的子目录进行操作
$(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
对$(SRCDIRS)
目录下的所有子目录,执行$(wildcard $(dir)/*.S))
命令。
- notdir函数,移除文件路径中的目录部分,只保留文件名部分
SRCS := src/file1.c src/file2.c src/file3.c
OBJS := $(notdir $(SRCS:.c=.o))
伪目标
.PHONY: clean
当目录下有与make 命令 同名的文件时 执行make 命令就会出现错误。
解决办法就是使用伪目标
文件路径
- 指定头文件的路径
-I
CFLAGS = -I/home/develop/include
- 指定要链接的文件路径
-L
LDFLAGS = -L/usr/lib -L/path/to/your/lib
- 指定要链接的文件名
-l
LIBS = -lpthread -liconv
实例
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= bsp
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
INCDIRS := imx6ul \
bsp/clk \
bsp/led \
bsp/delay
SRCDIRS := project \
bsp/clk \
bsp/led \
bsp/delay
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
print:
@echo INCLUDE = $(INCLUDE)
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
SFILENDIR := $(notdir $(SFILES))
CFILENDIR := $(notdir $(CFILES))
SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS := $(SOBJS) $(COBJS)
VPATH := $(SRCDIRS) #指定除当前路径下的查找源文件的路径
.PHONY: clean
$(TARGET).bin : $(OBJS)
$(LD) -Timx6ul.lds -o $(TARGET).elf $^
$(OBJCOPY) -O binary -S $(TARGET).elf $@
$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
------ By Flier
2024.2.11