1. 程式人生 > 其它 >linux kernel makefile 分析 - 3

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 型別單目標處理

此文不涉及,後面再分析