linux kernel makefile 分析 - 3

上一篇: https://www.cnblogs.com/zhangzhiwei122/p/16025969.html

背景说明

版本:

5.10.0 - 下面分析中 使用的行号,都是 参考 这个 版本的 Makefile 。

在线浏览: https://lxr.missinglinkelectronics.com/linux/Makefile

 

使用场景:

在源码文件夹下面建立一个build 文件夹,然后使用 O=build 

mkdir build

make O=build 

 

191 ~ 1949 部分内容分解

 

 

1、 192 ~ 249 设置了 一些变量

2、251 ~ 322 判断编译类型,

多目标:

mixed-build (混合多目标)

 

单目标:

config-build (config 类型目标,比如 make menuconfig ) 

非config 类型的目标。

             need-config ( 需要 依赖 .config文件的) 

                                    may-sync-config (可以使用 .config文件更新

              single-build ( 单独编译一个目录或一个文件,举例 make kernel/bound.s

3、mixed-build 为 1 时的处理(即 按照顺序,为每个目标启动 一个 sub make ,将多目标转换为 sub make 的单目标)

4、单目标环境设定

5、config 类型的单目标处理

6、非config 类型的单目标处理 ( 本文不涉及,后面分析)

 

1、 192 ~ 249 设置了 一些变量

1.1   198 ~ 213  KBUILD_CHECKSRC  默认为 0 ,可以通过命令行make C=1 或make C=2 设置

 208ifeq ("$(origin C)", "command line")
 209  KBUILD_CHECKSRC = $(C)
 210endif
 211ifndef KBUILD_CHECKSRC
 212  KBUILD_CHECKSRC = 0
 213endif

1.2 215 ~ 226  KBUILD_EXTMOD  和 extmod-prefix ,默认为空,如果是是 make M=dir 编译外部模块时,这两个才有值。

 215# Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the
 216# directory of external module to build. Setting M= takes precedence.
 217ifeq ("$(origin M)", "command line")
 218  KBUILD_EXTMOD := $(M)
 219endif
 220
 221$(if $(word 2, $(KBUILD_EXTMOD)), \
 222        $(error building multiple external modules is not supported))
 223
 224export KBUILD_CHECKSRC KBUILD_EXTMOD
 225
 226extmod-prefix = $(if $(KBUILD_EXTMOD),$(KBUILD_EXTMOD)/)

1.3 228 ~ 248  build_out_of_srctree     srctree   objtree  VPATH  设定(依赖 首次 进入 export 出来的 abs_srctree 和 abs_objtree ) 

 228ifeq ($(abs_srctree),$(abs_objtree))
 229        # building in the source tree
 230        srctree := .
 231        building_out_of_srctree :=
 232else
 233        ifeq ($(abs_srctree)/,$(dir $(abs_objtree)))
 234                # building in a subdirectory of the source tree
 235                srctree := ..
 236        else
 237                srctree := $(abs_srctree)
 238        endif
 239        building_out_of_srctree := 1
 240endif
 241
 242ifneq ($(KBUILD_ABS_SRCTREE),)
 243srctree := $(abs_srctree)
 244endif
 245
 246objtree         := .
 247VPATH           := $(srctree)
 248
 249export building_out_of_srctree srctree objtree VPATH

 

2、251 ~ 322 判断编译类型

通过 5 个变量   mixed-build   config-build   need-config   may-sync-config   single-build  来控制。

 

2.1  259 ~  269 对 可能出现的目标进行了归类。

clean-targets  ,clean 目标,包含  %clean  mrproper  cleandocs

no-dot-config-targets 不依赖  .config 文件的目标.   举例: $(clean-targets) 不依赖 .config 文件  make help  不需要依赖 .config 文件

no-sync-config-targets 不需要使用 .config 来更新 include/config/auto.conf 等文件的目标,举例: $(no-dot-config-targets) (它都不依赖 .config,自然...... )  %install   kernelrelease

single-targets 单个文件或文件夹作目标,采用统配符。 .a 结尾的,   .s 结尾的    /  结尾的, 等等 

 259version_h := include/generated/uapi/linux/version.h
 260old_version_h := include/linux/version.h
 261
 262clean-targets := %clean mrproper cleandocs
 263no-dot-config-targets := $(clean-targets) \
 264                         cscope gtags TAGS tags help% %docs check% coccicheck \
 265                         $(version_h) headers headers_% archheaders archscripts \
 266                         %asm-generic kernelversion %src-pkg dt_binding_check \
 267                         outputmakefile
 268no-sync-config-targets := $(no-dot-config-targets) %install kernelrelease
 269single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/

271 ~ 275 设置 了这些变量的默认值。 默认值相当于选择了   非config 类型的单目标,它  需要  .config 文件,可以使用 .config 文件来更新 include/config/auto.conf 等文件。 

 271config-build    :=
 272mixed-build     :=
 273need-config     := 1
 274may-sync-config := 1
 275single-build    :=

 need-config 变量

默认为1

277 ~ 281 检查是否需要把它置为空。

什么情况下置空呢? 两个条件同时满足:

a: make cmd goals 指定了 no-dot-config-targets目标,有这样的目标【即说明 命令行上面指定了目标;如果命令行没指定目标,还是需要 config的,即need-config = 1】

b: 命令行上目录只有 no-dot-config-targets目标

277ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)

 278        ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)

 279                need-config :=

 280        endif

 281endif

 282

 

 may-sync-config

