07_Uboot顶层Makefile分析_make xxx_defconfig

news2024/11/24 20:33:04

目录

make xxx_defconfig 过程

Makefile.build 脚本分析

scripts_basic 目标对应的命令

%config 目标对应的命令


make xxx_defconfig 过程

在编译uboot之前要使用"make xxx_defconfig"命令来配置uboot,那么这个配置过程是如何运行的呢?在顶层Makefile中有如下代码:

第422行定义了变量version_h,这变量保存版本号文件,此文件是自动生成的。文件include/generated/version_autogenerated.h内容如图所示: 

 第423行定义了变量timestamp_h,此变量保存时间戳文件,此文件也是自动生成的。文件include/generated/timestamp autogenerated.h内容如图所示:

第425行定义了变量no-dot-config-targets。

第429行定义了变量config-targets,初始值为0。

第430行定义了变量mixed-targets,初始值为0。

第431行定义了变量dot-config,初始值为1。

第433行将MAKECMDGOALS中不符合no-dot-config-targets的部分过滤掉,剩下的如果不为空的话条件就成立。MAKECMDGOALS是make的一个环境变量,这个变量会保存你所指定的终极目标列表,比如执行"make mx6ull_alientek_emme_defconfig",那么MAKECMDGOALS就为 mx6ull_alientek_emme_defconfig。很明显过滤后为空,所以条件不成立,变量 dot-config依旧为1。

第439行判断KBUILD_EXTMOD是否为空,如果KBUILD_EXTMOD为空的话条件成立,经过前面的分析,我们知道KBUILD_EXTMOD为空,所以条件成立。

第440行将MAKECMDGOALS中不符合"config"和“%config"的部分过滤掉,如果剩下的部分不为空条件就成立,很明显此处条件成立,变量config-targets=1。

第442行统计MAKECMDGOALS中的单词个数,如果不为1的话条件成立。此处调用Makefile 中的words函数来统计单词个数,words 函数格式如下:

$(words <text>)

很明显, MAKECMDGOALS的单词个数是1个,所以条件不成立, mixed-targets继续为0。综上所述,这些变量值如下:

config-targets = 1

mixed-targets = 0

dot-config=1

第448行如果变量mixed-targets为1的话条件成立,很明显,条件不成立。

第473行,没有目标与之匹配,所以不执行。

第465行如果变量config-targets为1的话条件成立,很明显,条件成立,执行这个分支。

第473行,没有目标与之匹配,所以不执行。

第476行,有目标与之匹配,当输入"make xxx_defconfig"的时候就会匹配到%config目标,目标“%config”依赖于scripts_basic、outputmakefile和FORCE。FORCE在顶层Makefile的1610 行有如下定义:

可以看出FORCE是没有规则和依赖的,所以每次都会重新生成FORCE。当FORCE作为其他目标的依赖时,由于FORCE总是被更新过的,因此依赖所在的规则总是会执行的。

依赖scripts_basic和outputmakefile在顶层Makefile中的内容如下:

第408行,判断KBUILD_SRC是否为空,只有变量KBUILD_SRC不为空的时候outputmakefile才有意义,经过我们前面的分析KBUILD_SRC为空,所以outputmakefile无效。只有 scripts_basic是有效的。

第396-398行是scripts_basic的规则,其对应的命令用到了变量Q、MAKE和build,其中:

Q=@或为空

MAKF=make

 

变量build是在scripts/Kbuild.include文件中有定义,定义如下: 

 从示例代码可以看出build--f$(srctree)/scripts/Makefile.build obj,经过前面的分析可知,变量srctree为”.”,因此:

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

 scripts_basic展开以后如下:

scripts_basic:

@make-f./scripts/Makefile.build obj=scripts/basic  //也可以没有@,视配置而定

@rm-f.tmp quiet recordmcount  //也可以没有@

 

Scripts_basic会调用文件./scripts/Makefile.build,这个我们后面在分析。 

接着回到示例代码顶层Makefile中的%config处,内容如下: 

%config: scripts_basic outputmakefile FORCE

$(Q)$(MAKE) S(build)=scripts/kconfig $@

 将命令展开就是:

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

