针对make 命令,其MAKECMDGOALS表示传递给make的所有的参数。
测试用例如下(该测试用例输出当前输入的命令内容,MAKECMDGOALS是一个全局变量):
%:
@echo $(MAKECMDGOALS)
all:
@echo "no param"
执行结果如下:
Make config/%config的解析
在LINUX的Makefile中,根据如下命令确定是否使用make config相关的命令,其中MAKECMDGOALS即为上面说明的内容
ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter config %config,$(MAKECMDGOALS)),)
config-targets := 1
ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
mixed-targets := 1
endif
endif
endif
当为make config相关的命令时,则将config-targets设为1,继续跟踪
ifeq ($(config-targets),1)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target
# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
include $(srctree)/arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG KBUILD_KCONFIG
config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@
%config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@
else
…
endif
针对make config相关命令,均依赖scripts_basic outputmakefile、FORCE规则,执行完依赖规则后,则调用mkdir -p include/linux include/config创建两个目录,接着调用$(MAKE) $(build)=scripts/kconfig $@执行kconfig相关的处理,下面分别介绍这几个规则。
scripts_basic规则
scripts_basic的定义如下:
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
其中build规则的定义如下(scripts/Kbuild.include):
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj=
# Usage:
# $(Q)$(MAKE) $(build)=dir
build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
因此scripts_basic可展开如下:
scripts_basic:
$(Q)$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/basic
$(Q)rm -f .tmp_quiet_recordmcount
即执行kernel-source/scripts/Makefile.build命令,传递的参数为obj=scripts/basic
其中scripts/Makfile.build文件主要用于编译scripts目录下的各种应用程序,此处是编译scripts/basic目录下的fixdep程序,该程序主要是打印目标文件所依赖的文件列表。
outputmakefile规则
# outputmakefile generates a Makefile in the output directory, if using a
# separate output directory. This allows convenient use of make in the
# output directory.
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
endif
这个规则主要是针对传递KBUILD_SRC变量指定kbuild_src源码目录的情况,其中srctree即为kbuild_src,objtree主要是存储编译产生obj的目录,定义为当前执行make的目录。其中CONFIG_SHELL即为当前系统的shell程序路径,即执行shell脚本 $(srctree)/scripts/mkmakefile,在objtree目录下生成一个makefile文件,以便用于编译使用。该规则与make %config关联不大,可不用关注。
FORCE规则
在linux内核中,FORCE规则的定义如下:
PHONY += FORCE
FORCE:
在MAKEFILE中,如果一个规则没有命令或者依赖,而且它的目标不是一个存在的文件名,则在执行此规则时,目标总会被认为是最新的。因此当别的规则依赖该规则时,由于依赖总被认为是被更新过的,所以作为依赖所在的规则定义的命令总会被执行。
scripts/kconfig规则
针对$(MAKE) $(build)=scripts/kconfig $@,扩展后的命令如下:
$(MAKE) -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj=scripts/kconfig $@
针对$(srctree)/)scripts/Makefile.build文件,会包含如下文件
-include include/config/auto.conf
include scripts/Kbuild.include
include scripts/Makefile.lib
# Do not include host rules unless needed
ifneq ($(hostprogs-y)$(hostprogs-m),)
include scripts/Makefile.host
endif
只需要将kconfig目录下的文件以及scripts目录下的makefile.host文件拷贝出来,并稍作修改,即可完成针对make menuconfig的移植。
目前已移植一个kconfig,移植后的kconfig目前支持make menuconfig、make xxx_defconfig命令,可实现针对应用程序的选择,然后在makefile中根据.config文件中的变量,即可决定哪些应用需要编译,哪些应用不需要编译。
移植后的kconfig目录结构如下:其中configs目录存放默认配置文件,顶层目录下的Makefile中定义了加载.config文件中的变量以及支持make menuconfig、make xxx_defconfig命令;tools目录下存放了kconfig源码,以及编译kconfig源码的Makefile.host文件,Uconfig文件即为linux内核中的Kconfig文件(该文件中内容的格式请参考linux doc目录下的介绍),用于make menuconfig显示条目。
├── configs
│ └── app_a_defconfig
├── Makefile
├── Makefile.common
├── tools
│ ├── kconfig
│ └── Makefile.host
└── Uconfig
以上即为本次主题的全部内容(链接地址如下https://gitee.com/jerry_chg/Uconfig.git)。