openwrt顶层Makefile分析

来源:互联网 发布:nb998 知乎 编辑:程序博客网 时间:2024/04/28 05:30

openwrt

这里主要介绍openwrt的主Makefile,并未对各个目录下的Makefile和相关文件进行介绍。

 

在Makefile里是两个主要的分支,由if语句根据OPENWRT_BUILD的值进行不同的处理。第一个部分主要是执行编译前的准备,第二个部分是执行编译。

打开Makefile文件,可以看到默认的make目标world,这个目标没有依赖文件和执行命令。

 

执行make的时候,首先进入第一个部分,此时OPENWRT_BUILD的值为0,然后将OPENWRT_BUILD的值赋为1,在这里用到了override指示符,override指示符的作用的忽略make命令行的参数的赋值,可以对该变量进行赋值。

载入include下的相关文件,在toplevel.mk可以看到

%::

        @+$(PREP_MK) $(NO_TRACE_MAKE) -r -sprereq

        @+$(SUBMAKE) -r $@

默认的目标就会执行这里。

在toplevel.mk的顶部定义了PREP_MK=OPENWRT_BUILD= QUIET=0,将OPENWRT_BUILD的值赋为0。

在执行@+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq命令的时候,在make命令行里有$(PREP_MK)变量,

而由于OPENWRT_BUILD的值为0,在verbose.mk文件里NO_TRACE_MAKE := $(MAKE) V=99,所以会执行顶层

目录的Makefile第一个分支部分的目标prereq,即toplevel.mk文件中的目标prereq:

prereq::prepare-tmpinfo .config

        @+$(MAKE) -r -s tmp/.prereq-build$(PREP_MK)

        @+$(NO_TRACE_MAKE) -r -s $@

这里会进行一些编译前的准备工作,然后执行@+$(NO_TRACE_MAKE) -r -s $@,再次去执行顶层Makefile,此时,并没有$(PREP_MK)变量,

所以会执行顶层Makefile的第一个部分,载入include下的相关文件,和一些必要的Makefile文件,在顶层Makefile去寻找prereq目标,

prereq:$(target/stamp-prereq) tmp/.prereq_packages

处理它的依赖文件。

然后再接着执行toplevel.mk

%::

        @+$(PREP_MK) $(NO_TRACE_MAKE) -r -sprereq

        @+$(SUBMAKE) -r $@

在@+$(SUBMAKE)-r $@命令中也没有$(PREP_MK)变量,所以在顶层Makefile的第二个部分,寻找Makefile的默认目标,即world。

world: prepare$(target/stamp-compile) $(package/stamp-cleanup) $(package/stamp-compile)$(package/stamp-install) $(package/stamp-rootfs-prepare)$(target/stamp-install) FORCE

        $(_SINGLE)$(SUBMAKE) -r package/index

根据各个依赖文件进行相应的编译,最终完成编译。

 

在顶层Makefile里比较麻烦的是,将Makefile分为了两个主要分支,在每个分支里通过include载入相应的文件,在这些文件里包含相应的目标执行命

令,在命令中多次用make+ 目标 + 参数 的方式,则会再次执行Makefile文件,就形成了Makefile的嵌套执行。

在嵌套执行的过程中,通过变量OPENWRT_BUILD来区分是执行顶层Makefile的那个部分,如果在make命令行中有OPENWRT_BUILD为0,则执行第一个部分,没有加OPENWRT_BUILD变量则执行第二个部分。

由于OPENWRT_BUILD是make命令行参数,所以在Makefile中如果要改变它的值,就用到了override指示符。


原创粉丝点击