同样也跟文件./scripts/Makefile.build有关,使用如下命令配置uboot,并观察其配置过程: 

 从图可以看出,我们的分析是正确的,接下来就要结合下面两行命令重点分析一下文件scripts/Makefile.build。

1.scripts_basic 目标对应的命令

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

2.%config 目标对应的命令

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

 

 

Makefile.build 脚本分析

从上可知,"make xxx_defconfig"配置 uboot 的时候如下两行命令会执行脚本

scripts/Makefile.build

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

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

scripts_basic 目标对应的命令

scripts_basic 目标对应的命令为:@make -f ./scripts/Makefile.build obj=scripts/basic。打开文

scripts/Makefile.build,有如下代码:

 第 9 行定义了变量 prefix 值为 tpl

10 行定义了变量 src,这里用到了函数 patsubst,此行代码展开后为:

 $(patsubst tpl/%,%, scripts/basic)

 patsubst 是替换函数,格式如下:

 $(patsubst <pattern>,<replacement>,<text>)

 此函数用于在 text 中查找符合 pattern 的部分,如果匹配的话就用 replacement 替换掉。

pattenr 是可以包含通配符“%”,如果 replacement 中也包含通配符“%”,那么 replacement 中的

这个“%”将是 pattern 中的那个“%”所代表的字符串。函数的返回值为替换后的字符串。因

此,第 10 行就是在“scripts/basic”中查找符合“tpl/%”的部分,然后将“tpl/”取消掉,但是

scripts/basic”没有“tpl/”,所以 src= scripts/basic

11行判断变量objsrc是否相等,相等的话条件成立,很明显,此处条件成立。

12行和第9行一样,只是这里处理的是“spl”,“scripts/basic”里面也没有“spl/”,所以

src继续为scripts/basic

15行因为变量objsrc相等,所以prefix=.

继续分析scripts/Makefile.build,有如下代码:

kbuild-dir 展开后为:

$(if $(filter /%, scripts/basic), scripts/basic, ./scripts/basic)

因为没有以“/”为开头的单词,所以$(filter /%, scripts/basic)的结果为空,kbuild dir=./scripts/basic。

kbuild-file 展开后为:

$(if $(wildcard ./scripts/basic/Kbuild), ./scripts/basic/Kbuild, ./scripts/basic/Makefile)

因为 scrpts/basic目录中没有 Kbuild 这个文件,所以 kbuild-file= ./scripts/basic/Makefile。最 后将 59 行展开,即:

include ./scripts/basic/Makefile

也就是读取 scripts/basic 下面的 Makefile 文件。

继续分析 scripts/Makefile.build,如下代码:

 __build 是默认目标,因为命令“@make -f ./scripts/Makefile.build obj=scripts/basic”没有指

定目标,所以会使用到默认目标:__build。在顶层 Makefile 中,KBUILD_BUILTIN 1,

KBUILD_MODULES 0,因此展开后目标__build 为:

__build:$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always) @:

可以看出目标__build 5个依赖:builtin-targetlib-targetextra-ysubdir-ym always

5个依赖的具体内容我们就不通过源码来分析了,直接在 scripts/Makefile.build 中输入图所示内容,将这5个变量的值打印出来:

执行如下命令:

make mx6ull_14x14_ddr512_emmc_defconfig V=1

从上图可以看出,只有 always 有效,因此__build 最终为:

__build: scripts/basic/fixdep @:

__build 依赖于 scripts/basic/fixdep,所以要先编译 scripts/basic/fixdep.c,生成 fixdep,前面

已经读取了scripts/basic/Makefile 文件。

综上所述,scripts_basic目标的作用就是编译出scripts/basic/fixdep 这个软件。

 

%config 目标对应的命令

 %config 目标对应的命令为: @make -f ./scripts/Makefile.build obj=scripts/kconfig

xxx_defconfig,各个变量值如下:

src= scripts/kconfig

kbuild-dir = ./scripts/kconfig

kbuild-file = ./scripts/kconfig/Makefile

include ./scripts/kconfig/Makefile

可以看出,Makefilke.build 会读取 scripts/kconfig/Makefile 中的内容,此文件有如下所示内容:

目标%_defconfig 刚好和我们输入的 xxx_defconfig 匹配,所以会执行这条规则。依赖为

