当前位置: 首页 > news >正文

imx6ull-系统移植篇5——U-Boot 顶层 Makefile 简析

目录

前言

Makefile分析

版本号

MAKEFLAGS 变量

命令输出

静默输出

设置编译结果输出目录

代码检查

模块编译

获取主机架构和系统

设置目标架构、交叉编译器和配置文件

调用 scripts/Kbuild.include

交叉编译工具变量设置

导出其他变量

make xxx_defconfig 过程

1. 命令解析阶段​​

​​2. Makefile 关键逻辑​​

​​分解说明​​:

​​3. 配置生成流程​​

​​步骤 1:复制默认配置​​

​​步骤 2:运行配置工具​​

​​步骤 3:生成头文件​​

​​4. Kconfig 系统的作用​​

​​5. 输出文件解析​​

Makefile.build 脚本分析

scripts_basic目标分析​

%config目标分析​

make流程


前言

在分析大型开源项目(如 U-Boot 或 Linux 内核)的源码时,​​必须从顶层 Makefile 入手​​,这是理解工程组织结构的核心入口。通过逐层分析顶层 Makefile 和子目录的 Makefile,可以清晰地掌握以下关键点:

  1. 工程构建流程​​:了解编译目标、依赖关系以及工具链的调用方式。

  2. ​代码模块划分​​:通过子目录的 Makefile 定位功能模块的代码分布。

  3. ​配置系统​​:分析 Kconfig与 Makefile 的联动逻辑,明确功能模块的编译条件。

本讲实验就让我们来分析一下U-Boot 的顶层 Makefile。

Makefile分析

版本号

VERSION 是主版本号, PATCHLEVEL 是补丁版本号, SUBLEVEL 是次版本号,这三个一起构成了 uboot 的版本号。比如当前的 uboot 版本号就是“2016.03”。

EXTRAVERSION 是附加版本信息, NAME 是和名字有关的,一般不使用这两个。

VERSION = 2016
PATCHLEVEL = 03
SUBLEVEL =
EXTRAVERSION =
NAME =

MAKEFLAGS 变量

递归调用​​:在 Makefile 中,可以使用 make命令调用其他 Makefile(通常是子目录中的 Makefile)。

基本格式:

$(MAKE) -C subdir
  • $(MAKE):调用 make命令(推荐使用变量 MAKE而非直接写 make,确保兼容性)。

  • -C <子目录路径>:切换到指定目录后执行其 Makefile。

导出变量​​(传递给子 Makefile):使变量在子 make过程中可见。

export VARIABLE_NAME

禁止导出变量​​(不传递给子 Makefile):阻止变量传递到子 make

unexport VARIABLE_NAME

有两个特殊的变量:“SHELL”和“MAKEFLAGS”,这两个变量除非使用“unexport”声明,否则的话在整个make的执行过程中,它们的值始终自动的传递给子make。

在uboot的主Makefile中有如下代码:

MAKEFLAGS += -rR --include-dir=$(CURDIR)

上述代码使用“+=”来给变量 MAKEFLAGS 追加了一些值,“-rR”表示禁止使用内置的隐含规则和变量定义,“--include-dir”指明搜索路径, ”$(CURDIR)”表示当前目录。

命令输出

uboot 默认编译是不会在终端中显示完整的命令,都是短命令,如图:

调试 uboot 的时候,可以通过设置变量“V=1“来实现完整的命令输出。

顶层 Makefile 中控制命令输出的代码如下:

ifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSEKBUILD_VERBOSE = 0
endififeq ($(KBUILD_VERBOSE),1)quiet =Q =
elsequiet=quiet_Q = @
endif

函数 $(origin V)

  • ​作用​​:origin是 Makefile 内置函数,用于判断变量的来源。

  • ​返回值​​:

    • "command line":表示变量 V是通过命令行传入的(如 make V=1)。

    • 其他可能值:"file"(来自 Makefile)、"environment"(环境变量)、"undefined"(未定义)。

检查 V是否来自命令行:

ifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)
endif

如果用户通过命令行指定了 V(如 make V=1),则将 V的值赋给 KBUILD_VERBOSE。

  • 输入 make V=1→ KBUILD_VERBOSE = 1(显示完整命令)
  • 输入 make V=0→ KBUILD_VERBOSE = 0(静默模式)。

