u-boot通过 #include <common.h> 间接包含 autoconf.h 的实现机制

在 U-Boot 中,通过 #include <common.h> 间接包含 autoconf.h 的实现机制涉及多个层级配置文件的协作和预处理过程。

(1) common.h 的枢纽作用
  • common.h 的位置:位于 include/common.h,是 U-Boot 的通用头文件,几乎被所有源码文件包含。

  • 关键包含语句

#include <config.h>  // 引入板级配置头文件
(2) config.h 的动态生成
  • 生成过程config.h 由编译系统自动生成,位于 include/config.h。其内容包含:

    /* Automatically generated - do not edit */
    #include <configs/<CONFIG_SYS_CONFIG_NAME>.h>  // 板级配置头文件
    

    运行

    其中 <CONFIG_SYS_CONFIG_NAME> 由 .config 中的 CONFIG_SYS_CONFIG_NAME 定义(如 imx8mm_evk)。

(3) 板级配置头文件的桥接
  • configs/<board>.h 的作用
    该文件(如 configs/imx8mm_evk.h)包含对 autoconf.h 的显式或隐式引用:

    #include <asm/arch/imx-regs.h>  // 间接包含 autoconf.h
    

    运行

    某些架构的代码会通过层级包含最终引入 include/generated/autoconf.h


2. autoconf.h 的生成与传播

(1) 生成过程
  • 来源autoconf.h 由 Kconfig 系统生成,位于 include/generated/autoconf.h。其内容为所有 CONFIG_* 宏的 C 语言定义:

    #define CONFIG_SPL_BUILD 1
    #define CONFIG_ARM 1
    

    这些宏源自 .config 文件。

(2) 预处理器级联展开
  • 编译预处理
    当编译器处理 common.h 时,会递归展开所有包含的头文件。例如:
    • common.h → config.h → configs/imx8mm_evk.h → asm/arch/imx-regs.h → ... → generated/autoconf.h
    • 此过程使得 autoconf.h 中的宏被间接注入到所有源码中。
(3) 编译参数传递
  • 动态宏的注入
    某些宏(如 CONFIG_SPL_BUILD)可能未被写入 autoconf.h,而是通过编译器的 -D 参数动态传递:

    CFLAGS += -DCONFIG_SPL_BUILD
    

    这些宏会在预处理阶段被添加到代码中。


3. 配置系统的代码生成支持

(1) autoconf.mk 的生成
  • 生成逻辑
    编译系统通过以下步骤生成 include/autoconf.mk

    1. 调用预处理器解析 common.h,提取所有宏定义(包括 autoconf.h 中的内容)。
    2. 使用 tools/scripts/define2mk.sed 脚本将宏转换为 Makefile 格式。
    3. 结果写入 autoconf.mk,供 Makefile 使用。
  • 关键命令

    cpp -dM include/common.h | sed -n -f tools/scripts/define2mk.sed > autoconf.mk
    

    运行

    其中 cpp -dM 会递归处理所有包含的头文件,包括 autoconf.h

(2) 编译时宏生效
  • Makefile 包含 autoconf.mk
    顶层 Makefile 显式包含 autoconf.mk,使其中的宏(如 CONFIG_SPL=y)影响编译条件:

    include include/autoconf.mk
    

    这使得代码中的条件编译(如 #ifdef CONFIG_SPL)能够正确响应配置。

### Linux 中使用 Vim 编辑器进行 C 语言开发 #### 创建项目目录结构 为了更好地管理代码,在开始编码之前可以先创建合适的文件夹来存储源码。假设当前操作是在 Ubuntu 终端环境下: ```bash pashan@ubuntu:~$ mkdir pu2410 pashan@ubuntu:~$ cd pu2410/ pashan@ubuntu:~/pu2410$ mkdir day01 pashan@ubuntu:~/pu2410$ cd day01 ``` 上述命令依次创建了一个名为 `pu2410` 的主文件夹及其子文件夹 `day01`,用于存放当天的学习材料。 #### 使用 Vim 编写简单的 C 程序 进入目标文件夹后,可以通过下面这条指令启动 Vim 并新建一个 `.c` 文件作为 C 源程序: ```bash pashan@ubuntu:~/pu2410/day01$ vi 01_hello.c ``` 在 Vim 内部模式下输入以下内容完成第一个简单示例——打印问候语句到控制台: ```c #include <stdio.h> // 引入标准输入输出库,以便使用 printf 函数 int main(){ printf("Hello World\n"); printf("Hello China\n"); return 0; } ``` 这段代码定义了两个字符串常量并通过调用 `printf()` 输出至屏幕;最后返回值 `0` 表明正常终止[^2]。 #### 安装 GCC 编译工具链 如果环境中尚未配置好必要的编译环境,则需提前安装 GNU Compiler Collection (GCC),它支持多种编程语言包括但不限于 C/C++ 。对于 Red Hat 类似的系统来说,可通过 YUM 包管理器快速部署所需组件: ```bash yum -y install gcc gcc-c++ autoconf make ``` 而对于 Debian 或者其衍生版本比如 Ubuntu ,则应该采用 APT 方式获取相同功能集: ```bash sudo apt-get update && sudo apt-get install build-essential ``` #### 编译与执行 当确认已经具备有效的编译条件之后,就可以尝试把刚才保存下来的纯文本形式的源代码转换成机器能够识别的目标格式即二进制可执行文件啦! ```bash gcc 01_hello.c ``` 这里省略掉了 `-o` 参数指定最终产物的名字,默认情况下生成的是叫做 `a.out` 的文件。接着只需要键入 `./a.out` 就能看到预期的效果咯[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值