CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= bsp
CC := $(CROSS_COMPILE)gcc #$(变量名)引用变量
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
#整个工程的.h头文件目录,"\"表示换行符
INCDIRS := imx6ul \
bsp/clk \
bsp/led \
bsp/delay
#整个工程的所有.c和.s文件
SRCDIRS := project \
bsp/clk \
bsp/led \
bsp/delay
# $(subst <from>,<to>,<text>) 将字符串<text>中的<from>内容替换为<to>
# $(patsubst <pattern>,<replacement>,<text>) 和上面一样但是多了"%".
# $(dir <names...>) 提取目录.如$(dir </src/a.c>) 还回/src.
# $(notdir <names...>) 提取文件名.如$(notdir </src/a.c>) 还回a.c
# $(foreach <var>, <list>,<text>) 把参数<list>中的单词逐一取出来放到参数<var>中,然后再执行<text>所包含的表达式。
# 每次<text>都会返回一个字符串,循环的过程中,<text>中所包含的每个字符串会以空格隔开,最后当整个循环结束时,
# <text>所返回的每个字符串所组成的整个字符串将会是函数 foreach 函数的返回值。
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
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))#放入obj文件夹
COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS := $(SOBJS) $(COBJS)
VPATH := $(SRCDIRS)
# "="变量的真实值取决于它所引用的变量的最后一次有效值.
#":="不会使用后面定义变量的值.
#"?="若前面没有赋值则现在赋值.若已经赋值则用之前的值.
#"+="追加变量的内容.
.PHONY: clean #伪目标clean. 避免生成文件,规则后面的命令会执行.
$(TARGET).bin : $(OBJS)
$(LD) -Timx6ul.lds -o $(TARGET).elf $^
$(OBJCOPY) -O binary -S $(TARGET).elf $@
$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
#"%"目标中表示对文件名的匹配.或者表示模式规则.
$(SOBJS) : obj/%.o : %.S #所有的.c和.s文件.
$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
#$@表示表示匹配模式中定义的目标集合.
#$<符合模式的一系列文件集合.
$(COBJS) : obj/%.o : %.c
$(CC) -Wall -nostdlib -c -O2 $(INCLUDE) -o $@ $<
clean:
rm -rf $(TARGET).elf $(TARGET).dis $(TARGET).bin $(COBJS) $(SOBJS)
#通配符“%”只能用在规则中,只有在规则中它才会展开,如果在变量定义和函数使用时,
#通配符不会自动展开,这个时候就要用到函数 wildcard,$(wildcard *.c) 功能和%一样.