uboot if_changed函数
u-boot编译过程分析
u-boot.lds: $(LDSCRIPT) prepare FORCE
$(call if_changed_dep,cpp_lds)
u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE
有类似
$(call if_changed,u-boot__)if_changed
之类的函数出现 if_changed 定义在 scripts/Kbuild.include 中: # Execute command if command has changed or prerequisite(s) are updated.
#
if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd) # Execute the command and also postprocess generated .d dependencies file.
if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
@set -e; \
$(echo-cmd) $(cmd_$(1)); \
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
rm -f $(depfile); \
mv -f $(dot-target).tmp $(dot-target).cmd) if_changed 函数在当发现规则的依赖有更新,或者是对应目标的命令行参数发生改变时($(strip $(any-prereq) $(arg-check)) 语句结果不为空),执行后面的语句。 这里看到 arg-check 和 any-prereq 两个变量,它们分别定义在 scripts/Kbuild.include 的 188 和 200 行中:
arg-check = $(
strip
$(
filter-out
$(cmd_
$(1)
), $(cmd_
$@
)) \
$(
filter-out
$(cmd_
$@
), $(cmd_
$(1)
)) )
... ...
any-prereq = $(
filter-out
$(PHONY)
,
$?
) $(
filter-out
$(PHONY)
$(
wildcard
$^
),
$^
)
在 any-prereq 中,首先使用 $(filter-out $(PHONY),$?) 将 $? 中的所有伪目标去掉,不然可能会将
FORCE 这种目标也带进来,如果此时返回非空,那么说明有比目标还要新的依赖文件。$(wildcard $^)
匹配当前目录下的所有依赖文件(已经存在的),然后再使用 $(filter-out $(PHONY) $(wildcard $^),$^)
将伪目标以及当前目录下匹配的文件列表从整个 $^ 列表中删除,如果返回不为空,那么说明某些依赖文件不存在,也就是说这些不存在的依赖文件还没生成
-- 这是因为某些依赖文件需要在编译时才会生成。
$(call if_changed,u-boot__)
中,$(1) 就是u-boot__
,所以 $(cmd_$(1) 就是表示 cmd_u-boot__
这个变量可以在 Makefile.build 中看到定义。它实际上表示的是这一次编译文件时所用到的命令行参数。$@ 表示目标文件,从上面叙述可知,它就是 $(obj)/%.o 。比如编译 init/main.o ,那么 $(cmd_$@) 就是表示 $(cmd_init/main.o),而在 init/.main.o.cmd 文件中我们看到了 cmd_init/main.o 用来保存着上次编译的参数。在 arg-check 中,首先使用 $(filter-out $(cmd_$(1)), $(cmd_$@)) 将上一次的编译参数中过略掉本次要编译的参数,再用 $(filter-out $(cmd_$@), $(cmd_$(1))) 将本次的编译参数中过滤掉上一次的编译参数。正反过滤的原因是,filter-out 函数在过滤时,如果第 2 个参数是第 1 个参数的子集或者是相同,那么返回空;所以,在第 1 次过滤时如果返回为空,那么 cmd_$@ 可能是等于 cmd_$(1) 的,也可能是它的子集,所以只有当再次反过来做过滤时发现返回为空,那么才能判断两次编译的参数是相等的,否则是不等的。如果返回结果不为空,说明编译参数发生了变化,那么就会执行 $(rule_cc_o_c) 。
set -e 表示如果命令执行有错那么命令停止执行并退出。 接着 $(echo-cmd) 用来打印出相关的编译命令,接着执行 $(cmd_$(1) 里的命令。 最后 echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd 将上面执行的命令写入一个叫 $(dot-target).cmd 的文件中,该文件为隐藏文件,在编译后的内核源码目录及其子目录下随处可见,比如在 init/ 下可以看到 .initramfs.o.cmd, .version.o.cmd 等等。 如果目标的依赖或者命令参数已经改变,那么将执行 cmd_vmlinux__ 所代表的新命令。那么这里可能会想到,在新老命令的比较中,老命令是从何而来?正如上面所分析的,老命令正是被写入到 $(dot-target).cmd 文件中的;这样一来,在 Makefile 中肯定有一处是将这些保存了老命令的文件包含进来的语句。在顶层 Makefile 中的 1481-1489 行可以看到:
# read all saved command lines
targets := $(
wildcard
$(
sort
$(targets)
))
cmd_files := $(
wildcard
.*.cmd $(
foreach
f,
$(targets)
,$(
dir
$(f)
).$(notdir
$(f)
).cmd))
ifneq
(
$(cmd_files)
,)
$(cmd_files)
: ;
# Do not try to update included dependency files
include
$(cmd_files)
endif
uboot if_changed函数的更多相关文章
- uboot main_loop函数分析
一.概述 main_loop()函数做的都是与具体平台无关的工作.主要包括的工作如下: (1)初始化启动次数限制机制 (2)Modem功能 (3)设置软件版本号 (4)启动延迟 (5)读取命令, ...
- uboot initf_dm函数分析
initf_dm, static int initf_dm(void){#if defined(CONFIG_DM) && CONFIG_VAL(SYS_MALLOC_F_LEN) / ...
- u-boot initf_bootstage函数分析
这篇博客主要分析 init_sequence_f 函数指针数组中的initf_bootstage函数: static int initf_bootstage(void){ bool from_s ...
- u-boot log_init函数分析
log_init, int log_init(void){ struct log_driver *drv = ll_entry_start(struct log_driver, log_driv ...
- 如何打开uboot的函数debug()的开关,输出更多调试信息?
答: 有两种方法: 一. 方法一 在文件<file>.c的首行加入以下内容: #define DEBUG #undef CONFIG_LOGLEVEL #define CONFIG_LOG ...
- U-Boot GOT表分析和u-boot.lds解读
转自:http://blog.sina.com.cn/s/blog_70dd16910100zab6.html u-boot-2010.09/arch/powerpc/cpu/mpc86xx/star ...
- U-Boot启动过程
开发板上电后,执行U-Boot的第一条指令,然后顺序执行U-Boot启动函数.看一下board/smdk2410/u-boot.lds这个链接脚本,可以知道目标程序的各部分链接顺序.第一个要链接的是c ...
- uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试
今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...
- uboot向kernel的传参机制——bootm与tags
http://blog.csdn.net/skyflying2012/article/details/35787971 最近阅读代码学习了uboot boot kernel的过程以及uboot如何传参 ...
随机推荐
- 【HTTP/FTP客户端库】
[HTTP/FTP客户端库]资料来源:http://curl.haxx.se/libcurl/competitors.html Free Software and Open Source projec ...
- .net sqlite 内存溢出 问题的分析与解决。
一个小的工具网站,用了sqlite数据库,在并发小的情况一切正常,但是并发量上来之后,就报"out of memory"错误了. 分析了代码,就是很简单的根据一个条件取一段数据,并 ...
- java 重写和重载的区别
重写:重写是子类的方法覆盖父类的方法,有两个重要特点 1.子类方法名和参数类型.个数必须和父类一样. 2.如果有返回值,则返回值类型也必须和父类一样. //父类 public class Bird() ...
- docker部署Javaweb项目(jdk+tomcat+mysql)
步骤一:在主机下载安装docker,参照Centos7上安装docker 步骤二:下载Linux版本的JDK1.6和Tomcat6.0(其他项目若依赖其他版本的运行环境可选择另外版本下载),通过sec ...
- 如果将get请求转换成post请求
td><a href="emp/${emp.id}">Edit</a></td> <form action="" ...
- 刃边法计算MTF(ESF、LSF、PSF)
MTF 调制传递函数 评价一个成像系统目前主流的办法主要有三种TV line检测,MTF检测,和SFR检测. MTF是Modulation Transfer Function的英文简称,中文为调制传递 ...
- 6、Shiro之自定义realm
1.创建一个包存放我们自定义的realm文件: 创建一个类名为CustomRealm继承AuthorizingRealm并实现父类AuthorizingRealm的方法,最后重写: CustomRea ...
- 读取数据库 生成Xml节点
foreach (DataColumn v in dt.Columns) { sb.Append("sb.Append(\"<" + v.ColumnName.To ...
- windows下简单安装postgres
目前版本是PostgreSQL 9.6,它经过以下平台认证: 32位Windows Windows 7,8和10 Windows 2008 Server 64位Windows Windows 7,8和 ...
- CSS3——对齐 组合选择符 伪类 伪元素 导航栏 下拉菜单
水平&垂直对齐 元素居中对齐 .center { margin: auto; width: 50%; border: 3px solid green; padding: 10px; } 文本 ...