最新uboot的Kbuild系统 2 make rpi_defconfig

查看 make rpi_defconfig 的执行过程


由于带了命令 rpi_defconfig,所以

ifeq ($(KBUILD_EXTMOD),)
        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                config-targets := 1
                ifneq ($(words $(MAKECMDGOALS)),1)
                        mixed-targets := 1
                endif
        endif
endif


config-targets=1


执行匹配顶层Makefile中 if config-targets里面的内容

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

依赖于  scripts_basic outputmakefile。

再展开后面命令为 ($(build)在include scripts/Kbuild.include中定义)

@make -f ./scripts/Makefile.build obj=scripts/kconfig rpi_defconfig


先处理依赖

1 scripts_basic

scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount

展开执行第一句

@make -f ./scripts/Makefile.build obj=scripts/basic

Makefile.build中执行的是

__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
$(subdir-ym) $(always)
@:

KBUILD_BUILTIN在顶层makefile中被定义为1。

初始时候什么都没有配置。所以

ifneq ($(strip $(lib-y) $(lib-m) $(lib-)),)
lib-target := $(obj)/lib.a
endif

ifneq ($(strip $(obj-y) $(obj-m) $(obj-) $(subdir-m) $(lib-target)),)
builtin-target := $(obj)/built-in.o
endif

都为空。


KBUILD_MODULES配置为空。


subdir-ym在include Makefile.lib里面

__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y += $(__subdir-y)
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
subdir-m += $(__subdir-m)

subdir-ym := $(sort $(subdir-y) $(subdir-m))

subdir-ym := $(addprefix $(obj)/,$(subdir-ym))


obj-y和obj-m都为空

subdir-ym也为空


在看always由于在前面有

prefix := tpl

src := $(patsubst $(prefix)/%,%,$(obj))

$(patsubst PATTERN,REPLACEMENT,TEXT)

搜索TEXT中用空格分开的单词。如果符合PATTERN。那么将PATTERN替换成REPLACEMENT

从$(obj)中寻找以tpl/开头字符串。用后面的部分替换。其实也就是如果有tpl/开头的。那么去掉 tpl/

这里$(obj)=scripts/basic

所以src=scripts/basic


kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))

$(filter PATTERN...,TEXT);

过滤掉TEXT当中不符合PATTERN的字符串

$(if condition,then,else)

如果条件满足返回then.否则返回else

也就是判断$(src)是不是以/开头的绝对路径。如果是,返回$(src)。否则返回$(srctree)/$(src)。

这里

$(src)=scripts/basic

$(srctree)=.

返回的是./scripts/basic


kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
$(wildcard PATTERN) 返回当前目录满足PATTERN的文件名

先查看./scripts/basic/Kbuild是否存在。如果存在。返回./scripts/basic/Kbuild。否则返回./scripts/basic/Makefile


include $(kbuild-file)

包含这个  $(kbuild-file)

这里就是 include ./scripts/basic/Makefile

hostprogs-y := fixdep
always := $(hostprogs-y)
# fixdep is needed to compile other host programs
$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep

这里always= $(hostprogs-y)=fixdep

filter-out是保留不符合pattern的。

$(filter-out fixdep,$(always))为NULL

$(addprefix $(obj)/,$(filter-out fixdep,$(always))) 也为NULL

所以always为fixdep

也就是构建fixdep,在scripts/basic/Makefile中有

hostprogs-y := fixdep

又在Makefile.build中有

ifneq ($(hostprogs-y)$(hostprogs-m),)
include scripts/Makefile.host
endif

因此包含了 Makefile.host。在Makefile.host中

__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))

# C code
# Executables compiled from a single .c file
host-csingle := $(foreach m,$(__hostprogs), \
$(if $($(m)-objs)$($(m)-cxxobjs)$($(m)-sharedobjs),,$(m)))

host-csingle 表示在本机运行的由单一的c文件编译的。因此fixdep在这里面。

构建fixdep

$(host-csingle): $(obj)/%: $(src)/%.c FORCE
$(call if_changed_dep,host-csingle)

调用if_changed_dep。这个函数在Kbuild.include里面。

if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ),                  \
@set -e;                                                             \
$(echo-cmd) $(cmd_$(1));                                             \
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
rm -f $(depfile);                                                    \
mv -f $(dot-target).tmp $(dot-target).cmd)


$(cmd_$(1));也就是执行cmd_host-csingle

cmd_host-csingle = $(HOSTCC) $(hostc_flags) -o $@ $< \
  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))

具体指令后续再看

后续还调用了fixdep。



2 依赖outputmakefile 

ifneq ($(KBUILD_SRC),)

$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
   $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif

由于KBUILD_SRC为NULL。所以这一部分不执行


3执行 @make -f ./scripts/Makefile.build obj=scripts/kconfig rpi_defconfig

参考 scripts_basic的执行过程。

会包含scripts/config目录下的Makefile 并构建rpi_defconfig目标。

因此命中kconfig/Makefile当中的

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


第一步先构建依赖 $(obj)/conf

再执行 scripts/kconfig/conf  --defconfig=arch/../configs/rpi_defconfig Kconfig

(注意当前的执行目录依然是顶层目录)

构建依赖conf的过程也是由于kconfig/Makefile中有

hostprogs-y := conf nconf mconf kxgettext qconf gconf

所以和前面的fixdep一样包含了Makefile.host。只是此时由于还有conf-objs:= conf.o  zconf.tab.o

因此conf是

host-cmulti := $(foreach m,$(__hostprogs),\
  $(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))

主机上运行的由多用.o文件组成的bin

同样编译过程就是Link这些o

cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
 $(addprefix $(obj)/,$($(@F)-objs)) \
 $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))


对于.o文件则是

$(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)

cmd_host-cxxobjs = $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<

这些都是根据依赖($(host-cxxobjs):) 一个个递归寻找的。

编译好conf之后

执行scripts/kconfig/conf  --defconfig=arch/../configs/rpi_defconfig Kconfig


因此make rpi_defconfig主要工作是

1产生fixdep

2产生conf

3调用scripts/kconfig/conf  --defconfig=arch/../configs/rpi_defconfig Kconfig 

关键的部分还是在conf的执行


如果不执行第三步。光执行1 2可以看出文件比原来多了







如果再执行第三步,那么就会多出一个.config




最关键的还是第3步















  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值