linux内核中build,linux内核Makefile中的build构建机制

一. build定义:

scripts/Kbuild.include

build

:= -f

$(if $(KBUILD_SRC),$(srctree)/)

scripts/Makefile.build obj

$(KBUILD_SRC)常规情况下为空,所以的变量定义可简化为:

build

:= -f

scripts/Makefile.build obj

二. (MAKE) $(build)=的处理过程

build使用的一般形式为:

$(MAKE) $(build)=

build_dir  [

argv]

斜体字部分为可变目录和参数,其中[

argv] 可选。使用scripts/Kbuild.include中的$(build)变量定义,进行变量替换后,上述命令则为:

$(MAKE) -f scripts/Makefile.build obj=

build_dir  [

argv]

Make进入由参数-f指定的Make文件scripts/Makefile.build,并传入参数obj=

build_dir和

argv。

在scripts/Makefile.build的处理过程中,传入的参数$(obj) 代表此次Make命令要处理(编译、链接、和生成) 文件所在的目录,该目录下通常情况下都会存在的Makefile文件会被Makefile.build包含。$(obj)目录下的Makefile记为$(obj)/Makefile。针对Make命令,有两种情况:不指明Make目标和指定目标。

1.不指定目标

$(MAKE) $(build)=

build_dir  [

argv]

中,当没有参数[argv]时,该Make命令没有指定目标。如顶层Makefile中,$(vmlinux-dirs)的构建规则:

$(vmlinux-dirs): prepare scripts

$(Q)$(MAKE) $(build)=$@

其他的还有主机程序fixdep的构建规则:

scripts_basic:

$(Q)$(MAKE) $(build)=scripts/basic

这时会使用Makefile.build中的默认目标__build。然后更进一步,会使用$(obj)/Makefile中定义的变量来进行目标匹配。

__build在Makefile.build中的构建规则为:

__build

:

$(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y))

\

$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target))

\

$(subdir-ym)

$(always)

@:

首先会构建该默认目标__build的依赖。Make会寻找重建这些依赖的规则。而这些规则要么在当前的Makefile文件Makefile.build中,要么在Makefile.build include的$(obj)/Makefile中。在此不指定Make目标的情况下,会使用Makefile.build中的构建规则来重建依赖。相应地,只重构那些在$(obj)/Makefile定义的依赖。其他的依赖要么

不满足条件,要么找不到重构规则而被忽略。

例如上述$(vmlinux-dirs)规则:

$(vmlinux-dirs): prepare scripts

$(Q)$(MAKE) $(build)=$@

的构建中,没有指明Make目标,那么将使用Makefile.build中的默认目标__build,且会包含上述多目标$(vmlinux-dirs)中,实际处理时的某单一目标(此为目录)下的Makefile文件,即$(obj)/Makefile。在__build规则中,因$(KBUILD_BUILTIN)被主目录设置为1,且export,所以将首先重建依赖$(builtin-target)。而依赖$(builtin-target)的重建规则在Makefile.build中,即:

$(builtin-target)

:

$(obj-y)

FORCE   ####

$(obj)/built-in.o,且先要构建依赖$(obj-y)

$(call if_changed,link_o_target)

该规则同样要首先重建依赖$(obj-y)。而$(obj-y)在$(obj)/Makefile中定义且被赋值。这时Make又会查找$(obj-y)包含文件的构建规则。同样地,该规则要么在Makefile.build中,要么在$(obj)/Makefile中。此处$(obj-y)为.o文件的合集,.o文件的构建规则在Makefile.build中被定义:

$(obj)

/%.o

:

$(src)

/%.c

$(recordmcount_source)

FORCE  ##

$(obj-y)匹配规则

$(call cmd,force_checksrc)

$(call if_changed_rule,cc_o_c)

就是重复这样一个递归的“规则----> 规则目标-->依赖--->重建依赖--->规则---->”....的过程,直至最后的目标文件被构建,然后逆推,由依赖层层重建其规则目标。如果构建的最终目标是主机程序,如上述fixdep的构建规则 :

scripts_basic:

$(Q)$(MAKE) $(build)=scripts/basic

Makefile.build除了要inclue $(obj)/Makefile即scripts/basic/Makefile文件外,还会include scripts/Makefile.host,在Makefile.build 对包含scripts/Makefile.host的处理如下:

ifneq (

$(hostprogs-y)$(hostprogs-m)

,)

include scripts/Makefile.host

#编译主机程序时,要包含Makefile.host文件

endif

因为在此之前已经包含了scripts/basic/Makefile,且在该Makefile文件里,hostprogs-y被赋值为fixdep,那么上述ifneq分支为真。即会包含scripts/Makefile.host。

在scripts/basic/Makefile里,有如下语句:

always        := $(hostprogs-y)

那么回到不指定目标的make命令里,接下来在Makefile.build中的默认目标__build中,会匹配到重建的依赖always。注意这里变量$(always)的值为fixdep。由此触发依赖fixdep的重建(否则,就没有入口目标的依赖层层重建至fixdep)。而它的重建规则在上面包含的scripts/Makefile.host中。其余过程在此略去,详细过程可参照文档“编译产生主机文件(host-cpp)”。

