Kconfig
在 Kbuild && Kconfig 这套构建系统中,当我们使用 make xxxconfg 类似的命令时,就会执行 Kconfig 流程。例如,当执行 make menuconfig 时会出现一个配置界面,允许开发者通过类似于 UI 的方式来对内核进行配置,之所为我们可以看到这个类似于 UI 的界面,就是因为 Kconfig 从中产生了多个文件和工具来实现的。
当我们在 U-Boot 根目录执行 make menuconfig 或者 make xxx_deconfig 时,make 命令便会读取 U-Boot 根目录下的 Makefile 文件,然后解析并匹配 Makefile 文件中的规则 。而 xxxconfig 就会匹配根目录下 Makefile 文件中的如下图示的规则(% 可以匹配任意非空字符串,所以 menuconfig、xxx_deconfig 都匹配):
- Q 是否显示信息信息,在 Makefile 前面有赋值为 @ 或 空
- MAKE: 就是指的可执行程序 make
- $(build): 定义在 ./scripts/Kbuild.include 中:181行
那么将以上命令展开之后就是:make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig menuconfig 或者 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig xxx_defconfig
- $(srctree): 在 Makefile 前面有赋值为 . 或 $(KBUILD_SRC)
- scripts_basic: 就定义在 U-Boot 根目录的 Makefile 中
那么将以上命令第一句规则展开之后就是:make -f $(srctree)/scripts/Makefile.build obj=scripts/basic ,第二句规则没啥可说的,就是移除个文件。
- outputmakefile: 就定义在 U-Boot 根目录的 Makefile 中,如下所示:
从规则代码可以看出只有当 KBUILD_SRC 不为空时才有效,而对于 KBUILD_SRC 一般都是空,非空的情况下一般也不使用。因此,这里的依赖 outputmakefile 这里就是空。对于具体见如下说明:
- FORCE 是没有规则和依赖的,所以每次都会重新生成 FORCE。当 FORCE 作为其他目标的依赖时,由于 FORCE 总是被更新过的,因此依赖所在的规则总是会执行的。
经过上面的分析,最终由两条语句 make -f $(srctree)/scripts/Makefile.build obj=scripts/basic 和 make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig menuconfig 或者 make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig xxx_defconfig 是我们需要进一步来解析的。接下来就要进入 /scripts/Makefile.build 这个文件了。
Makefile.build
对于 Makefile.build 文件,目前我们只需要关注下图所示的两部分(说明见注释):
接下就是进一步处理 scripts/basic/Makefile 或者 scripts/kconfig/Makefile 了。
make xxx_deconfig
经过上面的分析,当我执行 make xxx_defconfig 时(例如,我这里的 make stm32f769-disco_defconfig),最终会执行以下两句:make -f $(srctree)/scripts/Makefile.build obj=scripts/basic 和 make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig xxx_defconfig 。
- make -f $(srctree)/scripts/Makefile.build obj=scripts/basic 展开后是 cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -o scripts/basic/fixdep scripts/basic/fixdep.c 最终在 scripts/basic/ 目录下生成了可执行工具 fixdep。
- make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig xxx_defconfig 展开后是:
cc -Wp,-MD,scripts/kconfig/.conf.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -c -o scripts/kconfig/conf.o scripts/kconfig/conf.c
bison -oscripts/kconfig/zconf.tab.c -t -l scripts/kconfig/zconf.y
flex -oscripts/kconfig/zconf.lex.c -L scripts/kconfig/zconf.l
cc -Wp,-MD,scripts/kconfig/.zconf.tab.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -Iscripts/kconfig -c -o scripts/kconfig/zconf.tab.o scripts/kconfig/zconf.tab.c
cc -o scripts/kconfig/conf scripts/kconfig/conf.o scripts/kconfig/zconf.tab.o
scripts/kconfig/conf --defconfig=arch/../configs/stm32f769-eval_defconfig Kconfig
最终在 scripts/kconfig/ 目录下生成了可执行工具 conf,紧接着使用刚生成的 scripts/kconfig/conf 工具根据我们指定的 stm32f769-eval_defconfig 生成 .config 文件。
make menuconfig
经过上面的分析,当我执行 make menuconfig 时,最终会执行以下两句:make -f $(srctree)/scripts/Makefile.build obj=scripts/basic 和 make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig menuconfig 。
- make -f $(srctree)/scripts/Makefile.build obj=scripts/basic 与 make xxx_deconfig 时的语句是一样的。如果在执行 make menuconfig 之前没有使用 make xxx_deconfig,那么这句就会和 make xxx_deconfig 时一样去执行来生成 scripts/basic/fixdep。
- make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig menuconfig 展开后是:
make -f ./scripts/Makefile.build obj=scripts/basic
rm -f .tmp_quiet_recordmcount
make -f ./scripts/Makefile.build obj=scripts/kconfig menuconfig
set -e; mkdir -p scripts/kconfig/; /bin/bash scripts/kconfig/mconf-cfg.sh < scripts/kconfig/mconf-cfg.sh > scripts/kconfig/.mconf-cfg.tmp; if [ -r scripts/kconfig/.mconf-cfg ] && cmp -s scripts/kconfig/.mconf-cfg scripts/kconfig/.mconf-cfg.tmp; then rm -f scripts/kconfig/.mconf-cfg.tmp; else : ' UPD scripts/kconfig/.mconf-cfg'; mv -f scripts/kconfig/.mconf-cfg.tmp scripts/kconfig/.mconf-cfg; fi
cc -Wp,-MD,scripts/kconfig/.mconf.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/mconf.o scripts/kconfig/mconf.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.checklist.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/checklist.o scripts/kconfig/lxdialog/checklist.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.inputbox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/inputbox.o scripts/kconfig/lxdialog/inputbox.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.menubox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/menubox.o scripts/kconfig/lxdialog/menubox.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.textbox.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/textbox.o scripts/kconfig/lxdialog/textbox.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.util.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/util.o scripts/kconfig/lxdialog/util.c
cc -Wp,-MD,scripts/kconfig/lxdialog/.yesno.o.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -std=gnu11 -D_DEFAULT_SOURCE -D_XOPEN_SOURCE=600 -c -o scripts/kconfig/lxdialog/yesno.o scripts/kconfig/lxdialog/yesno.c
cc -o scripts/kconfig/mconf scripts/kconfig/mconf.o scripts/kconfig/zconf.tab.o scripts/kconfig/lxdialog/checklist.o scripts/kconfig/lxdialog/inputbox.o scripts/kconfig/lxdialog/menubox.o scripts/kconfig/lxdialog/textbox.o scripts/kconfig/lxdialog/util.o scripts/kconfig/lxdialog/yesno.o -Wl,-Bsymbolic-functions -lncursesw -ltinfo
scripts/kconfig/mconf Kconfig
最终生成 scripts/kconfig/mconf,紧接着使用刚生成的 scripts/kconfig/mconf 工具读取根目录的 Kconfig 文件,随之出现配置界面。
make xxx_deconfig之后,Kconfig 系统会在 U-Boot 源码根目录下生成 .config 文件,当我们使用 make menuconfig 修改了相关配置之后,Kconfig 系统最终也是修改根目录下的 .config 文件(注意,该文件默认是个隐藏文件,可使用 ls -al 查看),而 .config 文件就记录了我们当前对于 U-Boot 的配置,后续构建时便会读取该文件。
|