四、編譯第一步 make xxx_defconfig——Makefile.build 腳本


4.1 上章分析出的參數

4.1.1 變量

  • MAKECMDGOALS = xxx_defconfig
  • KBUILD_EXTMOD =
  • version_h := include/generated/version_autogenerated.h
  • timestamp_h := include/generated/timestamp_autogenerated.h
  • no-dot-config-targets := clean clobber mrproper distclean help %docs check% coccicheck ubootversion backup tests
  • config-targets := 1
  • mixed-targets := 0
  • dot-config := 1
  • KBUILD_SRC =
  • build := -f ./scripts/Makefile.build obj

4.1.2 環境變量

  • KBUILD_DEFCONFIG := sandbox_defconfig
  • KBUILD_KCONFIG =

4.1.3 需要進行分析的地方

(1)scripts_basic 目標執行的命令

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

(2)%config 目標執行的命令

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

  由以上分析可以知道,執行 make xxx_defconfig 需要執行 Makefile.build 腳本,第一次傳入的參數為 scripts/basic,第二次傳入的參數為 scripts/kconfig xxx_defconfig

4.2 Makefile.build 腳本分析

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

  make -f scripts/Makefile.build obj=scripts/basic 命令由於沒有指定目標,所以會在 script/Makefile.build 中處理默認目標__build:

  114~119 行

1 # We keep a list of all modules in $(MODVERDIR)
2 
3 __build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
4      $(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
5      $(subdir-ym) $(always)
6     @:

  同時,在scripts/Makefile.build 中會包含進 scripts/basic 目錄下的 Kbuild/Makefile,所以該make命令的實際效果是去編譯出 scripts/basic 目錄下的三個 host program,也就是 fixdep docproc和hash。

  56 到 59 行 包含

1 # The filename Kbuild has precedence over Makefile
2 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
3 kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
4 include $(kbuild-file)

  什么是host program?一般認為是和內核無關,但是要在編譯過程中使用的工具程序。關於這些程序的編譯,參考 scripts/Makefile.host 文件,以及 Documentation/kbuild/makefile.txt 文件中關於 host program 的這一節。

  scripts/basic 文件中的 Makefile

1 hostprogs-y    := fixdep
2 always        := $(hostprogs-y)
3 
4 # fixdep is needed to compile other host programs
5 $(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep

4.2.2 make -f ./scripts/Makefile.build obj=scripts/kconfig xxx_defconfig

  文件 scripts/Makefile.build 會包含obj變量所指代目錄內的 Makefile的,在這里就是 script/kconfig/Makefile。

  所以這里得查看這個文件:120~125行

1 %_defconfig: $(obj)/conf
2     $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
3 
4 # Added for U-Boot (backward compatibility)
5 %_config: %_defconfig
6     @:

  在這里,xxx_defconfig 需要依賴於同目錄下的conf程序。這其實就是 Linux 內核進行Kconfig操作的主程序之一了,類似的還有mconf,qconf和gconf等。他們其實都是 host program。關於它們是如何被編譯出來的,還請參見 scripts/kconfig/Makefile 文件,主要是借助於bison,flex和gperf三個工具來生成c源程序文件,之后再編譯出來的。這部分和我們Linux內核的構建主題關系不大.

  看一下 kconfig 的定義,變量的賦值在 scripts\kconfig'Makefile 中

1 ifdef KBUILD_KCONFIG
2 Kconfig := $(KBUILD_KCONFIG)
3 else
4 Kconfig := Kconfig
5 endif

  由於變量 KBUILD_KCONFIG 在arm架構Makefile中沒有被定義,所以 Kconfig 被定義成 arch/arm/kconfig,所以這個目標的規則就簡化成:

1 /* silent 是確定是否執行靜態編譯 */
2 ifeq ($(quiet),silent_)
3 silent := -s
4 endif
5 
6 $(obj)/conf -s --defconfig=arch/arm/configs/xxx_defconfig arch/arm/Kconfig

  這個命令就是讀取並解析以 arch/arm/Kconfig 為首的內核功能選項配置文件,並將文件 arch/arm/configs/s3c2410_defconfig 所設置的默認值分配給對應的所有選項,最終生成隱藏配置文件 .config。

  在 uboot 或內核開始真正編譯之前,構建系統會以 .config 文件為藍本生成 include/config/auto.conf 文件,這個文件的格式和 .config類似,這個文件會在頂層 以及 scripts/Makefile.build 文件中被直接包含進來,所以這些變量其實就成了 GNU Make 的變量。而uboot 或 內核各子目錄中的 Kbuild/Makefile 就可以使用這些變量的定義,來決定是否將該目錄下對應的代碼功能直接編譯到內核里面(這些變量取值為"y")、編譯成模塊(取值為"m")或者干脆不進行編譯(取值為"空")。可以想見,如果選擇不編譯,那出來的Linux內核就不會有對應的功能。

   在 arch/arm/Kconfig 文件中,我們可以查看到添加一塊開發板需要大致更改的地方:

  • arch/arm/cpu 目錄
  • board/  目錄

  在配置的時候,配置工具首先會解析架構平台目錄下的 Kconfig,這就是所謂和平台相關的主Kconfig。主Kconfig文件會包含其他目錄的Kcofnig文件,而其他目錄的Kconfig又會包含其他各子目錄的 Kconfig。如此形成一個樹型結構。 

4.3 小結

  作為uboot 或 內核構建系統對 kconfig 的支持,到這步就算是結束了,其根本目標是產生 .config 隱藏文件,用以記錄我們所需要的配置結果。但是在uboot或Linux內核里面,僅僅把配置結果保存在像 .config 這樣一個文件中是不夠的。在后面的配置中,依然會用到 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM