概述
编译总体过程
- 编译host工具
- 编译交叉工具链
- 编译内核模块
- 编译ipk
- 安装ipk到文件系统
- 编译内核
- 将内核和文件系统组合成最终binary
顶层Makefile分析
在顶层Makefile里比较麻烦的是,将Makefile分为了两个主要分支,第一个部分主要是执行编译前的准备,第二个部分是执行编译。在每个分支里通过include载入相应的文件,在这些文件里包含相应的目标执行命令,在命令中多次用make+目标+参数的方式,则会再次执行Makefile文件,就形成了Makefile的嵌套执行。在嵌套执行的过程中,通过变量OPENWRT_BUILD来区分是执行顶层Makefile的那个部分,如果在make命令行中有OPENWRT_BUILD为0,则执行第一个部分,没有加OPENWRT_BUILD变量则执行第二个部分。
由于OPENWRT_BUILD是make命令行参数,所以在Makefile中如果要改变它的值,就用到了override指示符。
target/Makefile、package/Makefile、tools/Makefile、toolchain/Makefile这四个子目录下的Makefile实际上是不能独立执行。主要利用$(INCLUDE_DIR)/subdir.mk动态建立规则,诸如$(toolchain/stamp-install)目标是靠$(INCLUDE_DIR)/subdir.mk的stampfile函数动态建立。
$(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
这类使用变量命名的目标,其变量的赋值位置在$(INCLUDE_DIR)/subdir.mk的stampfile函数中。目标只有依赖关系,可能说明其工作顺序,在$(INCLUDE_DIR)/subdir.mk的stampfile函数中有进一步说明其目标执行的命令,并为目标建立一个空文件,即使用变量命名的目标为真实的文件。
top Makefile: $(package/stamp-compile): $(target/stamp-compile) $(package/stamp-cleanup)
package_makefile: $(eval $(call stampfile,$(curdir),package,compile,$(TMP_DIR)/.build))
subdir.mk:
define stampfile # Parameters: <subdir> <name> <target> <depends> <config options> <stampfile location>
$(1)/stamp-$(3):=$(if $(6),$(6),$(STAGING_DIR))/stamp/.$(2)_$(3)$(5)
$$($(1)/stamp-$(3)): $(TMP_DIR)/.build $(4)
$(1)=$(curdir) $(2)=package $(3)=compile
$(package/stamp-compile):=$(STAGING_DIR)/stamp/.package_compile
prereq应该是预请求目标,在OpenWrt执行Makefile时好像都要先执行prereq目标。
prepare应该是准备目标,是world依赖的一个伪目标。依赖于文件.config和$(tools/stamp-install) $(toolchain/stamp-install)目标。
top Makefile: // second part
prereq: $(target/stamp-prereq) tmp/.prereq_packages
prepare: .config $(tools/stamp-install) $(toolchain/stamp-install)
world: prepare $(target/stamp-compile) $(package/stamp-compile) $(package/stamp-install) $(target/stamp-install) FORCE
$(_SINGLE)$(SUBMAKE) -r package/index
toplevel.mk:
prereq:: prepare-tmpinfo .config
@+$(NO_TRACE_MAKE) -r -s $@ (@make tmp/.prereq-build)
%::
@+$(PREP_MK) $(NO_TRACE_MAKE) -r -s prereq
@+$(ULIMIT_FIX) $(SUBMAKE) -r $@
除了少数在toplevel中被定义的目标外, 其他编译目标都会走到这里.将之简化后:
%::
make prereq
make $@
首先执行prereq, 然后再执行我们指定的目标或者默认目标world.
NO_TRACE_MAKE := $(MAKE) V=99
上面的 “%::” 用于解释world目标的规则
%是通配符,加上双冒号规则,此组合表示任何目标去无条件执行下面的命令
在执行@+$(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
最后
以上就是复杂金针菇为你收集整理的OpenWrt makefile 分析编译总体过程顶层Makefile分析的全部内容,希望文章能够帮你解决OpenWrt makefile 分析编译总体过程顶层Makefile分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复