默认为 1

283 ~ 291 行之间计算它的新值

两种情况下会将它置空

a: 命令行上指定了目标,且指定的目标只有 no-sync-config-targets . may-sync-config 需要置空。283 ~ 287行。

b: KBUILD_EXTMOD 不为空【即,使用此Makefile 编译 外部模块,不能更新 include/config.auto.conf 】,may-sync-config 需要置空。289 ~ 291 行。

283ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)

 284        ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)

 285                may-sync-config :=

 286        endif

 287endif

 288

 289ifneq ($(KBUILD_EXTMOD),)

 290        may-sync-config :=

 291endif

 

 

 config-build

默认为空

下列两个条件同时满足时,置为 1

a: KBUILD_EXTMOD 为空,即表示在编译内核(而非驱动模块),且

b:make cmd goals 里面的目标 包含 config 结尾 (比如 menuconfig,silentconfig,defconfig etc)

 

single-build

默认为空

命令行里面指定了 single-targets 时,置为1.

single-targets 是什么?即是单独的一个目标文件,或目标文件夹

269 行有定义

269single-targets := %.a %.i %.ko %.lds %.ll %.lst %.mod %.o %.s %.symtypes %/

 

举例: make kernel/bound.s

只生成目标 kernel/bound.s

 

 mixed-build

默认为空

下来情况之一,会置为 1

a: make cmd goals 里面指定了 %config + 其他目标。293 ~ 300 行

b: make cmd goals 指定了 single targets + 其他目标 302 ~ 308 行

c: make cmd goals 指定了 clean targets + 其他目标 310 ~ 315 行

d: make 同时指定 install + modules_install 目标 317 ~ 322行

293ifeq ($(KBUILD_EXTMOD),)

 294        ifneq ($(filter %config,$(MAKECMDGOALS)),)

 295                config-build := 1

 296                ifneq ($(words $(MAKECMDGOALS)),1)

 297                        mixed-build := 1

 298                endif

 299        endif

 300endif

 301

 302# We cannot build single targets and the others at the same time

 303ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),)

 304        single-build := 1

 305        ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),)

 306                mixed-build := 1

 307        endif

 308endif

 309

 310# For "make -j clean all", "make -j mrproper defconfig all", etc.

 311ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)

 312        ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),)

 313                mixed-build := 1

 314        endif

 315endif

 316

 317# install and modules_install need also be processed one by one

 318ifneq ($(filter install,$(MAKECMDGOALS)),)

 319        ifneq ($(filter modules_install,$(MAKECMDGOALS)),)

 320                mixed-build := 1

 321        endif

 322endif

 

3、324  ~  339  mixed-build 为 1 时的处理(单目标时,这段不可见)

 324ifdef mixed-build
 325# ===========================================================================
 326# We're called with mixed targets (*config and build targets).
 327# Handle them one by one.
 328
 329PHONY += $(MAKECMDGOALS) __build_one_by_one
 330
 331$(MAKECMDGOALS): __build_one_by_one
 332        @:
 333
 334__build_one_by_one:
 335        $(Q)set -e; \
 336        for i in $(MAKECMDGOALS); do \
 337                $(MAKE) -f $(srctree)/Makefile $$i; \
 338        done
 339
 340else # !mixed-build

 