如果 KBUILD_VERBOSE未被定义(用户未传入 V),则默认为 0(静默模式):

ifndef KBUILD_VERBOSEKBUILD_VERBOSE = 0
endif

控制命令回显:

  • 分支1(KBUILD_VERBOSE=1)​​:quiet为空,Q为空 → ​​显示完整编译命令​​(如 gcc -o file.c)。
  • ​​分支2(KBUILD_VERBOSE=0)​​:quiet = quiet_:用于生成简化的日志(如 CC file.o而非完整命令)。Q = @:禁止命令回显,实现静默编译。
ifeq ($(KBUILD_VERBOSE),1)quiet =Q =
elsequiet=quiet_Q = @
endif
  • 如果变量 quiet 为空的话,整个命令都会输出。
  • 如果变量 quiet 为“quiet_”的话,仅输出短版本。
  • 如果变量 quiet 为“silent_”的话,整个命令都不会输出。

静默输出

使用 uboot 的静默输出功能,编译的时候使用“make -s”即可。

顶层 Makefile中相应的代码如下:

 # If the user is running make -s (silent mode), suppress echoing of# commandsifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)quiet=silent_endifelse     # make-3.8xifneq ($(filter s% -s%,$(MAKEFLAGS)),)quiet=silent_endif
endifexport quiet Q KBUILD_VERBOSE

$(filter 4.%,$(MAKE_VERSION))

检测 make版本是否为 4.x

$(filter %s ,$(firstword x$(MAKEFLAGS)))

检测 make -s(make 4.x)

$(filter s% -s%,$(MAKEFLAGS))

检测 make -s(make 3.8x)

quiet=silent_

设置静默模式标志

export quiet Q KBUILD_VERBOSE

确保变量传递给子 make

函数$(filter pattern, text)​​:
​​作用​​:从 text中筛选出符合 pattern的单词。
​​示例​​:

$(filter s%, -s --silent)  # 返回 `-s`(匹配 `s%` 模式)

函数 $(firstword text)​​
​​作用​​:取 text中的第一个单词。
​​示例​​:

$(firstword a b c)  # 返回 `a`

变量$(MAKE_VERSION)​​
​​作用​​:获取当前 make工具的版本号(如 4.2.1)。


变量(MAKEFLAGS)​​
​​作用​​:获取 make命令的选项(如 -s、-j8),通常用于判断是否启用了静默模式。

代码逻辑首先是检查 make版本是否为 4.x​:

ifneq ($(filter 4.%,$(MAKE_VERSION)),) # make-4ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)quiet=silent_endif
else # make-3.8xifneq ($(filter s% -s%,$(MAKEFLAGS)),)quiet=silent_endif
endif

不同版本的 make对 MAKEFLAGS的处理方式不同,因此需要区分:

  • ​​make 4.x​​:

MAKEFLAGS可能包含 s或 --silent,但格式可能不同(如 --jobserver-fds=3,4 -s)。

$(firstword x$(MAKEFLAGS))确保正确解析第一个选项。

  • ​​make 3.8x​​:

直接检查 MAKEFLAGS是否包含 -s或 s%(旧版 make可能使用短选项 -s)。

然后是设置 quiet变量

quiet=silent_

如果检测到 make -s,则设置 quiet=silent_,表示进入静默模式。

后续的编译命令会使用 $(quiet)来决定是否打印详细信息(如 quiet_cmd_CC)。

最后是导出变量:

export quiet Q KBUILD_VERBOSE

export确保 quiet、Q、KBUILD_VERBOSE变量传递给子 make(递归调用时仍然有效)。

Q=@(可能在其他地方定义)用于禁止命令回显。

设置编译结果输出目录

uboot 可以将编译出来的目标文件输出到单独的目录中,在 make 的时候使用“O”来指定输出目录,比如“make O=out”就是设置目标文件输出到 out 目录中。

这么做是为了将源文件和编译产生的文件分开,当然也可以不指定 O 参数,不指定的话源文件和编译产生的文件都在同一个目录内,一般我们不指定 O 参数。

顶层 Makefile 中相关的代码如下:

