顶层目录的makefile的关键编译操作都是在makefile.build中定义的。
//把“__build”设置为假想目标
PHONY := __build
__build:
//清零obj-y,subdir-y ,EXTRA_CFLAGS变量
obj-y :=
subdir-y :=
EXTRA_CFLAGS :=
//包含Makefile,提取Makefile中的变量
include Makefile
# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y)) : c/ d/
# __subdir-y : c d
# subdir-y : c d
//使用filter函数将 obj-y中由空格隔开且匹配格式`/’的字提取出来
//使用patsubst 函数寻找`obj-y中符合格式`/’的字,用` ’替换它们
//给subdir-y赋值。
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
# c/built-in.o d/built-in.o
//使用foreach 函数,在subdir-y变量中提取每个由空格隔开的值并赋值给f,然后将f替换为f/built-in.o,在每个f/built-in.o之间添加空格组成一个新的字符串,给subdir_objs赋值。
subdir_objs := $(foreach f,$(subdir-y),$(f)/built-in.o)
# a.o b.o
//调用filter-out函数,返回在obj-y中由空格隔开且不匹配格式`/’的字
cur_objs := $(filter-out %/, $(obj-y))
//使用foreach 函数,在cur_objs变量中提取每个由空格隔开的值并赋值给f,然后将f替换为.$(f).d($(f)前加‘.’,代表这个文件是隐藏的)
dep_files := $(foreach f,$(cur_objs),.$(f).d)
//用wildcard 函数提取符合dep_files格式的.d文件,并在每一个文件名中间插入空格。
dep_files := $(wildcard $(dep_files))
//如果dep_files非空,包含dep_files中的文件
ifneq ($(dep_files),)
include $(dep_files)
endif
//
PHONY += $(subdir-y)
//根据文件夹里的built-in.o生成目标
__build : $(subdir-y) built-in.o
//进入子目录,使用Makefile.build编译子目录
$(subdir-y):
make -C $@ -f $(TOPDIR)/Makefile.build
//把当前目录的.O和子目录下的built-in.o链接成
built-in.o : $(cur_objs) $(subdir_objs)
$(LD) -r -o $@ $^
dep_file = .$@.d
//使用CC编译器将c文件编译为.o文件
//变量解析:CC:gcc, CFLAGS:-Wall -O2 -g,
//配置选项含义-Wp:,-MD:生成文件关联的信息,输出将导入到.d的文件里面
%.o : %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -Wp,-MD,$(dep_file) -c -o $@ $<
//重新定义 .PHONY的依赖
.PHONY : $(PHONY)