文章目录
1. 加载 -include 声明的文件
# 顶层 Makefile 270 KCONFIG_CONFIG ?= .config ...... 580 -include include/config/auto.conf 584 -include include/config/auto.conf.cmd ...... 587 $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; ...... 593 include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd 594 $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig 595 @# If the following part fails, include/config/auto.conf should be 596 @# deleted so "make silentoldconfig" will be re-run on the next build. 597 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \ 598 { rm -f include/config/auto.conf; false; } 599 @# include/config.h has been updated after "make silentoldconfig". 600 @# We need to touch include/config/auto.conf so it gets newer 601 @# than include/config.h. 602 @# Otherwise, 'make silentoldconfig' would be invoked twice. 603 $(Q)touch include/config/auto.conf ...... 608 -include include/autoconf.mk 609 -include include/autoconf.mk.dep
-include:表示在加载的时候会先去查找文件是否存在,
如果存在
,则读入且查看是否有规则对文件中的内容进行更新,如果有,那么等更新完再加载。如果没有相应的更新规则,那么直接加载进来;如果不存在
,会出现一个警告,但并不会直接退出,而是等完成makefile所有文件的读取之后,再试图用规则进行新建文件,如果没有规则新建这个文件,则直接报错,退出程序。
580-584行:尝试包含 auto.conf 和 auto.conf.cmd 这两个文件。
608-609行:尝试包含 autoconf.mk 和 autoconf.mk.dep 这两个文件。
由于使用 -include 进行声明,所以即使这四个文件不存在也不会报错退出。此时这四个文件都不存在,会出现警告但是不会直接退出,等完成 Makefile 读取所有文件后再试图用规则去新建这四个文件。《1.1 完成 Makefile 读取所有文件(列出目标)》由步骤1可知:完成了Makefile 读取所有文件,此时试图用规则去新建这四个文件。《1.2 用规则新建 -include 声明的文件》 回显 1-18
最终:《2. conf 工具》
创建:
回显 1-181 make -f ./Makefile syncconfig 2 make -f ./scripts/Makefile.build obj=scripts/basic 3 rm -f .tmp_quiet_recordmcount 4 make -f ./scripts/Makefile.build obj=scripts/kconfig syncconfig 5 scripts/kconfig/conf --syncconfig Kconfig 6 make -f ./scripts/Makefile.autoconf || \ 7 { rm -f include/config/auto.conf; false; } 8 if [ -d arch/arm/mach-bcm283x/include/mach ]; then \ 9 dest=../../mach-bcm283x/include/mach; \ 10 else \ 11 dest=arch-bcm283x; \ 12 fi; \ 13 ln -fsn $dest arch/arm/include/asm/arch 14 set -e; mkdir -p include/; (echo "/* Automatically generated - do not edit */"; for i in $(echo "" | sed 's/,/ /g'); do echo \#define CONFIG_$i | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'; done; echo \#define CONFIG_BOARDDIR board/raspberrypi/rpi; echo \#include \<config_uncmd_spl.h\>; echo \#include \<configs/"rpi".h\>; echo \#include \<asm/config.h\>; echo \#include \<linux/kconfig.h\>; echo \#include \<config_fallbacks.h\>;) < scripts/Makefile.autoconf > include/config.h.tmp; if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp; then rm -f include/config.h.tmp; else : ' UPD include/config.h'; mv -f include/config.h.tmp include/config.h; fi 15 /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/arm-linux-gnueabihf-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fshort-wchar -fno-strict-aliasing -fno-PIE -O2 -fno-stack-protector -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -g -fstack-usage -Wno-format-nonliteral -Wno-unused-but-set-variable -Werror=date-time -D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -nostdinc -isystem /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -DDO_DEPS_ONLY -dM ./include/common.h > u-boot.cfg.tmp && { grep 'define CONFIG_' u-boot.cfg.tmp > u-boot.cfg; rm u-boot.cfg.tmp; } || { rm u-boot.cfg.tmp; false; } 16 sed -n -f ./tools/scripts/define2mk.sed u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"; fi done > include/autoconf.mk 17 /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/arm-linux-gnueabihf-gcc -x c -DDO_DEPS_ONLY -M -MP -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fshort-wchar -fno-strict-aliasing -fno-PIE -O2 -fno-stack-protector -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -g -fstack-usage -Wno-format-nonliteral -Wno-unused-but-set-variable -Werror=date-time -D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -nostdinc -isystem /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -MQ include/config/auto.conf ./include/common.h > include/autoconf.mk.dep || { rm include/autoconf.mk.dep; false; } 18 touch include/config/auto.conf
1.1 完成 Makefile 读取所有文件(列出目标)
# 顶层 Makefile 141 ifeq ($(KBUILD_SRC),) 145 ifeq ("$(origin O)", "command line") 146 KBUILD_OUTPUT := $(O) 147 endif 150 PHONY := _all 156 ifneq ($(KBUILD_OUTPUT),) 165 PHONY += $(MAKECMDGOALS) sub-make 175 skip-makefile := 1 176 endif # ifneq ($(KBUILD_OUTPUT),) 177 endif # ifeq ($(KBUILD_SRC),) ...... 180 ifeq ($(skip-makefile),) 217 PHONY += all 480 PHONY += scripts_basic 488 PHONY += outputmakefile 512 no-dot-config-targets := clean clobber mrproper distclean \ 513 help %docs check% coccicheck \ 514 ubootversion backup tests check qcheck tcheck 516 config-targets := 0 517 mixed-targets := 0 518 dot-config := 1 520 ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) 521 ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) 522 dot-config := 0 523 endif 524 endif 526 ifeq ($(KBUILD_EXTMOD),) 527 ifneq ($(filter config %config,$(MAKECMDGOALS)),) 528 config-targets := 1 529 ifneq ($(words $(MAKECMDGOALS)),1) 530 mixed-targets := 1 531 endif 532 endif 533 endif 534 535 ifeq ($(mixed-targets),1) 540 PHONY += $(MAKECMDGOALS) __build_one_by_one 551 else 552 ifeq ($(config-targets),1) ...... 566 else 574 PHONY += scripts 1079 PHONY += inputs 1133 PHONY += dtbs 1820 PHONY += $(u-boot-dirs) 1847 PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 2097 PHONY += $(clean-dirs) clean archclean 2120 mrproper-dirs := $(addprefix _mrproper_,scripts) 2122 PHONY += $(mrproper-dirs) mrproper archmrproper 2133 PHONY += distclean 2212 DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \ 2213 linkcheckdocs dochelp refcheckdocs 2214 PHONY += $(DOC_TARGETS) 2218 endif #ifeq ($(config-targets),1) 2219 endif #ifeq ($(mixed-targets),1) 2221 PHONY += checkstack ubootrelease ubootversion 2292 PHONY += coccicheck 2315 endif # skip-makefile 2316 2317 PHONY += FORCE 2322 .PHONY: $(PHONY)
- 141-177行:由于
KBUILD_SRC
未定义为空,所以141行成立;由于未输入make O=xxx
,所以145和156行不成立; 最终:PHONY := _all- 180行:由于步骤1中显示156行条件不成立,
skip-makefile
未定义为空,所以这里条件成立。- 512-533行:特殊变量
MAKECMDGOALS
记录命令行参数指定的终极目标列表(例如:make clean,则MAKECMDGOALS= clean);当输入make M=xxx
时,变量KBUILD_EXTMOD=xxx
;由于这里输入的是make V=1
,所以变量MAKECMDGOALS
和KBUILD_EXTMOD
为空。
最终:
config-targets := 0
mixed-targets := 0
dot-config := 1- 由步骤3可知,
mixed-targets = 0
,所以最终列出的所有目标如下:PHONY = _all all scripts_basic outputmakefile scripts inputs dtbs $(u-boot-dirs) \ prepare archprepare prepare0 prepare1 prepare2 prepare3 $(clean-dirs) clean archclean \ _mrproper_scripts mrproper archmrproper distclean \ xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs linkcheckdocs dochelp refcheckdocs \ checkstack ubootrelease ubootversion coccicheck FORCE
1.2 用规则新建 -include 声明的文件
# 顶层 Makefile 270 KCONFIG_CONFIG ?= .config ...... 580 -include include/config/auto.conf 584 -include include/config/auto.conf.cmd 608 -include include/autoconf.mk 609 -include include/autoconf.mk.dep ...... 587 $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; ...... 593 include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd 594 $(Q)$(MAKE) -f $(srctree)/Makefile syncconfig 595 @# If the following part fails, include/config/auto.conf should be 596 @# deleted so "make silentoldconfig" will be re-run on the next build. 597 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \ 598 { rm -f include/config/auto.conf; false; } 599 @# include/config.h has been updated after "make silentoldconfig". 600 @# We need to touch include/config/auto.conf so it gets newer 601 @# than include/config.h. 602 @# Otherwise, 'make silentoldconfig' would be invoked twice. 603 $(Q)touch include/config/auto.conf
- 580-609行:使用
-include
引用这四个文件,即使这四个文件不存在也不会报错退出,并且接下来按顺序依次寻找新建这四个文件的规则。- 587行:目标
$(KCONFIG_CONFIG)
和include/config/auto.conf.cmd
, 这两个目标没有依赖,也没有生成它的规则命令,所以 GNU Make 本身无法生成 auto.conf.cmd ,然而该条语句后面的一个分号表明,这两个目标被强制是最新的。- 593行:四个声明文件中第一个文件
include/config/auto.conf
的新建规则,由于目标include/config/%.conf
依赖的$(KCONFIG_CONFIG)
和include/config/auto.conf.cmd
在步骤2中被强制为最新的,所以目标的两个依赖无需重新生成(就算不存在也无需生成),接下来执行目标的创建命令即可。- 594行:
$(srctree)
在顶层 Makefile 中定义为.
最终展开后为:# 顶层 Makefile 580 -include include/config/auto.conf 584 -include include/config/auto.conf.cmd 608 -include include/autoconf.mk 609 -include include/autoconf.mk.dep ...... 593 include/config/auto.conf: .config include/config/auto.conf.cmd 594 make -f ./Makefile syncconfig 597 make -f ./scripts/Makefile.autoconf || { rm -f include/config/auto.conf; false; } 603 touch include/config/auto.conf
- 执行594行命令,见下面《1.2.1 执行 make -f ./Makefile syncconfig》 回显 1-5
- 执行597行命令,见下面《1.2.2 执行 make -f ./scripts/Makefile.autoconf》 回显 6-17
- 执行603行命令,执行打印
touch include/config/auto.conf
命令 回显 18
- 创建命令执行说明:
在执行步骤1时include/config/auto.conf
已经创建,由《touch命令》 可知:不会创建或修改此文件,只会修改此文件的访问时间
和修改时间
最终:《2. conf 工具》
创建:
回显 1-181 make -f ./Makefile syncconfig 2 make -f ./scripts/Makefile.build obj=scripts/basic 3 rm -f .tmp_quiet_recordmcount 4 make -f ./scripts/Makefile.build obj=scripts/kconfig syncconfig 5 scripts/kconfig/conf --syncconfig Kconfig 6 make -f ./scripts/Makefile.autoconf || \ 7 { rm -f include/config/auto.conf; false; } 8 if [ -d arch/arm/mach-bcm283x/include/mach ]; then \ 9 dest=../../mach-bcm283x/include/mach; \ 10 else \ 11 dest=arch-bcm283x; \ 12 fi; \ 13 ln -fsn $dest arch/arm/include/asm/arch 14 set -e; mkdir -p include/; (echo "/* Automatically generated - do not edit */"; for i in $(echo "" | sed 's/,/ /g'); do echo \#define CONFIG_$i | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'; done; echo \#define CONFIG_BOARDDIR board/raspberrypi/rpi; echo \#include \<config_uncmd_spl.h\>; echo \#include \<configs/"rpi".h\>; echo \#include \<asm/config.h\>; echo \#include \<linux/kconfig.h\>; echo \#include \<config_fallbacks.h\>;) < scripts/Makefile.autoconf > include/config.h.tmp; if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp; then rm -f include/config.h.tmp; else : ' UPD include/config.h'; mv -f include/config.h.tmp include/config.h; fi 15 /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/arm-linux-gnueabihf-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fshort-wchar -fno-strict-aliasing -fno-PIE -O2 -fno-stack-protector -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -g -fstack-usage -Wno-format-nonliteral -Wno-unused-but-set-variable -Werror=date-time -D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -nostdinc -isystem /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -DDO_DEPS_ONLY -dM ./include/common.h > u-boot.cfg.tmp && { grep 'define CONFIG_' u-boot.cfg.tmp > u-boot.cfg; rm u-boot.cfg.tmp; } || { rm u-boot.cfg.tmp; false; } 16 sed -n -f ./tools/scripts/define2mk.sed u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"; fi done > include/autoconf.mk 17 /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/arm-linux-gnueabihf-gcc -x c -DDO_DEPS_ONLY -M -MP -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fshort-wchar -fno-strict-aliasing -fno-PIE -O2 -fno-stack-protector -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -g -fstack-usage -Wno-format-nonliteral -Wno-unused-but-set-variable -Werror=date-time -D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -nostdinc -isystem /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -MQ include/config/auto.conf ./include/common.h > include/autoconf.mk.dep || { rm include/autoconf.mk.dep; false; } 18 touch include/config/auto.conf
1.2.1 执行 make -f ./Makefile syncconfig
重新调用顶层 Makefile 文件,并执行
make syncconfig
命令,由此可知:
config-targets := 1
mixed-targets := 0
dot-config := 1
重新调用后的顶层Makefile的目标如下:
PHONY =
_all all scripts_basic outputmakefile checkstack ubootrelease ubootversion coccicheck FORCE
执行 《make xxxx_defconfig》 时,scripts/basic/fixdep
和scripts/kconfig/conf
已创建,
所以执行《make syncconfig V=1 分析》时,其中回显2
和回显5-9
无需创建。
最终:《2. conf 工具》
回显 1-5
1 make -f ./Makefile syncconfig 2 make -f ./scripts/Makefile.build obj=scripts/basic 3 rm -f .tmp_quiet_recordmcount 4 make -f ./scripts/Makefile.build obj=scripts/kconfig syncconfig 5 scripts/kconfig/conf --syncconfig Kconfig
1.2.2 执行 make -f ./scripts/Makefile.autoconf
命令:mkae -f ./scripts/Makefile.autoconf || { rm -f include/config/auto.conf; false; }
||
表示逻辑或,||
左边的命令执行成功,后面的命令就不会被执行,否则||
右边的命令才会被执行。false
或true
是两个内置命令,可以单独运行,true
单独运行完返回状态码0
,false
单独运行完返回状态码非0
最终:
- 执行:
mkae -f ./scripts/Makefile.autoconf || { rm -f include/config/auto.conf; false; }
, 回显 6-7- 由《make -f ./scripts/Makefile.autoconf》 分析可知:
2.1 将arch/arm/mach-bcm283x/include/mach
软连接到arch/arm/include/asm/arch
, 回显 8-13
2.2 执行$(filechk_config_h)
命令,将执行结果写入include/config.h
文件中, 回显 14
2.3 打印和执行$(cmd_u_boot_cfg)
命令,将执行结果写入u-boot.cfg
文件中, 回显 15
2.4 打印和执行$(cmd_autoconf)
命令,将执行结果写入include/autoconf.mk
文件中, 回显 16
2.5 打印和执行$(cmd_autoconf_dep)
命令,将执行结果写入include/autoconf.mk.dep
文件中, 回显 17创建
回显 6-17
6 make -f ./scripts/Makefile.autoconf || \ 7 { rm -f include/config/auto.conf; false; } 8 if [ -d arch/arm/mach-bcm283x/include/mach ]; then \ 9 dest=../../mach-bcm283x/include/mach; \ 10 else \ 11 dest=arch-bcm283x; \ 12 fi; \ 13 ln -fsn $dest arch/arm/include/asm/arch 14 set -e; mkdir -p include/; (echo "/* Automatically generated - do not edit */"; for i in $(echo "" | sed 's/,/ /g'); do echo \#define CONFIG_$i | sed '/=/ {s/=/ /;q; } ; { s/$/ 1/; }'; done; echo \#define CONFIG_BOARDDIR board/raspberrypi/rpi; echo \#include \<config_uncmd_spl.h\>; echo \#include \<configs/"rpi".h\>; echo \#include \<asm/config.h\>; echo \#include \<linux/kconfig.h\>; echo \#include \<config_fallbacks.h\>;) < scripts/Makefile.autoconf > include/config.h.tmp; if [ -r include/config.h ] && cmp -s include/config.h include/config.h.tmp; then rm -f include/config.h.tmp; else : ' UPD include/config.h'; mv -f include/config.h.tmp include/config.h; fi 15 /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/arm-linux-gnueabihf-gcc -E -Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -std=gnu11 -fshort-wchar -fno-strict-aliasing -fno-PIE -O2 -fno-stack-protector -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -g -fstack-usage -Wno-format-nonliteral -Wno-unused-but-set-variable -Werror=date-time -D__KERNEL__ -D__UBOOT__ -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux -mword-relocations -fno-pic -mno-unaligned-access -ffunction-sections -fdata-sections -fno-common -ffixed-r9 -msoft-float -pipe -Iinclude -I./arch/arm/include -include ./include/linux/kconfig.h -nostdinc -isystem /home/xd/rpi3b/toolchain/toolchain-rpi32b/bin/../lib/gcc/arm-linux-gnueabihf/7.5.0/include -DDO_DEPS_ONLY -dM ./include/common.h > u-boot.cfg.tmp && { grep 'define CONFIG_' u-boot.cfg.tmp > u-boot.cfg; rm u-boot.cfg.tmp; } || { rm u-boot.cfg.tmp; false; } 16 sed -n -f ./tools/scripts/define2mk.sed u-boot.cfg | while read line; do if [ -n "" ] || ! grep -q "${line%=*}=" include/config/auto.conf; then echo "$line"