# kbuild supports saving output files in a separate directory.
# To locate output files in a separate directory two syntaxes are supported.
# In both cases the working directory must be the root of the kernel src.
# 1) O=
# Use "make O=dir/to/store/output/files/"
#
# 2) Set KBUILD_OUTPUT
# Set the environment variable KBUILD_OUTPUT to point to the directory
# where the output files shall be placed.
# export KBUILD_OUTPUT=dir/to/store/output/files/
# make
#
# The O= assignment takes precedence over the KBUILD_OUTPUT environment variable.# KBUILD_SRC is set on invocation of make in OBJ directory
# KBUILD_SRC is not intended to be used by the regular user (for now)
ifeq ($(KBUILD_SRC),)# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
ifeq ("$(origin O)", "command line")KBUILD_OUTPUT := $(O)
endif# That's our default target when none is given on the command line
PHONY := _all
_all:# Cancel implicit rules on top Makefile
$(CURDIR)/Makefile Makefile: ;ifneq ($(KBUILD_OUTPUT),)# Invoke a second make in the output directory, passing relevant variables# check that the output directory actually existssaved-output := $(KBUILD_OUTPUT)KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && /bin/pwd)...
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)

判断“O”是否来自于命令行,如果来自命令行的话条件成立, KBUILD_OUTPUT就为$(O),因此变量 KBUILD_OUTPUT 就是输出目录。

ifeq ("$(origin O)", "command line")

判断 KBUILD_OUTPUT 是否为空。

ifneq ($(KBUILD_OUTPUT),)

调用 mkdir 命令,创建 KBUILD_OUTPUT 目录,并且将创建成功以后的绝对路径赋值给 KBUILD_OUTPUT。至此,通过 O 指定的输出目录就存在了。

KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd

​关键点​

​实现方式​

输出目录指定

O=dir或 export KBUILD_OUTPUT=dir

优先级控制

O=覆盖 KBUILD_OUTPUT

目录切换与递归编译

mkdir -pcd+ 递归调用 make

源码目录判断

ifeq ($(KBUILD_SRC),)

代码检查

uboot 支持代码检查:

  • 使用命令“make C=1”,使能代码检查,检查那些需要重新编译的文件。
  • “make C=2”用于检查所有的源码文件。

顶层 Makefile 中的代码如下:

# Call a source code checker (by default, "sparse") as part of the C compilation.
#
# Use 'make C=1' to enable checking of only re-compiled files.
# Use 'make C=2' to enable checking of *all* source files, regardless of whether they are re-compiled or not.
#
# See the file "Documentation/sparse.txt" for more details, including where to get the "sparse" utility.ifeq ("$(origin C)", "command line")KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRCKBUILD_CHECKSRC = 0
endif

主要判断 C 是否来源于命令行,如果 C 来源于命令行,那就将 C 赋值给变量KBUILD_CHECKSRC,如果命令行没有 C 的话 KBUILD_CHECKSRC 就为 0。

模块编译

在 uboot 中允许单独编译某个模块,使用命令“ make M=dir”即可,旧语法“ make SUBDIRS=dir”也是支持的。

顶层 Makefile 中的代码如下:

# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
ifdef SUBDIRSKBUILD_EXTMOD ?= $(SUBDIRS)
endififeq ("$(origin M)", "command line")KBUILD_EXTMOD := $(M)
endif# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all
ifeq ($(KBUILD_EXTMOD),)_all: all
else_all: modules
endififeq ($(KBUILD_SRC),)# building in the source treesrctree := .
elseifeq ($(KBUILD_SRC)/,$(dir $(CURDIR)))# building in a subdirectory of the source treesrctree := ..elsesrctree := $(KBUILD_SRC)endif
endif
objtree := .
src := $(srctree)
obj := $(objtree)VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))export srctree objtree VPATH

代码解析:

外部模块构建控制​​,支持两种指定外部模块目录的方式:

  • 旧语法:SUBDIRS=$PWD
  • 新语法:M=dir(优先级更高)

​​构建目标选择​​:

  • 普通构建:_all依赖 all目标
  • 外部模块构建:_all依赖 modules目标

​​源码/构建目录处理​​:

  • 检测是否在源码树构建(KBUILD_SRC为空)
  • 设置 srctree和 objtree路径
  • 处理 VPATH(虚拟路径)以便查找源码

​​变量导出​​:将关键目录变量导出供子 make 使用

该段代码主要实现外部模块构建支持和灵活的目录路径处理,是 Linux 内核构建系统的核心功能之一。

