u-boot中makefile的执行步骤

本文分析的uboot版本是2013.04.主要目的是通过分析uboot顶目录下的makefile文件,了解uboot的大致执行步骤和顺序。


make命令的执行步骤见<makefile中文手册>的P31页。

简而言之就是先读取makefile文件;然后读取include包含的文件;重建已读取makefile文件的规则;展开变量和函数等。


所以当我们在在shell中输入make后,不论是否带参数(make带参数会影响makefile的执行过程)都是先执行sinclude的部分

sinclude $(obj).boards.depend
$(obj).boards.depend:   boards.cfg
    awk '(NF && $$1 !~ /^#/) { print $$1 ": " $$1 "_config; $$(MAKE)" }' $< > $@
这个sinclude的主要目录是看看文件夹下是否右.boards.depend文件,如果没有则依赖boards.cfg文件,更具awk规则来生成一个。

截取.boards.depend的部分内容,格式如下:

mini2440: mini2440_config; $(MAKE)
VCMA9: VCMA9_config; $(MAKE)
smdk2410: smdk2410_config; $(MAKE)
omap1510inn: omap1510inn_config; $(MAKE)

可以发现最左侧的都是目标,比如目标mini2440或smdk2410

并且这些目标都是依赖$(board)_config类型的文件,规则都是执行make动作。 

那为啥要生成这个.boards.depend文件呢?后面再解释,先往下看。


sinclude之后就要重建规则,展开变量,执行makefile了。

我们先分析在shell中直接输入make且不带参数的情况。这种case下,在sinclude等之后就会顺序执行到makefile中的如下处:

ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))                                                       
这是个判断语句,就是在include目录中查找是否右config.mk文件

默认情况下是没有这个文件的,并且如果我们直接在shell中输入make,那make执行到这里的时候也只是执行sinclude的动作,并没有去创建config.mk文件

所以这里就应该直接跑到else的中执行:

else    # !config.mk                                                                                                     
all $(obj)u-boot.hex $(obj)u-boot.srec $(obj)u-boot.bin \
$(obj)u-boot.img $(obj)u-boot.dis $(obj)u-boot \
$(filter-out tools,$(SUBDIRS)) \
updater depend dep tags ctags etags cscope $(obj)System.map:                                                             
<span style="white-space:pre">	</span>@echo "System not configured - see README" >&2                                                                       
<span style="white-space:pre">	</span>@ exit 1
可以看到这里就一个目标,就是从all开始的字符一直到 $(obj)System.map,这个目标就会作为makefile的最终目标。

但是这个目标只是打印了句:system not configured然后提示我们看下READE文件就退出了。

这说明什么呢?说明在shell中仅输入make不带参数的话是编不出u-boot.bin文件的。   ^_^

如何正确编出u-boot.bin文件这里就不说了,请看README的提示吧。


下面我们再来分析另外一种,shell中输入make 带参数的命令。

比如我们要编译mini2440的u-boot。那么可以输入 make mini2440或者make mini2440_config

我们先分析输入make mini2440的情况。

输入make mini2440之后,首先做的和前面一样,先执行sinclude等操作,然后再执行其它动作。

这里我们输入的是make mini2440,注意这时make的执行过程和前面不带参数的make执行过程是不一样的!

具体如下:

make  mini2440参数mini2440是目标,make会去Makefile文件中寻找mini2440对应的依赖和规则。

那我们的Makefile中有mini2440这个规则吗?答案是有!而且是sinclude执行之后才有的。

前面分析过sinclude执行之后是生成了一个.boards.depend的文件,这里面包含了一条:

mini2440: mini2440_config; $(MAKE)
并且该文件是通过sinclude引入的,所以最终这条语句相当于被插入到了Makefile文件中。

所以当输入make mini2440后, 是先去执行mini2440对应的规则,而不是之前不带参数的make执行到ifeq处!

接着我们分析这个mini2440的目标,它依赖的是mini2440_config文件,规则是$(MAKE)也就是再执行make。

那这个mini2440_config依赖文件存在吗?答案是存在!

在顶目录的Makefile中我们看到右如下语句:

%_config::  unconfig                                                                                                     
<span style="white-space:pre">	</span>@$(MKCONFIG) -A $(@:_config=) 
这个%_config就是前面依赖的文件,%是通配符,只要字串中带有后缀_config的都会引用到这里,那mini2440_config当然也不例外。

所以mini2440_config的规则也就是在这里定义,这里会先执行unconfig的相关规则,然后再执行自己的规则。

替换之后就相当于运行./mkconfig -A  mini2440。这时就跑到顶目录的mkconfig中去执行了,

执行完这个之后在include目录下就生成乐config.mk文件。

接着我们再回过头去看mini2440的规则,mini2440的规则是$(MAKE),那就是相当于执行完顶目录的mkconfig之后再执行make且不带参数。

这时候就会从顶目录Makefile开头开始执行,这时就会执行到ifeq语句,此时include目录下已经有了config.mk文件,条件判断成立,后续就

执行ifeq里面的内容去了,最终就会生成u-boot.bin等文件。

我们再理一下这个make mini2440的过程,如下:

1.执行sinclude,生成.boards.depend文件,

mini2440: mini2440_config; $(MAKE)
被插入到顶目录的Makefile文件中

2.检查make参数mini2440对应的依赖文件mini2440_config

3.检查mini2440_config对应的依赖文件和规则

%_config::  unconfig                                                                                                     
<span>	</span>@$(MKCONFIG) -A $(@:_config=) 
4.执行unconfig

unconfig:
<span style="white-space:pre">	</span>@rm -f $(obj)include/config.h $(obj)include/config.mk \
<span style="white-space:pre">	</span>$(obj)board/*/config.tmp $(obj)board/*/*/config.tmp \
<span style="white-space:pre">	</span>$(obj)include/autoconf.mk $(obj)include/autoconf.mk.dep   
5.执行
@$(MKCONFIG) -A $(@:_config=) 

在include目录下生成config.mk文件

6.执行mini2440: mini2440_config; $(MAKE)中的规则
$(MAKE)

相当与再执行一次不带参数的make命令

7从头开始执行顶目录Makefile,此时已存在config.mk文件,所以如下判断成立

 ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk))
所以在这个ifeq里面会去做一些编译链接,最终生成u-boot等文件。


回顾前面,我们说了生成mini2440的uboot可以使用两个命令。make mini2440或make mini2440_config。

那如果输入make mini2440_config的执行过程是怎么样的呢?

如果输入make mini2440_config文件,步骤和make mini2440是一样的,只是不需要依赖.boards.depend文件而已!


记得以前老版本的uboot,比如1.1.6版本,要编译mini2440的uboot的话,应该要分开输入两条命令。

1.先make mini2440_config

2.再make all

所以这个新版本的uboot这么写的makefile的好处大概就是只需要在shell中输入 Target名称就可以,不需要再多输入"_config"。

而且只需要输入这一边就可以得到u-boot.bin文件。

猜你喜欢

转载自blog.csdn.net/rockrockwu/article/details/38706939