linux make xxx_defconfig 过程 Makefile.build 脚本分析

本文深入剖析Linux内核构建过程,重点介绍config-targets、mixed-targets和dot-config变量的作用,以及它们如何影响内核配置和编译。文章详细解释了Makefile中的条件编译流程,展示了如何通过scripts/kconfig生成.config配置文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

config-targets := 0
mixed-targets  := 0
dot-config     := 1

ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
		dot-config := 0
	endif
endif

ifeq ($(KBUILD_EXTMOD),)
        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                config-targets := 1
                ifneq ($(words $(MAKECMDGOALS)),1)
                        mixed-targets := 1
                endif
        endif
endif

ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.

PHONY += $(MAKECMDGOALS) __build_one_by_one

$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
	@:

__build_one_by_one:
	$(Q)set -e; \
	for i in $(MAKECMDGOALS); do \
		$(MAKE) -f $(srctree)/Makefile $$i; \
	done

else
ifeq ($(config-targets),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 $@

else
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.

ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice
# in parallel
PHONY += scripts
scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
	 asm-generic
	$(Q)$(MAKE) $(build)=$(@)

# Objects we will link into vmlinux / subdirs we need to visit
init-y		:= init/
drivers-y	:= drivers/ sound/ firmware/
net-y		:= net/
libs-y		:= lib/
core-y		:= usr/
endif # KBUILD_EXTMOD

第 490~507 行和 uboot 一样,都是设置定义变量 config-targets、 mixed-targets 和 dot-config的值,最终这三个变量的值为:

config-targets= 1
mixed-targets= 0
dot-config= 1

因为 config-targets=1,因此第 534 行~541 行成立。第 534 行引用 arch/arm/Makefile 这个文件,这个文件很重要, 因为 zImage、 uImage 等这些文件就是由 arch/arm/Makefile 来生成的。
第 535 行导出变量 KBUILD_DEFCONFIG KBUILD_KCONFIG。
第 537 行,没有目标与之匹配,因此不执行。
第 540 行,“make xxx_defconfig”与目标“%config”匹配,因此执行。“%config”依赖scripts_basic、 outputmakefile 和 FORCE,“%config”真正有意义的依赖就只有 scripts_basic,scripts_basic 的规则如下:

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

build 定义在文件 scripts/Kbuild.include 中,值为 build := -f $(srctree)/scripts/Makefile.buildobj,因此将代码展开就是:

scripts_basic:
@make -f ./scripts/Makefile.build obj=scripts/basic //也可以没有@,视配置而定
@rm -f . tmp_quiet_recordmcount //也可以没有@

Makefile.build 脚本分析

从上一小节可知,“ make xxx_defconfig“配置 Linux 的时候如下两行命令会执行脚本

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

我们依次来分析一下:

1、 scripts_basic 目标对应的命令

scripts_basic 目标对应的命令为: @make -f ./scripts/Makefile.build obj=scripts/basic。打开文件 scripts/Makefile.build,有如下代码:

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

将 kbuild-dir 展开后为:

kbuild-dir=./scripts/basic

将 kbuild-file 展开后为:

kbuild-file= ./scripts/basic/Makefile

最后将 59 行展开,即:

include ./scripts/basic/Makefile

继续分析 scripts/Makefile.build,如下代码:

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

__build 是默认目标,因为命令“@make -f ./scripts/Makefile.build obj=scripts/basic”没有指定目标,所以会使用到默认目标__build。在顶层 Makefile 中, KBUILD_BUILTIN 为 1,KBUILD_MODULES 为空,因此展开后目标__build 为:

__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)
@:

可以看出目标__build 有 5 个依赖: builtin-target、 lib-target、 extra-y、 subdir-ym 和 always。
这 5 个依赖的具体内容如下:

builtin-target =
lib-target =
extra-y =
subdir-ym =
always = scripts/basic/fixdep scripts/basic/bin2c

只有 always 有效,因此__build 最终为:

__build: scripts/basic/fixdep scripts/basic/bin2c
@:

__build 依赖于 scripts/basic/fixdep 和 scripts/basic/bin2c,所以要先将 scripts/basic/fixdep 和scripts/basic/bin2c.c 这两个文件编译成 fixdep 和 bin2c。
综上所述, scripts_basic 目标的作用就是编译出 scripts/basic/fixdep 和 scripts/basic/bin2c 这两个软件。
2、 %config 目标对应的命令
%config 目 标 对 应 的 命 令 为 :

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

xxx_defconfig,此命令会使用到的各个变量值如下:

src= scripts/kconfig
kbuild-dir = ./scripts/kconfig
kbuild-file = ./scripts/kconfig/Makefile
include ./scripts/kconfig/Makefile

可以看出, Makefile.build 会读取 scripts/kconfig/Makefile 中的内容,此文件有如下所示内容:

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

目标%_defconfig 与 xxx_defconfig 匹配,所以会执行这条规则,将其展开就是:

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

%_defconfig依赖scripts/kconfig/conf,所以会编译scripts/kconfig/conf.c生成conf这个软件。
此软件就会将%_defconfig 中的配置输出到.config 文件中,最终生成 Linux kernel 根目录下的.config 文件。

