zoukankan      html  css  js  c++  java
  • 三、编译第一步 make xxx_defconfig——Makefile.build 脚本

    3.1 上章分析回顾

    3.1 上章分析出的参数

    3.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

    3.1.2 环境变量

    • KBUILD_DEFCONFIG := sandbox_defconfig
    • KBUILD_KCONFIG =

    3.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

    3.2 Makefile.build 脚本分析

    3.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

    3.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 的定义,变量的赋值在 scriptskconfig'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。如此形成一个树型结构。 

    3.3 小结

      作为uboot 或 内核构建系统对 kconfig 的支持,到这步就算是结束了,其根本目标是产生 .config 隐藏文件,用以记录我们所需要的配置结果。但是在uboot或Linux内核里面,仅仅把配置结果保存在像 .config 这样一个文件中是不够的。在后面的配置中,依然会用到 

  • 相关阅读:
    数据库三范式(转)
    Tyrion中文文档(含示例源码)
    mongodb数据库导入导出恢复
    HTTP协议:Content-Type
    requests爬虫组件
    JS 数组对象
    JS 函数
    javascript window对象属性和方法
    js String对象
    Math对象-JavaScript
  • 原文地址:https://www.cnblogs.com/idyllcheung/p/11206881.html
Copyright © 2011-2022 走看看