執行make默認目標的依賴鏈如下:

1. include/config/auto.conf去匹配include/config/%.conf,執行其命令: $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig即make -f ./Makefile silentoldconfig, 該句執行與make x210ii_qt_defconfig相似 silentoldconfig匹配到%config,其依賴scripts_basic,生成fixdep docproc hash 再回到%config下執行$(Q)$(MAKE) $(build)=scripts/kconfig $@即make scripts/Makefile.build obj=scripts/kconfig silentoldconfig,其過程為Makefile.build 包含scripts/kconfig/Makefile,其包含了silentoldconfig目標,silentoldconfig又依賴於scripts/kconfig/conf, Makefile.host依據scripts/kconfig里的材料再次生成conf,回到執行silentoldconfig目標下的命令$< -s $(Kconfig) 即scripts/kconfig/conf -s arch/arm/Kconfig該命令根據.config和arch/arm/Kconfig生成include/config/auto.conf.cmd, include/config/auto.conf ,include/generated/autoconf.h
2. 回到include/config/kernel.release,該目標命令:
$(Q)echo "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))" > $@,該句將版本信息輸出到include/config/kernel.release,
3. 再回到prepare3,無命令;
4. 回到prepare2,無命令,
5. 到include/linux/version.h下執行$(call filechk,version.h)該句得到include/linux/version.h;
6. 再到include/generated/utsrelease.h下執行$(call filechk,utsrelease.h)得到include/generated/utsrelease.h;
7. 再回到prepare1,無命令;再到scripts_basic和上次功能一樣;回到archprepare執行$(Q)$(MAKE) $(clean)=$(boot),該句產生include/generated/mach-types.h,該命令再arch/arm/Makefile中;
8. 回到prepare0 執行$(Q)$(MAKE) $(build)=. 即把當前目錄傳遞給scripts/Makefile.build,則該makefile會包含根目錄下的kbuild,根據該文件下的規則產生include/generated/bounds.h和include/generated/asm-offsets.h;
9. 回到prepare0 執行下一句$(Q)$(MAKE) $(build)=. missing-syscalls該句根據kbuild下的規則去執行scripts/checksyscalls.sh腳本,
10. 到scripts,開始執行scripts下的命令$(Q)$(MAKE) $(build)=$(@) 即make -f scripts/Makefile.host obj=script 先包含scripts下的Makefile默認執行目標__build其此時依賴鏈如下:
__build:
$(subdir-ym) $(always)
subdir-ym=scripts/mod always= scripts/kallsyms scripts/pnmtologo scripts/conmakehash
開始$(subdir-ym)的命令$(Q)$(MAKE) $(build)=$@即make -f scripts/Makefile.build obj=scripts/mod該命令先用scripts/mod/mk_elfconfig.c生成mk_elfconfig,再用mk_elfconfig生成mk_elfconfig.h,最后得到scripts/mod/modpost,
退出回到$(always)得到scripts/kallsyms scripts/pnmtologo scripts/conmakehash退出scripts
11. 接下來回到目標$(vmlinux-dirs)執行至關重要的一句話$(Q)$(MAKE) $(build)=$@首先我們來分析$(vmlinux-dirs)它包含 $(init-y) $(init-m) $(core-y) $(core-m) $(drivers-y) $(drivers-m) $(net-y) $(net-m) $(libs-y) $(libs-m) 基本也就是整個內核了,打印出來為:
vmlinux-dirs = init usr arch/arm/kernel arch/arm/mm arch/arm/common arch/arm/mach-s5pv210 arch/arm/plat-s5p arch/arm/plat-samsung arch/arm/vfp kernel mm fs ipc security crypto block drivers sound firmware net arch/arm/lib lib,$(Q)$(MAKE) $(build)=$@將其一一執行。舉例:$@=init時:$(Q)$(MAKE) $(build)=$@即為make -f scripts/Makefile.build obj=init 將包含init/Makefile,其中定義了一些變量和一些規則導致__build的依賴為編入內核模式即builtin-target = init/built-in.o最后根據scripts/Makefile.build,和init/Makefile中的規則生成 init/built-in.o,執行完成退出。
12. 最后生成$(vmlinux-lds) vmlinux.o $(kallsyms.o) vmlinux,zimage
總結:
生成內核的過程:先做准備工作,目標$(vmlinux-dirs)的依賴prepare的scripts用於產生頭文件的一些功能文件,接着對$(vmlinux-dirs)下文件有一一生成,最后生成$(vmlinux-lds) vmlinux.o $(kallsyms.o) vmlinux,zimage
關於文件生成機制:
主Makefile調用scripts/Makefile.build並且傳入obj變量指明要編譯的文件目錄,scripts/Makefile.build中會包含obj變量的makefile或者kbuild,如果執行時未傳入目標則會默認執行scripts/Makefile.build中的__build,該目標有三種依賴模式:編入模式(鏈接到內核),非編入模式,編譯子文件和主機編譯模式,每種依賴模式的確定要根據obj中Makefile定義的變量來確定,編譯規則則是按照scripts/Makefile.build,scripts/Makefile.host,scripts/Makefile.lib,obj/Makefile等來確定;如果執行時指定目標,則obj下的makefile必然有相應的目標與之對應,再根據scripts/Makefile.build,scripts/Makefile.host,scripts/Makefile.lib,obj/Makefile中的規則編譯。
