【u-boot-2018.11】make配置过程分析

一、u-boot编译

u-boot的编译分为两步:配置、编译。

(1)第一步:配置,执行make pangu_basic_defconfig进行配置,生成.config文件

(2)第二步:编译,执行make进行编译,生成u-boot.*。

二、u-boot配置过程分析

u-boot从u-boot-2014.10版本引入Kbuild系统以后,Makefile的管理和组织跟以前版本有了很大的不同,这使得Makefile变得很复杂。

整个Makefile中,include很多其他不同用途的Makefile,各种目标和依赖也很多,因此要想完全搞清楚make的执行过程很困难,因此先根据u-boot编译过程慢慢分析,这里先分析u-boot的配置过程。

1.配置命令:make pangu_basic_defconfig

执行配置命令时,u-boot根目录下的Makefile中有唯一的规则匹配目标:495行

%config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

其中$(build)定义在scripts/Kbuild.include中:182行

###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj

因此上面的命令展开以后就是:

$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig pangu_basic_defconfig

-f表示指定Makefile文件,因此make时实际运行的Makefile文件为scripts/Makefile.build。

2.依赖scripts_basic

依赖scripts_basic的定义位于u-boot顶层目录下的Makefile中:414行

# Basic helpers built in scripts/
PHONY += scripts_basic
scripts_basic:
	$(Q)$(MAKE) $(build)=scripts/basic
	$(Q)rm -f .tmp_quiet_recordmcount

由上可知,scripts_basic并没有进一步的依赖,展开后的规则如下:

scripts_basic:
	$(Q) make -f $(srctree)/scripts/Makefile.build obj=scripts/basic
	$(Q) rm -f .tmp_quiet_recordmcount

-f表示指定Makefile文件,因此make时实际运行的Makefile文件为scripts/Makefile.build。

3.scripts/Makefile.build

3.1.文件开头:

# SPDX-License-Identifier: GPL-2.0
# ==========================================================================
# Building
# ==========================================================================

# Modified for U-Boot
prefix := tpl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := spl
src := $(patsubst $(prefix)/%,%,$(obj))
ifeq ($(obj),$(src))
prefix := .
endif
endif

根据传入的obj参数,设置src:

(1)对于scripts_basic目标,obj=scripts/basic,那么src=scripts/basic;(2)而对于%config目标,obj=scripts/kconfig,那么src=scripts/kconfig。

3.2.搜寻src目录下的Makefile:54行

# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
include $(kbuild-file)

(1)当src=scripts/basic时,这里替换展开后相当于:

include ./scripts/basic/Makefile

那么对于scripts目标,它的最终结果就是编译scripts/basic/fixdep.c生成主机上的可执行文件fixdep。

(2)当src=scripts/kconfig时,这里替换展开后相当于:

include ./scripts/kconfig/Makefile

对于这里传入的目标pangu_basic_defconfig,它的匹配目标是:

%_defconfig: $(obj)/conf
	$(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)

展开为:

pangu_basic_defconfig: scripts/kconfig/conf
    $(Q)scripts/kconfig/conf  --defconfig=arch/../configs/pangu_basic_defconfig Kconfig

此处目标pangu_basic_defconfig依赖于scripts/kconfig/conf,接下来检查并生成依赖:

hostprogs-y := conf nconf mconf kxgettext qconf gconf

hostprogs-y指出conf被定义为主机上可执行的程序,其依赖于另外两个文件:

conf-objs	:= conf.o  zconf.tab.o

通过编译conf.c和zconf.tab.c生成conf-objs,并链接为scripts/kconfig/conf。

生成依赖后就是执行目标的命令了:

$(Q)scripts/kconfig/conf  --defconfig=arch/../configs/pangu_basic_defconfig Kconfig

conf工具从根目录下开始树状读取默认的Kconfig文件,分析其配置并保存在内存中。分析完默认的Kconfig文件后,再读取指定文件(即arch/../configs/pangu_basic_defconfig)更新得到最终的符号表,并输出到.config文件中。

猜你喜欢

转载自blog.csdn.net/linuxweiyh/article/details/99331659