总结:

由于没有指定Make目标,那么将使用Makefile.build的默认目标__build,建构的入口点就在此。Make在Makefile.build 和$(obj)/Makefile

中寻找 __build依赖的重建规则,主机程序目标还用到了Makefile.host文件。依次变量展开,依赖层层递归重建。

2.指定目标:

一般情况下,在(MAKE) $(build)=

build_dir  [

argv] 中,通过参数[

argv]  指定Make目标时,使用的是$(obj)/Makefile文件中构建规则。这时,在$(obj)/Makefile文件中不仅要给一些变量赋值,且还包含本目录下目标的重建规则。

如:

%config

: scripts_basic outputmakefile FORCE

$(Q)

mkdir -p include/linux include/config

$(Q)$(MAKE)

$(build)

=scripts/kconfig $@

在此指定Make目标为自动化变量$@,当我们输入类似如下的命令:

make nitrogen6x_defconfig

那么,上述Make命令会被大致替换为:

make -f scripts/Makefile.build obj=scripts/kconfig nitrogen6x_defconfig

即指定Make的目标为nitrogen6x_defconfig。那么在$(obj)目录scripts/kconfig下的Makefile中包含nitrogen6x_defconfig模式匹配规则。其他的流程和上节的"不指定目标"处理类似。在此不再敖述。

二. 入口处:

1.顶层Makefile---- 指定目标-----include scripts/kconfig/Makefile

如在终端中执行配置命令make nitrogen6x_defconfig

%config

: scripts_basic outputmakefile FORCE

$(Q)

mkdir -p include/linux include/config

$(Q)$(MAKE)

$(build)

=scripts/kconfig $@

2.auto.conf autoconf.h auto.conf.cmd的生成----指定目标-----include scripts/kconfig/Makefile

include/config/%.conf

:

$(KCONFIG_CONFIG)

include/config/auto.conf.cmd

$(Q)$(MAKE)

-f

$(srctree)

/Makefile silentoldconfig

将在顶层Makefile中递归到上述1中的%config规则,所以,其最终还会包含

scripts/kconfig/Makefile

3. 目标编译和链接----不指定目标-----include 各个build目标下的Makefile

$(vmlinux-dirs)

: prepare scripts

$(Q)$(MAKE)

$(build)

=$@

4. 模块----模块建构中单独讨论

$(module-dirs)

:crmodverdir

$(objtree)

/Module.symvers

$(Q)$(MAKE)

$(build)

=

$(patsubst _module_%,%,$@)

modules

:

$(module-dirs)

@

$(kecho)

'  Building modules, stage 2.';

$(Q)$(MAKE)

-f

$(srctree)

/scripts/Makefile.modpost

5. 单目标----不指定目标

%.o

:%.c prepare scripts FORCE

$(Q)$(MAKE)

$(build)

=

$(build-dir)

$(target-dir)$(notdir $@)

6. 子目录递归----不指定目标-----include递归的子目录下Makefile

scripts/Makefile.build

$(subdir-ym)

:

$(Q)$(MAKE)

$(build)

=$@

-----------------------------------------------------------------------------

三. Makefile.build文件总框架:

src

:=

$(obj)

-include include/config/auto.conf  #if xxx_CONFIG配置选项

include scripts/Kbuild.include    #if_changed等变量

##########################

包含obj目录下的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)

############################包含Makefile.lib###################################

include scripts/Makefile.lib

######################

编译主机程序时,要包含Makefile.host文件

#####################

ifneq (

$(hostprogs-y)$(hostprogs-m)

,)

include scripts/Makefile.host

endif

########################

####

定义builtin-target

#################################

ifneq (

$(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target))

,)

builtin-target

:=

$(obj)

/built-in.o

########

endif

########################

####

__build构建规则#################################

__build

:

$(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y))

\

$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target))

\

$(subdir-ym)

$(always)

@:

###################

$(obj)/built-in.o,且先要构建依赖$(obj-y)

#####################

$(builtin-target)

:

$(obj-y)

FORCE

$(call if_changed,link_o_target)

############################ 普通模式匹配规则#################################

define rule_cc_o_c

$(call echo-cmd,checksrc)

$(cmd_checksrc)

\

$(call echo-cmd,cc_o_c)

$(cmd_cc_o_c)

;              \

$(cmd_modversions)

\

$(call echo-cmd,record_mcount)

\

$(cmd_record_mcount)

\

scripts/basic/fixdep

$(depfile)

$@ '

$(call make-cmd,cc_o_c)

' >    \

$(dot-target)

.tmp;  \

rm -f

$(depfile)

;                     \

mv -f

$(dot-target)

.tmp

$(dot-target)

.cmd

endef

$(obj)

/%.o

:

$(src)

/%.c

$(recordmcount_source)

FORCE  ##

$(obj-y)匹配规则

$(call cmd,force_checksrc)

$(call if_changed_rule,cc_o_c)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值