4、341 ~ 585  单目标环境设定

这部分 代码  比较多,就不贴代码分析了。

4.1   342 行  引入 scripts/Kbuild.include ,里面定义了很多辅助函数 , 比如  cmd  filechk   if_changed  

4.2  344  ~  347  export   VERSION  PATCHLEVEL   SUBLEVEL  KERNELRELEASE   KERNELVERSION 

4.3  349 引入  scripts/subarch.include  ,里面包含函数判断  编译主机  的arch,放在 SUBARCH  (替补 arch),

4.4  369 行,如果命令行没有 指定  ARCH=xx,则  ARCH赋值为 4.3 中得到的 SUBARCH

4.5  370 ~ 394 ,由 ARCH 得到 SRCARCH 源码文件夹下面的 ARCH 文件夹名称

4.6 396 ~ 403  KCONFIG_CONFIG 默认为 .config    KBUILD_DEFCONFIG 默认为 defconfig   CONFIG_SHELL 默认为 sh

4.7 405 ~ 424   构建编译机器 上面的一些工具时使用   KBUILD_HOSTCFLAGS        KBUILD_HOSTCXXFLAGS         KBUILD_HOSTLDFLAGS          KBUILD_HOSTLIBS

4.8  426 ~  465  定义了 make 工具需要的 变量

4.9  467  ~  519  各种 flags 变量的定义和导出。 KBUILD_CFLAGS   CFLAGS_KERNEL  CFLAGS_MODULE  KBUILD_CFLAGS_KERNEL  KBUILD_CFLAGS_MODULE ( 5 中类型定义差别?暂未知)   KBUILD_AFLAGS       KBUILD_LDFLAGS 

4.10  530 ~ 560  设置 config 类型单目标 和  其他 类型单目标 都依赖的 目标( 比如  outputmakefile   scripts_basic ,在下面的 5 中被依赖)

4.11  562  ~  579  处理 如果编译器是 clang 时的情况,在  KBUILD_CFLAGS    KBUILD_AFLAGS 上面追加参数,export  CLANG_FLAGS .  

 

5、config 类型单目标处理 587 ~ 603

595  include  /arch/$(SRCARCH)/Makefile  ,包含它是为了得到 这个 arch (比如aarch64)的默认配置文件,放在KBUILD_DEFCONFIG中,

           make  defconfig 目标是 config 目标,会走到这儿,将defconfig 目标传递给  scripts/kconfig 目录下的 Makefile ,它需要使用  KBUILD_DEFCONFIG 变量。

598 和 601 分开,单纯是因为  601 处的 %config 无法匹配 到  598 处的 config 。如果不想要可读性,可以合二为一,整成  %onfig 这样的目标。

598 和 601 处,指定  config 目标依赖 outputmakefile   scripts_basic   ,先要完成这两个依赖才可以 启动下面的 sub make .

 587ifdef config-build
 588# ===========================================================================
 589# *config targets only - make sure prerequisites are updated, and descend
 590# in scripts/kconfig to make the *config target
 591
 592# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
 593# KBUILD_DEFCONFIG may point out an alternative default configuration
 594# used for 'make defconfig'
 595include arch/$(SRCARCH)/Makefile
 596export KBUILD_DEFCONFIG KBUILD_KCONFIG CC_VERSION_TEXT
 597
 598config: outputmakefile scripts_basic FORCE
 599        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 600
 601%config: outputmakefile scripts_basic FORCE
 602        $(Q)$(MAKE) $(build)=scripts/kconfig $@
 603
 604else #!config-build

 

6、非config 类型单目标处理

此文不涉及,后面再分析。

604 ~ 1949 单个编译目标处理 - 分解

https://www.cnblogs.com/zhangzhiwei122/p/16027368.html

 

posted @ 2022-03-19 16:39  张志伟122  阅读(626)  评论(0编辑  收藏  举报