$(obj)/conf,展开后就是 scripts/kconfig/conf。接下来就是检查并生成依赖 scripts/kconfig/conf

conf 是主机软件,到这里我们就打住,不要纠结 conf 是怎么编译出来的,否则就越陷越深,太

绕了,像 conf 这种主机所使用的工具类软件我们一般不关心它是如何编译产生的。如果一定要

看是 conf 是怎么生成的,可以输入如下命令重新配置 uboot,在重新配置 uboot 的过程中就会

输出 conf 编译信息。

 make distclean

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_

defconfig V=1

 得到 scripts/kconfig/conf 以后就要执行目标%_defconfig 的命令:

$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

相关的变量值如下:

silent=-s 或为空

SRCARCH=..

Kconfig=Kconfig

将其展开就是:

@ scripts/kconfig/conf --defconfig=arch/../configs/xxx_defconfig Kconfig

上述命令用到了 xxx_defconfig 文件,比如 mx6ull_alientek_emmc_defconfig。这里会将

mx6ull_alientek_emmc_defconfig 中的配置输出到.config 文件中,最终生成 uboot 根目录下

.config 文件。

这个就是命令make xxx_defconfig 执行流程,总结一下如图所示:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/489476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++类模板

类模板和函数模板语法相似&#xff0c;在声明模板template后面加类&#xff0c;此类称为类模板. 类模板作用&#xff1a; 建立一个通用类&#xff0c;类中的成员 数据类型可以不具体制定&#xff0c;用一个虚拟的类型来代表。 语法&#xff1a; template<typename T> …

深入解析PyTorch中的模型定义:原理、代码示例及应用

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【基础算法】大数运算问题

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

Python高光谱遥感数据处理与机器学习(最新的技术突破讲解和复现代码)

将高光谱技术与Python编程工具结合起来&#xff0c;聚焦高频技术难点&#xff0c;明确开发要点&#xff0c;快速复现高光谱数据处理和分析过程&#xff0c;并对每一行代码进行解析&#xff0c;对学习到的理论和方法进行高效反馈。实践篇&#xff0c;通过高光谱矿物识别&#xf…

了解这个项目进度跟踪管理工具,轻松掌握项目进度

白天开会晚上干活的PM和战场上的将军没有区别&#xff0c;产品研发如同组团杀敌&#xff0c;团队配合最为重要。Zoho Projects项目管理工具&#xff0c;适用于各种规模和需求的公司。 一、需求管理 在项目中&#xff0c;我们使用它Zoho收集整理各方反馈&#xff0c;快速处理工单…

自媒体达人养成计划(ChatGPT+new bing)

本节课我们来探索如何使用GPT帮助我们成为自媒体达人&#xff0c;快速赚到一个小目标&#xff01;在此之前&#xff0c;我们需要先做些准备工作~ 首先是平台选取&#xff0c;写文章第一件事就是要保证内容的有效性和准确性&#xff0c;不然就成为营销号了嘛&#xff0c;所以我…

5---最长回文字串

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s “babad” 输出&#xff1a;“bab” 解释&#xff1a;“aba” 同样是符合题意的答案。 示例 2&…

改进沙猫群优化算法(ISCSO)-附代码

改进沙猫群优化算法(ISCSO) 文章目录 改进沙猫群优化算法(ISCSO)1.沙猫群优化算法2. 改进沙猫群优化算法2.1 混沌映射初始化2.2 引入互利共生策略2.3 引入莱维飞行策略 3.实验结果4.参考文献5.Matlab代码6.Python代码 摘要&#xff1a;对沙猫群优化算法进行改进。在改进的沙猫群…

Vue.js 教程---菜鸟教程

文章目录 Vue.js 教程Vue.js 安装Vue.js 起步Vue.js 模板语法插值指令用户输入过滤器缩写 Vue.js 条件语句Vue.js 循环语句Vue.js 计算属性Vue.js 监听属性Vue.js样式绑定 Vue.js 教程 本教程主要介绍了 Vue2.x 版本的使用 第一个实例&#xff1a; <body> <div id&…

Linux 信号学习

