Linux make defconfig过程分析

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- xilinx_zynq_defconfig

.config文件生成过程 - 顶层makefile

首先判断是否为make *config,如果是的话 config_targets=1, dot_config=1
然后执行这段脚本:

# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target

# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
include arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG KBUILD_KCONFIG

config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

%config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

走%config规则,依赖scripts_basic、outputmakefile 和FORCE
outputmakefile是一个phony, 其规则如下:

ifneq ($(KBUILD_SRC),)
	$(Q)ln -fsn $(srctree) source
	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif

KBUILD_SRC用来保存kernel代码位置(在代码外编译时会用到),我们在代码位置编译所以为空,所以outputmakefile什么也不执行。

%config依赖FORCE,意味着它的recipe每次都会被执行

scripts_basic是一个phony, 其规则如下:

scripts_basic:
	$(Q)$(MAKE) $(build)=scripts/basic
	$(Q)rm -f .tmp_quiet_recordmcount

$(build)定义在scripts/Kbuild.include,为

###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj

所以 scripts_basic执行的命令会是 make -f ./scripts/Makefile.build obj=scripts/basic
Makefile.build的作用在后边描述

那么,%config的recipe就是:
$(Q)$(MAKE) $(build)=scripts/kconfig $@ => make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

scripts/Makefile.build

上述两个命令都用到了scripts/Makefile.build,这也是一个makefile,其关键变量的定义如下

src := $(obj)
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)

scripts_basic in scripts/Makefile.build

对于顶层Makefile中的scripts_basic目标,执行的make -f ./scripts/Makefile.build obj=scripts/basic。此时变量如下:

  • src: scripts/basic
  • kbuild-dir: /home/liyichen/work/linux4.14/scripts/basic
  • kbuild-file: /home/liyichen/work/linux4.14/scripts/basic/Makefile

所以include的是 /home/liyichen/work/linux4.14/scripts/basic/Makefile

make命令中未指定目标,所以实际构建./scripts/Makefile.build中的默认目标:

__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
	 $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
	 $(subdir-ym) $(always)
	@:

其中,@:表示一个空的shell指令
看一下它的依赖:

  • KBUILD_BUILTIN:由顶层makefile导出,表示是否需要构建(或链接)当前目录下的 built-in.a 内置目标文件,为1
  • builtin-target:在这里是空,因为:
ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)
builtin-target := $(obj)/built-in.o
endif
  • lib-target:为空
  • extra-y:为空(why?)
  • KBUILD_MODULES: 顶层makefile定义并导出,为空,因为我们不是在编译modules
  • subdir-ym:空(why?)
  • always: scripts/basic/fixdep scripts/basic/bin2c (why?)

所以 make -f ./scripts/Makefile.build obj=scripts/basic 的作用就是编译 scripts/basic/fixdep scripts/basic/bin2c

%config in ./scripts/Makefile.build

make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

  • src: scripts/kconfig
  • kbuild-dir: /home/liyichen/work/linux4.14/scripts/kconfig
  • kbuild-file: /home/liyichen/work/linux4.14/scripts/kconfig/Makefile

所以include的是 /home/liyichen/work/linux4.14/scripts/kconfig/Makefile

xxx_defconfig对应的就是 scripts/kconfig/Makefile 中的 %_defconfig 目标:

%_defconfig: $(obj)/conf
	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

展开变量后就是

%_defconfig: scripts/kconfig/conf
@ scripts/kconfig/conf --defconfig=arch/arm/configs/%_defconfig Kconfig

其依赖 scripts/kconfig/conf 是一个命令行程序,将在本机编译。conf工具将defconfig输出到.config中 (TBD)

posted @ 2026-05-08 10:33  p_wild  阅读(4)  评论(0)    收藏  举报