获取主机架构和系统

下来顶层 Makefile 会获取主机架构和系统,也就是我们电脑的架构和系统。

代码如下:

HOSTARCH := $(shell uname -m | \sed -e s/i.86/x86/ \-e s/sun4u/sparc64/ \-e s/arm.*/arm/ \-e s/sa110/arm/ \-e s/ppc64/powerpc/ \-e s/ppc/powerpc/ \-e s/macppc/powerpc/ \-e s/sh.*/sh/)HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \sed -e 's/\(cygwin\).*/cygwin/')export HOSTARCH HOSTOS

HOSTARCH(主机架构)的确定:

HOSTARCH := $(shell uname -m | \sed -e s/i.86/x86/ \-e s/sun4u/sparc64/ \-e s/arm.*/arm/ \-e s/sa110/arm/ \-e s/ppc64/powerpc/ \-e s/ppc/powerpc/ \-e s/macppc/powerpc/ \-e s/sh.*/sh/)
  • uname -m:获取机器的硬件名称(如 x86_64armv7lppc64le等)。

  • sed命令:将不同的架构名称统一为构建系统识别的标准名称:

    • i.86→ x86(匹配 i386, i486, i586, i686)

    • sun4u→ sparc64

    • arm.*→ arm(所有ARM架构统一为arm)

    • sa110→ arm(StrongARM处理器归类为ARM)

    • ppc64/ppc/macppc→ powerpc(所有PowerPC架构统一)

    • sh.*→ sh(SuperH架构)

HOSTOS(主机操作系统)的确定

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \sed -e 's/\(cygwin\).*/cygwin/')
  • uname -s:获取操作系统名称(如 LinuxDarwinCYGWIN_NT-10.0)。

  • tr '[:upper:]' '[:lower:]':将结果转换为小写(如 Linux→ linux)。

  • sed命令:特殊处理Cygwin环境:

  • 将 cygwin.*统一为 cygwin(避免版本号差异)。

将 HOSTARCH 和 HOSTOS导出为环境变量,供后续Makefile或子进程使用。

export HOSTARCH HOSTOS

最后导出的目标是: HOSTARCH=x86_64, HOSTOS=linux。

设置目标架构、交叉编译器和配置文件

编 译 uboot 的 时 候 需 要 设 置 目 标 板 架 构 和 交 叉 编 译 器 ,“ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-”就是用于设置 ARCH 和 CROSS_COMPILE。

在顶层Makefile 中代码如下:

# set default to nothing for native builds
ifeq ($(HOSTARCH),$(ARCH))CROSS_COMPILE ?=
endifKCONFIG_CONFIG ?= .config
export KCONFIG_CONFIG

原生构建的交叉编译工具链设置​​:

当检测到主机架构(HOSTARCH)和目标架构(ARCH)相同时,自动清空交叉编译前缀(CROSS_COMPILE)。

ifeq ($(HOSTARCH),$(ARCH))CROSS_COMPILE ?=
endif
  • HOSTARCH:主机CPU架构(由之前代码通过uname -m获取并标准化)。
  • ARCH:目标系统架构(通常在Makefile或配置中指定,如arm、x86)。

如果 HOSTARCH == ARCH,说明是​​原生编译​​(如x86主机编译x86程序),无需交叉编译工具链。

CROSS_COMPILE ?=:清空变量,避免使用类似arm-linux-gnueabi-的前缀。

?=表示仅当变量未定义时才赋值,允许用户在命令行覆盖(如强制指定make CROSS_COMPILE=arm-linux-)。

内核配置文件路径设置​

定义内核配置文件的默认路径,并导出为环境变量。

KCONFIG_CONFIG ?= .config
export KCONFIG_CONFIG
  • KCONFIG_CONFIG:存储配置文件路径(默认为当前目录下的.config)。
  • ?=:如果未通过环境变量或命令行指定,则默认使用.config。
  • export:确保子Makefile或脚本能访问该路径(如scripts/kconfig读取配置)。

调用 scripts/Kbuild.include

主 Makefile 会调用文件 scripts/Kbuild.include 这个文件。

顶层 Makefile 中代码如下:

# We need some generic definitions (do not try to remake the file).
scripts/Kbuild.include: ;
include scripts/Kbuild.include