Linux 信号学习 信号量的基本概念信号产生的条件信号如何被处理信号的异步特质 信号的分类可靠信号/不可靠信号实时信号/非实时信号 常见信号与默认行为信号处理signal() 函数sigaction()函数 向进程发送信号kill() 函数raise() 函数 alarm()和pause()函数alarm() 定时函数paus…

玩转传感器----理解时序和数据采集(DHT11)

该文章以DHT11模块进行分析 目录 1.模块复位&#xff08;时序图&#xff09; 2.DHT11的应答信号 3.读取1bit数值&#xff08;比较高电平的时间是否大于40us&#xff09; 4.读取一个字节 5.把读取的字节放入单片机 6. 寄存器设置IO口方向 1.模块复位&#xff08;时序图&a…

22.Java多线程

Java多线程 一、进程和线程 进程是程序的一次动态执行过程&#xff0c;它需要经历从代码加载&#xff0c;代码执行到执行完毕的一个完整的过程&#xff0c;这个过程也是进程本身从产生&#xff0c;发展到最终消亡的过程。多进程操作系统能同时达运行多个进程&#xff08;程序…

使用Python接口自动化测试post请求和get请求,获取请求返回值

目录 引言 请求接口为Post时&#xff0c;传参方法 获取接口请求响应数据 引言 我们在做python接口自动化测试时&#xff0c;接口的请求方法有get,post等&#xff1b;get和post请求传参&#xff0c;和获取接口响应数据的方法&#xff1b; 请求接口为Post时&#xff0c;传参方法…

C++系列二:数据类型

C数据类型 1. 原始类型2. 复合类型3. 类型转换3.1 隐式类型转换3.2 显式类型转换 4. 总结&#xff08;手稿版&#xff09; 1. 原始类型 C 中的原始类型包括整型&#xff08;integral types&#xff09;、浮点型&#xff08;floating-point types&#xff09;、字符型&#xff…

涨薪60%,从小厂逆袭,坐上美团技术专家(面经+心得)

前言 大多数情况下&#xff0c;程序员的个人技能成长速度&#xff0c;远远大于公司规模或业务的成长速度。所以&#xff0c;跳槽成为了这个行业里最常见的一个词汇。 实际上&#xff0c;跳槽的目的无非是为了涨薪或是职业发展&#xff0c;我也不例外。普通本科毕业后&#xf…

计算机网络基础知识(一)计算机发展史、网络设备、网络结构及拓扑

文章目录 01 | 网络设备02 | 网络结构 && 拓扑 网络发展史可以追溯到20世纪60年代&#xff0c;当时美国国防部高级研究计划署&#xff08;ARPA&#xff09;启动了一个名为 ARPANET 的项目&#xff0c;旨在建立军事目的的分布式通信网络&#xff0c;使得网络中的任何一台…

【redis】redis红锁Redlock算法和底层源码分析

【redis】redis红锁Redlock算法和底层源码分析 文章目录 【redis】redis红锁Redlock算法和底层源码分析前言一、当前代码为8.0版&#xff0c;接上一步分布式锁的主要考点lock加锁关键逻辑unlock解锁关键逻辑 二、redis分布式锁-Redlock红锁主页说明:目前所写的分布式锁还有什么…

c++自学笔记(陆续更新)

本笔记为从菜鸟教程边学边记录的笔记---》C 教程 | 菜鸟教程 面向对象程序设计 封装&#xff08;Encapsulation&#xff09;&#xff1a;封装是将数据和方法组合在一起&#xff0c;对外部隐藏实现细节&#xff0c;只公开对外提供的接口。这样可以提高安全性、可靠性和灵活性。…

C语言入门教程||C语言 头文件||C语言 强制类型转换

C语言 头文件 头文件是扩展名为 .h 的文件&#xff0c;包含了 C 函数声明和宏定义&#xff0c;被多个源文件中引用共享。有两种类型的头文件&#xff1a;程序员编写的头文件和编译器自带的头文件。 在程序中要使用头文件&#xff0c;需要使用 C 预处理指令 #include 来引用它…

USART串口接收

文章目录 运行环境&#xff1a;1.1 串口接收代码分析1)开启接收中断和空闲中断2)接收存储变量声明和定义3)中断处理函数 2.1实验效果 运行环境&#xff1a; ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 usb转串口 杜邦线转4pin 1.1 串口接收…