赞
踩
uboot的makefile里面有两个all:
第一个all:没有依赖,也没有命令。后面接的是两条include
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
另外一个 all: $(ALL-y) $(SUBDIR_EXAMPLES)
这个all才是我们真正需要执行的
要理解这里的all 空命令的作用。必须了解下面几个点
1
当makefile中有两个相同目标的时候,会执行后一个目标。因为后一个目标会重载前一个。
比如
all:
echo all1
all:
echo all2
执行make 会输出后一个all2
2伪目标
一个使用地方是 当不需要产生一个实际的目标文件的时候(比如只要执行指令)。
clean:
rm *.o
这样是不产生文件。只需要执行指令。如果当前目录没有一个文件叫做clean。执行make clean是正常的 。如果目录下有一个clean文件。那么由于这个clean文件是最新的,因此就不会执行rm *.o操作。因此需要定义一个伪目标。不管目录下是否存在这个目标。都会执行clean的操作rm *.o
.PHONY clean
clean:
rm *.o
3空命令
可以存在依赖文件,但是没有命令行。
比如
all:
或者
all: $(obj)
空命令的唯一作用是防止make在执行时,试图为重建这个目标去查找隐含命令
这句话暂时不好理解。先看后面的再说。
4makefile的执行规则和include 这个是关键点
makefile首先被解析。
遇到include。先去解析include的文件(假设为inc.mk),解析完毕以后再回头来解析原makefile。
关键点是如果这个inc.mk不存在。make不会退出。而是先提出一个警告,继续处理原makefile的内容。
等到原makefile的内容处理完毕以后。会尝试使用规则来重建这个inc.mk文件,也就是尝试将这个inc.mk文件当做一个目标来执行。如果不能重建出这个inc.mk。那么报告一个错误,make退出。如果这个inc.mk重建成功了。那么将原makefile的状态重置,重新开始执行这个makefile。
回头来看uboot的makefile。假定我们成功执行了make xxxx_config。接下来执行了一个make 命令
首先遇到的就是一个
all:
sinclude $(obj)include/autoconf.mk.dep
sinclude $(obj)include/autoconf.mk
我们来看如果没有第一个all:会是什么结果。
此时的autoconf.mk.dep 以及 autoconf.mk都是不存在的
但是根据第四条。make不会退出。会先继续往下执行。执行完整个makefile
再回头来看include的文件。
如果在makefile末尾打印一句reach to end,在sinclude $(obj)include/autoconf.mk也打印一句,那么我们看到的结果是
Makefile:189: "hereis include autoconf.mk.dep"
Makefile:892: "reach to end"
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
Makefile:189: "hereis include autoconf.mk.dep"
Makefile:892: "reach to end"
make: `include/autoconf.mk' is up to date.
根据第四条,第一次没有autoconf.mk 先执行了整个makefile的读取打印了reach to end。
然后回过头将include/autoconf.mk以及 include/autoconf.mk.dep当做一个目标执行。因此才会有Generating include/autoconf.mk
Generating include/autoconf.mk.dep的输出。完毕后重置makefile状态。重新执行makefile。此时autoconf.mk和autoconf.mk.dep都有了。
为什么没有编译uboot呢? 因为我们执行的命令是make 。后面没有带参数,因此makefile会编译默认遇到的第一个目标。因为我们注释了第一个all:
所以直接执行了include。打开autoconf.mk.dep看到第一行就是include/autoconf.mk: include/common.h 。这就是makefile遇到的第一个目标
include/autoconf.mk。因此将include/autoconf.mk当做终极目标执行了。此时的include/autoconf.mk是前一次刚产生的,所以是最新的。makefile认为没有必要重新执行。
因此什么都不做,最后输出了make: `include/autoconf.mk' is up to date.这里也就理解了前面的第三条 空命令的唯一作用是防止make在执行时,试图为重建这个目标去查找隐含命令,这个隐含的命令就是执行第一个遇到的目标。
如果有第一个all:的话。makefile就知道需要执行的终极目标是 all。而不是include的autoconf.mk.dep里面的include/autoconf.mk。
继续执行到遇到后面的all: 后面的all将覆盖前面的all。执行这里的操作。所以最终执行的是第二个all
因此第一个all:的含义就是
如果你 执行make的时候没有带任何其他目标。单独的一个make。可以避免以autoconf.mk.dep里面的include/autoconf.mk作为错误目标。
如果你执行make的时候带了目标。这个all:有不有都无所谓。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。