在构建混合目标(如 make defconfig all )时会将 mixed-targets 变量设置为 1 ,这样在顶层 Makefile 的 438 行的判断条件成立:
ifeq ($(mixed-targets),1)
从 438 行到 464 行的代码片段如下:
[code=Makefile]ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.
%:: FORCE
$(Q)$(MAKE)-C $(srctree) KBUILD_SRC= $@
else
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 $@[/mw_shl_code]
从下面这段代码的注释可以知道:
[code=Makefile]# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.
%:: FORCE
$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@[/mw_shl_code]
这里构建的是混合目标,会一个个的进行处理。
上面使用了一个双冒号规则,在双冒号前面使用了 % 号,说明匹配任何一个目标,$(srctree) 变量表示内核源代码所在目录,而且 KBUILD_SRC= 定义为空。如果像上面执行 make defconfig all 命令时,deconfig 和 all 这两个目标会分别被处理成:
$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= defconfig
$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= all
是几个 *.c 文件,还有一个 Makefile 文件,并没有子目录,再看一下 Makefile 内容:
[code=Makefile]
###
# Makefile.basic lists the most basic programs used during the build process.
# The programs listed herein are what are needed to do the basic stuff,
# such as fix file dependencies.
# This initial step is needed to avoid files to be recompiled
# when kernel configuration changes (which is what happens when
# .config is included by main Makefile.
# ---------------------------------------------------------------------------
# fixdep: Used to generate dependency information during build process
# docproc: Used in Documentation/DocBook
对于 outputmakefile 实际上只有在执行 make 命令时指定了 O 选项(关于 O 选项可参考:http://www.groad.net/bbs/read.php?tid-3844.html)才有用,在顶层 Makefile 中的 396-404 行中可以看到它的注释及相关代码:
[code=Makefile]# 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[/mw_shl_code]
注释里总的意思是,outputmakefile 会在输出目录(O 选项指定的目录)里创建一个 Makefile 文件。因为如果指定了 O 选项,那么 $(KBUILD_SRC) 就不会为 0,所以会执行 ifneq-endif 块里的语句。在输出目录里创建的新的 Makefile 文件调用 scripts/mkmakefile 这个脚本文件来完成,$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) 这 4 个变量是传递到脚本文件中的 4 个参数。