Chinaunix首页 | 论坛 | 博客
  • 博客访问: 306487
  • 博文数量: 111
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 672
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-05 23:41
文章分类

全部博文(111)

文章存档

2017年(111)

我的朋友

分类: LINUX

2017-06-19 18:04:16

当在顶层目录执行”make menuconfig”会执行顶层Makefile 第415行的规则 

config %config: scripts_basic outputmakefile FORCE 
$(Q)mkdir -p include/linux include/config 
$(Q)$(MAKE) $(build)=scripts/kconfig $@ 

这里”menuconfig”与模式”%config”匹配。所以其执行的规则如下: 

menuconfig: scripts_basic outputmakefile FORCE 
$(Q)mkdir -p include/linux include/config 
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig 

这个规则有三个依赖:scripts_basic、outputmakefile、FORCE。下面看一下这三个依赖: 

1、 FORCE 

首先分析一下这个依赖,它的规则定式义在1485行: 

PHONY = FORCE 
FORCE: 

这个规则没有命令也没有依赖,它的目标也不是一个存在的文件名。在执行此规则时,目标FORCE总会被认为是最新的。这样当它作为其它规则的依赖时,因为依赖总被认为被更新过的,所以那个规则的中定义的命令总会被执行。 

2、 scripts_basic 

这个依赖的规则在347行定义: 

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

build这个变量定义在scripts/Kbuild.include的114行: 

build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj 

所以上面的规则可写成如下形式: 

scripts_basic: 
$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/basic 

这个规则的命令最终会进入scripts目录,执行Makefile.build文件,并传递参数obj=scripts/basic. 

在Makefile.build的第5行有: 

src := $(obj) 

这就把传递进来的值赋给了src,所以 

src := scripts/basic 

从第16行开始的两行把src (即scripts/basic)目录下的Makefile包含进来(如果有Kbuild则包含Kbuild) 

kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) 

在第19行包含了scripts/Makefile.lib进来, 

在Makefile.build的第83行,是make在Makefile.build中遇到的第一个目标 

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

KBUILD_BUILTIN在顶层Makefile的第207行定义 

KBUILD_BUILTIN := 1 

如果执行”make modules”,会在214行开始对其进行一些处理 

ifeq ($(MAKECMDGOALS),modules) 
KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) 
endif 

所以我们这里 KBUILD_BUILTIN :=1 

KBUILD_MODULES在顶层Makefile的第206行定义, 

KBUILD_MODULES := 

如果执行”make all”、”make _all”、”make modules”、”make”中任一个命令,则在222行开始会对这个变量进行处理 

ifneq ($(filter all _all modules,$(MAKECMDGOALS)),) 
KBUILD_MODULES := 1 
endif 

ifeq ($(MAKECMDGOALS),) 
KBUILD_MODULES := 1 
endif 

因此,我们这里KBUILD_MODULES := 

分析了这两个变量后,上面的规则可重新写为 

__build: $(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always) 
@: 

这就是通过规则 

scripts_basic: 
$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/basic 

在scripts/Makefile.build文件中执行的第一个规则, 

规则中的依赖由几个变量$(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always)表示。规则的命令是一个冒号命令”:”,冒号(:)命令是bash的内建命令,通常把它看作true命令。bash的help解释 (help :)为:No effect; the command does nothing. A zero exit code is returned.(没有效果,该命令是空操作,退出状态总是0)。 
__build: $(builtin-target) $(lib-target) $(extra-y)) $(subdir-ym) $(always) 
@: 

构建一些依赖目标,这里主要是构建$(always)变量指定的目标。其他变量在scripts/basic/Makefile中并没有定义。 

3、 outputmakefile 

回到顶层Makefile中看规则 

menuconfig: scripts_basic outputmakefile FORCE 
$(Q)mkdir -p include/linux include/config 
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig 

中的outputmakefile参数构建规则在357行开始定义 

outputmakefile: 
ifneq ($(KBUILD_SRC),) 
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ 
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) 
endif 

这个规则的命令运行一个shell脚本scripts/mkmakefile,并传递四个参数。这个脚本主要是在$(objtree)参数指定的目录中生成一个Makefile文件。由于这里KBUILD_SRC为空,所以这个脚本并不会被执行 

回头再看看刚才那个规则 

menuconfig: scripts_basic outputmakefile FORCE 
$(Q)mkdir -p include/linux include/config 
$(Q)$(MAKE) $(build)=scripts/kconfig menuconfig 

在他的依赖被处理完后,开始执行规则的命令。第一个命令创建了两个目录,第二个命令扩展后为 

$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj =scripts/kconfig menuconfig 

这个命令依然是执行scripts/Makefile.build这个makefile文件。并执行它里面menuconfig的规则。根据上面的分析, 在Makefile.build会包含scripts/kconfig/Makefile文件。然后执行以menuconfig为目标的规则,在 scripts/kconfig/Makefile的13行定义 

menuconfig: $(obj)/mconf 
            $< arch/$(ARCH)/Kconfig 
  
从这个命令可以看出,最终会运行arch/arm/Kconfig这个脚本,出现配置界面
阅读(1257) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~