BSP工程管理实验-编写通用Makefile
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 \ # 头文件.h路径
bsp/clk \
bsp/led \
bsp/delay
SRCDIRS := project \ #源代码.c路径
bsp/clk \
bsp/led \
bsp/delay
INCLUDE := $(patsubst %, -I %, $(INCDIRS)) # 指定生成文件的头文件路径
# patsubst:模式字符串替换函数
# -I指定头文件路径
# INCDIRS每个单词替换 imx6ul 变成 -I imx6ul
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
# foreach 循环作用,$(SRCDIRS)逐一取出当作dir
# 带入表达式$(wildcard $(dir)/*.S)在这些路径下找.S文件
# 在$(SRCDIRS)的多个路径下,就project有.S文件
# SFILES = project/start.S
SFILENDIR := $(notdir $(SFILES))
CFILENDIR := $(notdir $(CFILES))
# 去掉文件路径 project/start.S 变成 start.S
SOBJS := $(patsubst %, obj/%, $(SFILENDIR:.S=.o))
# 名字start.S变成start.o
COBJS := $(patsubst %, obj/%, $(CFILENDIR:.c=.o))
OBJS := $(SOBJS) $(COBJS)
# 用于依赖处 $(TARGET).bin : $(OBJS),作用就是改下文件后缀
VPATH := $(SRCDIRS)
# 指定在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
$(SOBJS) : obj/%.o : %.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)
# 打印
print;
@echo OBJ=$(OBJ)
函数总结
patsubst函数
$(patsubst ,,
名称:模式字符串替换函数——patsubst。
功能:查找
返回:函数返回被替换过后的字符串。
示例:
$(patsubst %.c,%.o,x.c.c bar.c)
把字符串“x.c.c bar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.o bar.o”
foreach函数
foreach 函数和别的函数非常的不一样。因为这个函数是用来做循环用的, Makefile中的 foreach 函数几乎是仿照于 Unix 标准 Shell( /bin/sh)中的 for 语句,或是 C-Shell(/bin/csh)中的 foreach 语句而构建的。它的语法是:$(foreach < var>,< list>,< text>)
这个函数的意思是,把参数中的单词逐一取出放到参数所指定的变量中,然后再执行
wildcard
如果你要让通配符在变量中展开,也就是让 objects 的值是所有[.o]的文件名的集合,那么,你可以这样:
objects := $(wildcard *.o)