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