Makefile常用命令
# 下面用来定义变量并赋值
# := 和 = 一样的吗?
# 这里?=代表如果变量已经赋值了,不要重新赋值,而是保留原来的值
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET ?= key
# 配置一些编译工具
# CC用来编译汇编.S文件和C语言.c文件, 从而得到.o目标文件
# LD用来链接.o目标文件为.elf文件
# OBJCOPY用来去除.elf文件中符号表,重定位表和调戏信息等,从而得到.bin文件
# OBJDUMP用来反编译.elf文件, 得到.dis汇编代码
CC := $(CROSS_COMPILE)gcc
LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy
OBJDUMP := $(CROSS_COMPILE)objdump
# \代表并接到一行内,注意\只能是行末, 等价写法就是
# INCDIRS := imx6ul bsp/clk bsp/led bsp/delay (后面继续)
INCDIRS := imx6ul \
bsp/clk \
bsp/led \
bsp/delay \
bsp/beep \
bsp/gpio \
bsp/key
SRCDIRS := target \
bsp/clk \
bsp/led \
bsp/delay \
bsp/beep \
bsp/gpio \
bsp/key
# patsubst函数 用法就是
# %代表INCDIRS中每个空格分隔的字符串,
# 现在把 INCDIRS中的 任意字符串 % 替换为 字符串 -I %
# 例如这里imx6ul bsp/clk bsp/led bsp/delay (等) 就变为了-I imx6ul -I bsp/clk -I bsp/led -I bsp/delay (等)
INCLUDE := $(patsubst %, -I %, $(INCDIRS))
# foreach函数 $(dir) 代表 $(SRCDIRS)中么个空格分割的字符串
# wildcard 函数代表按通配符寻找 $(dir)目录下的所有文件
# 下面会得到SFILES是类似 aaa/bbb.S ccc/ddd.S
# 下面会得到CFILES是类似 aaa/bbb.c ccc/ddd.c
SFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.S))
CFILES := $(foreach dir, $(SRCDIRS), $(wildcard $(dir)/*.c))
# 下面通过notdir函数去除目录路径
# 会得到类似bbb.S, ddd.S和 bbb.c, ddd.c等
SFILENDIR := $(notdir $(SFILES))
CFILENDIR := $(notdir $(CFILES))
# 下面用patsubst函数来替换,注意 $(SFINENDIR:.S=.o)的写法使得
# 前一个%代表 SFINENDIR中的每个xxx.S, 后一个%对应代表xxx.o
SOBJS := $(patsubst %, obj/% $(SFINENDIR:.S=.o))
COBJS := $(patsubst %, obj/% $(CFINENDIR:.c=.o))
OBJS := $(SOBJS) $(COBJS)
# VPATH用于在依赖文件中使用了%.xxx 就去VPATH指定的路径搜索相关文件
VPATH = $(SRCDIRS)
# 代表clean是一个伪目标,以免Makefile同级目录下有一个clean文件导致make clean不会执行
.PHONY clean:
# $^代表依赖集合 $@代表目标
# -Timx6ul.lds指定imx6ul.lds文件所描述的链接配置来链接.o目标文件
# OBJCOPY中的 -S 代表过滤掉.elf中的符号表和重定位表
$(TARGET).bin : $(OBJS)
$(LD) -Timx6ul.lds -o $(TARGET).elf $^
$(OBJCOPY) -O binary -S $(TARGET).elf $@
$(OBJDUMP) -D -m arm $(TARGET).elf > $(TARGET).dis
# $<代表依赖集合中的第一个依赖文件
# 这里通过$(SOBJS)指定了目标文件的集合
$(SOBJS) : obj/%.o : %.S
$(CC) -Wall -nostdlib -c -O2 -o $@ $<
$(COBJS) : obj/%.o : %.c
$(CC) -Wall -nostdlib -c -O2 -o $@ $<
clean:
rm -rf $(TARGET).bin $(TARGET).elf $(TARGET).dis $(OBJS)