<think>嗯,我现在需要理解用户提到的命令:make -C buildroot defconfig BR2_DEFCONFIG=../$(buildroot_defconfig)。首先,这个命令看起来是用于Buildroot系统的配置。让我先拆解一下各个部分的作用。 首先,make是构建工具,-C buildroot应该是指切换到buildroot目录下执行make命令。defconfig是一个目标,通常用于生成默认配置。然后是BR2_DEFCONFIG=../$(buildroot_defconfig),这里可能涉及到环境变量或者Makefile中的变量替换。不过用户这里的$(buildroot_defconfig)可能需要用具体的文件名替换,比如用户可能有自己的defconfig文件,比如raspberrypi3_defconfig之类的。 接下来,我需要确认各个参数的具体含义。make -C <dir>会让make先切换到指定目录再执行,所以这里就是进入buildroot目录,执行make defconfig,并且设置BR2_DEFCONFIG变量为上级目录下的某个defconfig文件。通常,Buildroot在配置时可以使用BR2_DEFCONFIG来指定外部配置文件的位置,这样在生成.config时会基于这个文件进行配置。 不过,用户命令中的$(buildroot_defconfig)可能是一个变量,但在实际使用时需要替换为具体的文件名,否则shell会尝试将其解释为变量,如果未定义的话可能出错。例如,用户应该运行类似这样的命令:make -C buildroot defconfig BR2_DEFCONFIG=../configs/raspberrypi3_defconfig,其中../configs/...是相对于buildroot目录的路径。 可能用户在使用时,buildroot_defconfig是一个变量,存储了配置文件的路径,所以需要根据实际情况替换。此外,理解Buildroot的工作流程也很重要:defconfig目标用于生成默认配置,BR2_DEFCONFIG指定了外部配置文件的位置,Buildroot会将该文件复制到.config并进行必要的处理。 可能还需要检查路径是否正确,确保指定的defconfig文件确实存在于../的位置。如果路径错误,Buildroot可能会报错找不到文件。此外,执行该命令后,Buildroot会根据提供的defconfig生成.config,之后用户可以进行进一步的配置或编译。 总结一下,这个命令的作用是让Buildroot使用指定的外部配置文件来初始化项目的默认配置。用户需要确保变量替换正确,并且路径有效。同时,了解Buildroot的配置流程对于正确使用这些命令很重要。</think>在使用Buildroot进行嵌入式系统构建时,`make -C buildroot defconfig BR2_DEFCONFIG=../$(buildroot_defconfig)` 是一个关键命令,以下是逐步解析: --- ### **1. 命令拆解** - **`-C buildroot`** 表示切换目录到 `buildroot`,后续的 `make` 操作将在该目录下执行。 - **`defconfig`** 这是Makefile的目标(Target),作用是根据指定配置初始化Buildroot环境。 它会生成 `.config` 文件,包含工具链、内核、文件系统等配置。 - **`BR2_DEFCONFIG=../$(buildroot_defconfig)`** `BR2_DEFCONFIG` 是Buildroot的环境变量,用于指定外部自定义配置文件的路径。 `$(buildroot_defconfig)` 需替换为实际文件名(如 `raspberrypi4_defconfig`),路径指向Buildroot目录外的配置文件。 --- ### **2. 执行逻辑** 1. **切换目录** ```bash cd buildroot ``` 2. **调用defconfig目标** ```bash make defconfig ``` 3. **指定外部配置文件** Buildroot会从 `../`(上级目录)加载名为 `buildroot_defconfig` 的配置文件(需替换为实际文件名),并将其复制到 `buildroot/.config`。 --- ### **3. 典型使用场景** 假设你有一个自定义配置文件 `my_board_defconfig` 存放在 `configs/` 目录下: ```bash make -C buildroot defconfig BR2_DEFCONFIG=../configs/my_board_defconfig ``` 执行后: - Buildroot会生成 `.config`,内容基于 `my_board_defconfig`。 - 后续可通过 `make menuconfig` 调整配置,或直接编译 `make`。 --- ### **4. 注意事项** - **路径正确性** 确保 `BR2_DEFCONFIG` 指向的文件路径有效。若路径错误,会报错 `No such file or directory`。 - **变量替换** `$(buildroot_defconfig)` 是Shell变量,需提前定义或直接替换为文件名: ```bash # 错误(未定义变量时): make -C buildroot defconfig BR2_DEFCONFIG=../$(my_config) # 正确(直接使用文件名): make -C buildroot defconfig BR2_DEFCONFIG=../my_config_defconfig ``` - **后续操作** 生成 `.config` 后,建议保存配置以便复用: ```bash make savedefconfig # 将当前配置保存为 defconfig 文件 ``` --- ### **5. 总结** 该命令的核心作用是 **通过外部配置文件快速初始化Buildroot项目**,适用于批量构建或团队协作场景。使用时需注意: 1. 替换 `$(buildroot_defconfig)` 为实际文件名。 2. 确保配置文件路径正确。 3. 理解 `defconfig` 与 `.config` 的关系(前者是模板,后者是编译依据)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值