//默认目标的第一依赖对象__modpost,为第二个依赖对象生成所需要的*.mod.c文件,其中
//第二依赖对象就是我们最终需要的endpointdd.ko文件
_modpost:__modpost
includeinclude/config/auto.conf
includescripts/Kbuild.include
includescripts/Makefile.lib
//从模块编译第一阶段中(就是执行KERNEL_make_modules)生成的endpointdd.mod文件
//中提取模块名,则 modules =endpointdd.ko
__modules:= $(sort $(shell grep -h '\.ko' /dev/null $(wildcard$(MODVERDIR)/*.mod)))
modules := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
//默认目标的第二依赖对象endpointdd.ko,就是我们所需要的最终对象文件
_modpost:$(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
//modpost的主处理过程,其中modpost是一个可执行程序,生成第二依赖对象所需要的
//*.mod.c文件
modpost= scripts/mod/modpost \
$(if$(CONFIG_MODVERSIONS),-m) \
$(if$(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
$(if$(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if$(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if$(KBUILD_EXTRA_SYMBOLS), $(patsubst %, -e %,$(KBUILD_EXTRA_SYMBOLS)))\
$(if$(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if$(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
$(if$(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
$(if$(CONFIG_MARKERS),-M $(markersfile)) \
$(if$(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
$(if$(cross_build),-c)
//modpost命令
cmd_modpost= $(modpost) -s
//$(modules:.ko=.o) = endpointdd.o,在模块编译第一阶段已经生成了
//这里执行第一依赖对象的编译
__modpost:$(modules:.ko=.o) FORCE
//执行处理,最终是使用modpost生成所需要的*.mod.c文件
$(callcmd,modpost) $(wildcard vmlinux) $(filter-out FORCE,$^)
//endpointdd.mod.o文件生成,其中依赖的*.mod.c由modpost生成
$(modules:.ko=.mod.o):%.mod.o: %.mod.c FORCE
//使用gcc生成*.mod.o文件
$(callif_changed_dep,cc_o_c)
//第二依赖最终的目标对象endpointdd.ko,这里依赖endpointdd.mod.o文件
$(modules):%.ko :%.o %.mod.o FORCE
//使用ld命令生成最终的endpointdd.ko文件
$(callif_changed,ld_ko_o)