使用“include”包含了文件 scripts/Kbuild.include,此文件里面定义了很多变量,在 uboot 的编译过程中会用到这些变量,后面有机会再分析。

交叉编译工具变量设置

# Make variables (CC, etc...)AS = $(CROSS_COMPILE)as
# Always use GNU ld
ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)LD = $(CROSS_COMPILE)ld.bfd
elseLD = $(CROSS_COMPILE)ld
endif
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
LDR = $(CROSS_COMPILE)ldr
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump

所有工具均以$(CROSS_COMPILE)为前缀,支持交叉编译(如arm-linux-gnueabi-gcc)

基础工具:

  • AS:汇编器(as)
  • CC:C编译器(gcc)
  • CPP:C预处理器(gcc -E)
  • AR:静态库打包工具(ar)
  • NM:符号表查看工具(nm)

检测是否存在ld.bfd(Binutils的默认链接器),若存在则优先使用:

ifneq ($(shell $(CROSS_COMPILE)ld.bfd -v 2> /dev/null),)LD = $(CROSS_COMPILE)ld.bfd  # 优先尝试GNU bfd版本的ld
elseLD = $(CROSS_COMPILE)ld       # 回退到标准ld
endif

导出其他变量

接下来在顶层 Makefile 会导出很多变量,代码如下:

export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION
export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR
export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS
LD CC
export CPP AR NM LDR STRIP OBJCOPY OBJDUMP
export MAKE AWK PERL PYTHON
export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGSexport KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS
LDFLAGS
export KBUILD_CFLAGS KBUILD_AFLAGS

目标系统配置变量如下:

变量

典型值示例

作用

ARCH

armriscv

目标CPU架构

CPU

cortex-a7

具体CPU型号

BOARD

mx6ull_alientek

开发板名称

VENDOR

freescale

芯片厂商

SOC

mx6

芯片系列

CPUDIR

arch/arm/cpu/armv7

CPU相关代码路径

BOARDDIR

board/freescale/mx6ull

开发板相关代码路径

在 uboot 根目录下有个文件叫做 config.mk,这 7 个变量就是在 config.mk 里面定义的。

make xxx_defconfig 过程

在编译 uboot 之前要使用“make xxx_defconfig”命令来配置 uboot,那么这个配置过程是如何运行的呢?

1. 命令解析阶段​

当执行 make xxx_defconfig时:

  • ​​xxx_defconfig​​:

    对应 configs/目录下的预置配置文件(如 mx6ull_alientek_emmc_defconfig)。

  • ​​Makefile 目标匹配​​:

    顶层 Makefile 中定义了 %config规则,匹配所有以 _defconfig结尾的目标。


​2. Makefile 关键逻辑​

顶层 Makefile 中的相关规则如下:

%config: scripts_basic outputmakefile FORCE $(Q)$(MAKE) $(build)=scripts/kconfig $@
​分解说明​​:
  • ​依赖项​​:

    • scripts_basic:确保 scripts/kconfig目录下的工具(如 confmconf)已编译。

    • outputmakefile:生成输出目录的 Makefile(用于 O=dir构建)。

    • FORCE:强制目标每次执行(即使文件已存在)。

  • ​​实际执行​​:

    • $(build)=scripts/kconfig:调用 scripts/Kbuild.include中的 build变量,切换到 scripts/kconfig目录。

    • $@:展开为 xxx_defconfig(用户输入的目标)。


​3. 配置生成流程​

​步骤 1:复制默认配置​
  • 从 configs/xxx_defconfig复制到 .config(根目录下):

    cp configs/xxx_defconfig .config
​步骤 2:运行配置工具​

调用 scripts/kconfig/conf工具处理配置:

scripts/kconfig/conf --defconfig=.config Kconfig
  • ​​--defconfig​​:指定输入配置文件。

  • ​​Kconfig​​:顶层 Kconfig 文件,定义所有配置选项的层级关系。

