版权声明:转载请声明 https://blog.csdn.net/qq_40732350/article/details/84103748
顶层Makefile解析(随工程而变):
CROSS_COMPILE = #指定编译器种类
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld #链接工具
CC = $(CROSS_COMPILE)gcc #编译工具
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar #打包工具
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip #优化工具
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
export AS LD CC CPP AR NM #将定义的变量导出,方便其他makefile使用
export STRIP OBJCOPY OBJDUMP #将定义的变量导出,方便其他makefile使用
CFLAGS := -Wall -O2 -g #编译器参数
CFLAGS += -I $(shell pwd)/include #指定编译器头文件(根据实际项目手动修改)
LDFLAGS := -lm -lfreetype -lvga #指定编译器链接库(根据实际项目手动修改)
export CFLAGS LDFLAGS #将定义的变量导出,方便其他makefile使用
TOPDIR := $(shell pwd) #获得当前程序的顶层目录
export TOPDIR #输出顶层目录
TARGET := XXXXXXX #编译后的程序名(根据实际项目手动修改)
#-------------------------顶层要生成的.o文件以及顶层文件夹(根据实际项目手动修改)------------
obj-y += main.o
obj-y += display/
obj-y += draw/
obj-y += encoding/
obj-y += fonts/
#--------------------------------------------顶层的第一个规则(默认规则)-----------------all :
make -C ./ -f $(TOPDIR)/Makefile.build #进入当前目录,使用顶层的makefile.build进行编译
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o #将编译好的built-in.o文件链接生成我们的目标文件
#------------------------------------------------顶层的清除规则-------------------
clean:
rm -f $(shell find -name "*.o") #删除所有的.o文件
rm -f $(shell find -name "*.d") #删除所有的.d文件
rm -f $(TARGET) #删除目标文件
.PHONY:all clean
顶层Makefile.build解析(无需改动):
PHONY := __build #定义一个PHONY变量
__build: #开头说明__build伪目标,使其成为Makefile.build的第一个目标
obj-y := #定义当前目录的目标变量,初始值为空
subdir-y := #定义当前目录的子目录变量,初始值为空
include Makefile #将当前目录的Makefile包含进来,初始化obj-y
#obj-y:=a.o b.o c/ d/
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y))) #筛选出当前目录的目标变量中的子目录,并且去掉/
#$(filter %/, $(obj-y)):c/ d/
#__subdir-y:c d
subdir-y += $(__subdir-y) #将开始定义的subdir-y赋值为__subdir-y
#subdir-y:c d
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o) #对于subdir-y里面的每一个值(目录),增加一个相应的目录/built-in.o的变量值
#subdir_objs:c/built-in.o d/built-in.o
cur_objs := $(filter-out %/, $(obj-y)) #得到obj-y中的.o文件
#cur_objs:a.o b.o
dep_files := $(foreach f,$(cur_objs),.$(f).d) #对于所有的.o文件,定义它的依赖文件名
#dep_files: .a.d .b.d
dep_files := $(wildcard $(dep_files))
ifneq ($(dep_files),) #根据依赖文件名,判断依赖文件是否存在,存在就包含就来
include $(dep_files)
endif
PHONY += $(subdir-y) #将$(subdir-y)也加入到变量PHONY中
--------------------------------------------Makefile. build的第一个规则--------------------------------------------
__build : $(subdir-y) built-in.o #第一个规则
$(subdir-y): #第一个规则的第一个依赖规则
make -C $@ -f $(TOPDIR)/Makefile.build #依次进入该子目录变量里面存储的值,使用的Makefile.build进行编译
built-in.o : $(cur_objs) $(subdir_objs) #第一个规则的第二个依赖规则
$(LD) -r -o $@ $^ #该规则的命令:将该目录下的.o和$(subdir_obj)打包成built-in.o文件
dep_file = [email protected] #
%.o : %.c #第一个规则的第二个依赖规则的依赖规则
$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $< #用于将目录下所有的.c文件编译成.o文件
.PHONY : $(PHONY) #将PHONY声明为伪目标
子目录Makefile(随工程而变):
子目录的Makefile就是包含该目录下所有的目标文件名和子目录文件夹名。
例如任何一个子目录可写成:
objs-y := a.o
objs-y += b.o
objs-y += c/
objs-y += d/