​步骤 3:生成头文件​
  • 根据 .config生成 include/config.h和 include/config/auto.conf

  • auto.conf:包含所有配置项的 CONFIG_*变量,供 Makefile 使用。

  • config.h:C 代码可包含的宏定义(如 #define CONFIG_SYS_TEXT_BASE 0x87800000)。


​4. Kconfig 系统的作用​

  • ​层级化配置​​:

    每个子目录的 Kconfig文件定义该模块的配置选项(如 arch/arm/Kconfig定义 ARM 架构相关配置)。

  • ​依赖关系​​:

    通过 depends onselect等关键字确保配置的合理性(例如启用某驱动时自动依赖其总线配置)。

  • ​交互界面​​:

    支持 menuconfigxconfig等图形化配置工具(但 defconfig是非交互模式)。


​5. 输出文件解析​

配置完成后生成的关键文件:

文件路径

作用

.config

最终生效的配置文件(可直接手动修改后运行 make oldconfig同步变更)

include/config.h

供 C 代码使用的宏定义(如 CONFIG_CMD_MMC

include/config/auto.conf

供 Makefile 使用的变量(如 CONFIG_ARM=y

include/config/tristate.conf

三态配置(y/m/n)的状态记录

Makefile.build 脚本分析

scripts_basic目标分析​

编译生成 scripts/basic/fixdep工具,用于处理依赖文件(如 .d文件):

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

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

# Modified for U-Boot
prefix := tpl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := spl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := .
endif
endif

​​路径解析​​:

  • prefix初始为 tpl,尝试匹配 tpl/scripts/basic→ 失败 → 回退到 spl→ 最终 prefix=.。
  • src := scripts/basic(源码目录),obj := scripts/basic(输出目录)。

​​Makefile 包含​​:

  • 通过 include ./scripts/basic/Makefile加载子目录的构建规则。
  • scripts/basic/Makefile中定义 always := fixdep,强制编译 fixdep。

默认目标 __build​​:

依赖 scripts/basic/fixdep,触发 fixdep的编译:

__build: scripts/basic/fixdep@:

%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

可以看出, Makefilke.build 会读取 scripts/kconfig/Makefile 中的内容.

总而言之,一切的一切都是为了最后生成.config文件。

make流程

make xxx_defconfig: 用于配置 uboot,这个命令最主要的目的就是生成.config 文件。

make:用于编译 uboot,这个命令的主要工作就是生成二进制的 u-boot.bin 文件和其他的一些与 uboot 有关的文件,比如 u-boot.imx 等等。

http://www.dtcms.com/a/279570.html

相关文章:

  • 蓝象智联入选江苏金融数据开发主体:隐私计算如何赋能公共数据价值释放?
  • Java :编译器的占位符 T#1
  • 【PTA数据结构 | C语言版】字符串匹配算法
  • es的自定义词典和停用词
  • 天海电子闯上市:业绩增速骤降,“踩雷”合众汽车,存坏账风险
  • Go从入门到精通(22) - 一个简单web项目-统一日志输出
  • 5.浏览本地文件获取路径与文件名称 C#例子 WPF例子
  • Elasticsearch 9.x 升级变化
  • 【安卓笔记】线程基本使用:锁、锁案例
  • Windows安装postgreSQL(保姆级教程)
  • 机床自动化中的“方言翻译官”:EtherNet/IP 转 PROFIBUS DP 实战手记
  • 安全初级(一)
  • 胡志明证券交易所新一代交易系统解决方案——基于美联储利率决议背景下的越南跨境金融基础设施升
  • pycharm恢复出厂设置,可以解决大多数pycharm存在的问题
  • nginx:SSL_CTX_use_PrivateKey failed
  • 怎么 将训练后的词嵌入向量反编译为自然语言
  • AI多因子模型解析白银14年新高:流动性压力与工业避险需求的联动效应
  • 数字化工厂规划-项目启动会汇报材料编写思路
  • Android Studio C++/JNI/Kotlin 示例 二
  • 三相新能源并网系统序阻抗模型——序阻抗分析器IMAnalyzer
  • Docker部署语音转文字(STT)服务并接入Home Assistant
  • linux服务器redis配置开机自启
  • 2025 R3CTF
  • 我的开源项目-AI Agent 配置系统
  • 技嘉UEFI固件SMM漏洞使系统面临固件植入和持久控制风险
  • Oracle 学习笔记
  • 【工具变量】A股上市公司产学研合作及专利数据统计(1998-2023年)
  • TextIn:文档全能助手,让学习效率飙升的良心软件~
  • 《汇编语言:基于X86处理器》第7章 复习题和练习,编程练习
  • RAG索引流程中的文档解析:工业级实践方案与最佳实践