Linux Makefile学习(二)
来源:互联网 发布:性价比 实木家具 知乎 编辑:程序博客网 时间:2024/04/30 08:53
# Use LINUXINCLUDE when you must reference the include/ directory.
# Needed to be compatible with the O= option
# 当你需要设计include/目录时,使用LINUXINCLUDE
# 需要配合O=选项一起使用
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-I$(srctree)/arch/$(hdr-arch)/include \
-include include/linux/autoconf.h
KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration \
-Wno-format-security \
-fno-delete-null-pointer-checks
KBUILD_AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
# 从include/config/kernel.release中读取KERNELRELEASE变量(如果include/config/kernel.release存在)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP
export MAKE AWK GENKSYMS INSTALLKERNEL PERL UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
# even be read-only.
# 当编译目录树外的模块时,将MODVERDIR放在模块树下而非内核树下。内核树可能只是只读的。
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
# Files to ignore in find ... statements
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
# ===========================================================================
# Rules shared between *config targets and build targets
# *config目标和build目标之间的共享规则。
# Basic helpers built in scripts/
# 在scripts目录下的基本辅助对象构建
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic//$(build)在scripts/Kbuild.include文件中定义。
//build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
# To avoid any implicit rule to kick in, define an empty command.
# 为了阻止规则隐含规则生效,定义一个空命令。
scripts/basic/%: scripts_basic ;
PHONY += 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在输出目录创建一个Makefile。这使在输出目录使用make很方便。
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \//$(CONFIG_SHELL)上文定义过,获取本地shell
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)//会在$(objtree)目录下创建一个Makefile
//具体分析在mkmakefile文件讲解中
endif
# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to scripts/kconfig/Makefile
# It is allowed to specify more targets when calling make, including
# mixing *config targets and build targets.
# For example 'make oldconfig all'.
# Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config).
#
no-dot-config-targets := clean mrproper distclean \
cscope TAGS tags help %docs check% \
include/linux/version.h headers_% \
kernelrelease kernelversion
config-targets := 0
mixed-targets := 0
dot-config := 1
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)//过滤掉不符合$(no-dot-config-targets)
//模式的内容
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)//过滤掉符合$(no-dot-config-targets)
//模式的内容
dot-config := 0
endif
endif
ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter config %config,$(MAKECMDGOALS)),)
config-targets := 1
ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
mixed-targets := 1
endif
endif
endif
ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.
# 如果是混合目标,重新一个一个目标递归调用一次该Makefile。
%:: 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
# 只有*config目标 - 确定依赖被更新后,进入scripts/kconfig中去构造*config目标。
# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
# 读arch特定的Makefile去按照需要设置KBUILD_DEFCONFIG变量。KBUILD_DEFCONFIG可以在使用'make defconfig'
# 时指出一个备选的默认configuration。
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
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
# 只有构建目标 - 这包括vmlinux,和arch特定目标,clean目标和别的。通常除了*config目标都是构建目标。
ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice
# in parallel
# 额外的帮助内建在scripts/下
# 仔细列出依赖关系,以便我们不用尝试构建两次脚本。
PHONY += scripts
scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@)
# Objects we will link into vmlinux / subdirs we need to visit
# 我们需要链接进vmlinux中的部分,也是我们需要访问的子目录。
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
endif # KBUILD_EXTMOD
ifeq ($(dot-config),1) //符合no_dot_config_targets的集合不为空且不符合no_dot_config_targets集合为空
//时,dot-config-targets为0
# Read in config
-include include/config/auto.conf //后文中创建出来的
ifeq ($(KBUILD_EXTMOD),)
# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
# 阅读所有Kconfig*文件的依赖关系,如果检测出变化,确保运行旧配置文件。
-include include/config/auto.conf.cmd
# To avoid any implicit rule to kick in, define an empty command
# 定一个空命令行,阻止隐式规则。
$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
# If .config is newer than include/config/auto.conf, someone tinkered
# with it and forgot to run make oldconfig.
# if auto.conf.cmd is missing then we are probably in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
# 如果.config比include/config/auto.conf文件新,某些人笨手笨脚,忘记执行make oldconfig。
# 如果在被清理的目录中,auto.conf.cmd文件丢失了,我们要执行配置步骤以确保获取更新后的Kconfig文件。
include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
# external modules needs include/linux/autoconf.h and include/config/auto.conf
# but do not care if they are up-to-date. Use auto.conf to trigger the test
# 外部模块需要include/linux/autoconf.h和include/config/auto.conf,但是不关心是否是最新的。使用auto.config
# 触发检测。
PHONY += include/config/auto.conf
include/config/auto.conf:
$(Q)test -e include/linux/autoconf.h -a -e $@ || (\ //-e表示检测文件是否存在,-a
//表示前后两个条件必须同时满足
echo; \
echo " ERROR: Kernel configuration is invalid.";\
echo " include/linux/autoconf.h or $@ are missing.";\
echo " Run 'make oldconfig && make prepare' on kernel src to fix it.";\
echo; \
/bin/false) //以错误码退出
endif # KBUILD_EXTMOD
else
# Dummy target needed, because used as prerequisite
# 需要一个假目标作为先决条件
include/config/auto.conf: ;
endif # $(dot-config)
# The all: target is the default when no target is given on the
# command line.
# 当没有在命令行给出明确目标,all是默认目标。
# This allow a user to issue only 'make' to build a kernel including modules
# Defaults vmlinux but it is usually overridden in the arch makefile
# 这允许用户只使用‘make’构建包含模块的内核。
# 默认是vmlinux但经常被arch下makefile重写。
all: vmlinux.
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os//-Os相当于-O2.5。是使用了所有-O2的优化选项,但又不缩减代码尺寸的方法。
else
KBUILD_CFLAGS += -O2
endif
include $(srctree)/arch/$(SRCARCH)/Makefile
//cc-option检测给出的选项$(CC)是否支持,不支持则指定第二个可选参数为$(CC)选项。第二个参数是可选的,
//如果被省略且第一个参数不被支持,KBUILD_CFLAGS被设为空值
//call类似与shell中的函数调用,cc-option在Scripts/Kbuild.include文件中定义。
ifneq ($(CONFIG_FRAME_WARN),0)
KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
endif
# Force gcc to behave correct even for buggy distributions
# 强制gcc有正确运行,甚至是对于缺陷分支。
ifndef CONFIG_CC_STACKPROTECTOR
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
endif
ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
KBUILD_CFLAGS += -fomit-frame-pointer
endif
ifdef CONFIG_DEBUG_INFO
KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
endif
ifdef CONFIG_FUNCTION_TRACER
KBUILD_CFLAGS += -pg//产生供gprof剖析用的可执行文件
endif
# We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
# arch Makefile may override CC so keep this after arch Makefile is included
# arch下Makefile可能会重写CC变量,所以在arch Makefile被包含后保存下来。
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
//-nostdinc 不在标准系统目录中搜索头文件,只在-I指定的目录中搜索
//-isystem
//$(shell $(CC) -print-file-name=include) 编译器的include路径
# warn about C99 declaration after statement
KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
# revert to pre-gcc-4.4 behaviour of .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# conserve stack if available
KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
PS:很多选项不知道什么意思。
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
# But warn user when we do so
# 添加用户提供的CPPFLAGS,AFLAGS和CFLAGS作为最后的部分。
# 但是当这样做时,提示用户。
warn-assign = \
$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
ifneq ($(KCPPFLAGS),)
$(call warn-assign,CPPFLAGS)
KBUILD_CPPFLAGS += $(KCPPFLAGS)
endif
ifneq ($(KAFLAGS),)
$(call warn-assign,AFLAGS)
KBUILD_AFLAGS += $(KAFLAGS)
endif
ifneq ($(KCFLAGS),)
$(call warn-assign,CFLAGS)
KBUILD_CFLAGS += $(KCFLAGS)
endif
# Use --build-id when available.
# 可以的时候,使用--build-id选项。
//--build-id是链接器选项。
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
$(call cc-ldoption, -Wl$(comma)--build-id,))
LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
LDFLAGS_vmlinux += $(call ld-option, -X,)
endif
# Default kernel image to build when no specific target is given.
# KBUILD_IMAGE may be overruled on the command line or
# set in the environment
# Also any assignments in arch/$(ARCH)/Makefile take precedence over
# this default value
# 当没有给出明确的目标时,默认创建内核镜像。
# 在命令行或者环境变量中设置的KBUILD_IMAGE可能会无效。
# arch/$(ARCH)/Makefile下任何任务的优先级都高于这个默认值。
export KBUILD_IMAGE ?= vmlinux
#
# INSTALL_PATH specifies where to place the updated kernel and system map
# images. Default is /boot, but you can set it to other values
#
# INSTALL_PATH指定更新的内核和system map镜像放置位置。默认是/boot,但你可以将它设置成别的值。
export INSTALL_PATH ?= /boot
#
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots. This is not defined in the
# makefile but the argument can be passed to make if needed.
#
# INSTALL_MOD_PATH指定MODLIB的前缀,MODLIB是构建根目录请求的模块目录。这个值没有在makefile中定义,但
# 如果需要可以传递给它值。
#
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
export MODLIB
#
# INSTALL_MOD_STRIP, if defined, will cause modules to be
# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
# the default option --strip-debug will be used. Otherwise,
# INSTALL_MOD_STRIP will used as the options to the strip command.
#
# INSTALL_MOD_STRIP,如果被定义,将会在模块安装后被strip(PS:strip作用是除去绑定程序和符号调试程序
# 使用的信息)。如果INSTALL_MOD_STRIP是‘1’,默认选项--strip-debug 将被使用。否则,INSTALL_MOD_STRIP
# 将被用作strip命令的选项。
ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $(STRIP) --strip-debug
else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1
else
mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
$(net-y) $(net-m) $(libs-y) $(libs-m)))
vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
$(init-n) $(init-) \
$(core-n) $(core-) $(drivers-n) $(drivers-) \
$(net-n) $(net-) $(libs-n) $(libs-))))
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
# Needed to be compatible with the O= option
# 当你需要设计include/目录时,使用LINUXINCLUDE
# 需要配合O=选项一起使用
LINUXINCLUDE := -Iinclude \
$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \
-I$(srctree)/arch/$(hdr-arch)/include \
-include include/linux/autoconf.h
KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common \
-Werror-implicit-function-declaration \
-Wno-format-security \
-fno-delete-null-pointer-checks
KBUILD_AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
# 从include/config/kernel.release中读取KERNELRELEASE变量(如果include/config/kernel.release存在)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
export ARCH SRCARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
export CPP AR NM STRIP OBJCOPY OBJDUMP
export MAKE AWK GENKSYMS INSTALLKERNEL PERL UTS_MACHINE
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
# even be read-only.
# 当编译目录树外的模块时,将MODVERDIR放在模块树下而非内核树下。内核树可能只是只读的。
export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
# Files to ignore in find ... statements
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
# ===========================================================================
# Rules shared between *config targets and build targets
# *config目标和build目标之间的共享规则。
# Basic helpers built in scripts/
# 在scripts目录下的基本辅助对象构建
PHONY += scripts_basic
scripts_basic:
$(Q)$(MAKE) $(build)=scripts/basic//$(build)在scripts/Kbuild.include文件中定义。
//build := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.build obj
# To avoid any implicit rule to kick in, define an empty command.
# 为了阻止规则隐含规则生效,定义一个空命令。
scripts/basic/%: scripts_basic ;
PHONY += 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在输出目录创建一个Makefile。这使在输出目录使用make很方便。
outputmakefile:
ifneq ($(KBUILD_SRC),)
$(Q)ln -fsn $(srctree) source
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \//$(CONFIG_SHELL)上文定义过,获取本地shell
$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)//会在$(objtree)目录下创建一个Makefile
//具体分析在mkmakefile文件讲解中
endif
# To make sure we do not include .config for any of the *config targets
# catch them early, and hand them over to scripts/kconfig/Makefile
# It is allowed to specify more targets when calling make, including
# mixing *config targets and build targets.
# For example 'make oldconfig all'.
# Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config).
#
no-dot-config-targets := clean mrproper distclean \
cscope TAGS tags help %docs check% \
include/linux/version.h headers_% \
kernelrelease kernelversion
config-targets := 0
mixed-targets := 0
dot-config := 1
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)//过滤掉不符合$(no-dot-config-targets)
//模式的内容
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)//过滤掉符合$(no-dot-config-targets)
//模式的内容
dot-config := 0
endif
endif
ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter config %config,$(MAKECMDGOALS)),)
config-targets := 1
ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
mixed-targets := 1
endif
endif
endif
ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.
# 如果是混合目标,重新一个一个目标递归调用一次该Makefile。
%:: 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
# 只有*config目标 - 确定依赖被更新后,进入scripts/kconfig中去构造*config目标。
# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
# 读arch特定的Makefile去按照需要设置KBUILD_DEFCONFIG变量。KBUILD_DEFCONFIG可以在使用'make defconfig'
# 时指出一个备选的默认configuration。
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
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.
# 只有构建目标 - 这包括vmlinux,和arch特定目标,clean目标和别的。通常除了*config目标都是构建目标。
ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice
# in parallel
# 额外的帮助内建在scripts/下
# 仔细列出依赖关系,以便我们不用尝试构建两次脚本。
PHONY += scripts
scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@)
# Objects we will link into vmlinux / subdirs we need to visit
# 我们需要链接进vmlinux中的部分,也是我们需要访问的子目录。
init-y := init/
drivers-y := drivers/ sound/ firmware/
net-y := net/
libs-y := lib/
core-y := usr/
endif # KBUILD_EXTMOD
ifeq ($(dot-config),1) //符合no_dot_config_targets的集合不为空且不符合no_dot_config_targets集合为空
//时,dot-config-targets为0
# Read in config
-include include/config/auto.conf //后文中创建出来的
ifeq ($(KBUILD_EXTMOD),)
# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
# 阅读所有Kconfig*文件的依赖关系,如果检测出变化,确保运行旧配置文件。
-include include/config/auto.conf.cmd
# To avoid any implicit rule to kick in, define an empty command
# 定一个空命令行,阻止隐式规则。
$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
# If .config is newer than include/config/auto.conf, someone tinkered
# with it and forgot to run make oldconfig.
# if auto.conf.cmd is missing then we are probably in a cleaned tree so
# we execute the config step to be sure to catch updated Kconfig files
# 如果.config比include/config/auto.conf文件新,某些人笨手笨脚,忘记执行make oldconfig。
# 如果在被清理的目录中,auto.conf.cmd文件丢失了,我们要执行配置步骤以确保获取更新后的Kconfig文件。
include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
# external modules needs include/linux/autoconf.h and include/config/auto.conf
# but do not care if they are up-to-date. Use auto.conf to trigger the test
# 外部模块需要include/linux/autoconf.h和include/config/auto.conf,但是不关心是否是最新的。使用auto.config
# 触发检测。
PHONY += include/config/auto.conf
include/config/auto.conf:
$(Q)test -e include/linux/autoconf.h -a -e $@ || (\ //-e表示检测文件是否存在,-a
//表示前后两个条件必须同时满足
echo; \
echo " ERROR: Kernel configuration is invalid.";\
echo " include/linux/autoconf.h or $@ are missing.";\
echo " Run 'make oldconfig && make prepare' on kernel src to fix it.";\
echo; \
/bin/false) //以错误码退出
endif # KBUILD_EXTMOD
else
# Dummy target needed, because used as prerequisite
# 需要一个假目标作为先决条件
include/config/auto.conf: ;
endif # $(dot-config)
# The all: target is the default when no target is given on the
# command line.
# 当没有在命令行给出明确目标,all是默认目标。
# This allow a user to issue only 'make' to build a kernel including modules
# Defaults vmlinux but it is usually overridden in the arch makefile
# 这允许用户只使用‘make’构建包含模块的内核。
# 默认是vmlinux但经常被arch下makefile重写。
all: vmlinux.
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os//-Os相当于-O2.5。是使用了所有-O2的优化选项,但又不缩减代码尺寸的方法。
else
KBUILD_CFLAGS += -O2
endif
include $(srctree)/arch/$(SRCARCH)/Makefile
//cc-option检测给出的选项$(CC)是否支持,不支持则指定第二个可选参数为$(CC)选项。第二个参数是可选的,
//如果被省略且第一个参数不被支持,KBUILD_CFLAGS被设为空值
//call类似与shell中的函数调用,cc-option在Scripts/Kbuild.include文件中定义。
ifneq ($(CONFIG_FRAME_WARN),0)
KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})
endif
# Force gcc to behave correct even for buggy distributions
# 强制gcc有正确运行,甚至是对于缺陷分支。
ifndef CONFIG_CC_STACKPROTECTOR
KBUILD_CFLAGS += $(call cc-option, -fno-stack-protector)
endif
ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
KBUILD_CFLAGS += -fomit-frame-pointer
endif
ifdef CONFIG_DEBUG_INFO
KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
endif
ifdef CONFIG_FUNCTION_TRACER
KBUILD_CFLAGS += -pg//产生供gprof剖析用的可执行文件
endif
# We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH
KBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)
endif
# arch Makefile may override CC so keep this after arch Makefile is included
# arch下Makefile可能会重写CC变量,所以在arch Makefile被包含后保存下来。
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)
//-nostdinc 不在标准系统目录中搜索头文件,只在-I指定的目录中搜索
//-isystem
//$(shell $(CC) -print-file-name=include) 编译器的include路径
# warn about C99 declaration after statement
KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signed / unsigned warnings in gcc 4.0
KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
# disable invalid "can't wrap" optimizations for signed / pointers
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
# revert to pre-gcc-4.4 behaviour of .eh_frame
KBUILD_CFLAGS += $(call cc-option,-fno-dwarf2-cfi-asm)
# conserve stack if available
KBUILD_CFLAGS += $(call cc-option,-fconserve-stack)
PS:很多选项不知道什么意思。
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
# But warn user when we do so
# 添加用户提供的CPPFLAGS,AFLAGS和CFLAGS作为最后的部分。
# 但是当这样做时,提示用户。
warn-assign = \
$(warning "WARNING: Appending $$K$(1) ($(K$(1))) from $(origin K$(1)) to kernel $$$(1)")
ifneq ($(KCPPFLAGS),)
$(call warn-assign,CPPFLAGS)
KBUILD_CPPFLAGS += $(KCPPFLAGS)
endif
ifneq ($(KAFLAGS),)
$(call warn-assign,AFLAGS)
KBUILD_AFLAGS += $(KAFLAGS)
endif
ifneq ($(KCFLAGS),)
$(call warn-assign,CFLAGS)
KBUILD_CFLAGS += $(KCFLAGS)
endif
# Use --build-id when available.
# 可以的时候,使用--build-id选项。
//--build-id是链接器选项。
LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
$(call cc-ldoption, -Wl$(comma)--build-id,))
LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
LDFLAGS_vmlinux += $(call ld-option, -X,)
endif
# Default kernel image to build when no specific target is given.
# KBUILD_IMAGE may be overruled on the command line or
# set in the environment
# Also any assignments in arch/$(ARCH)/Makefile take precedence over
# this default value
# 当没有给出明确的目标时,默认创建内核镜像。
# 在命令行或者环境变量中设置的KBUILD_IMAGE可能会无效。
# arch/$(ARCH)/Makefile下任何任务的优先级都高于这个默认值。
export KBUILD_IMAGE ?= vmlinux
#
# INSTALL_PATH specifies where to place the updated kernel and system map
# images. Default is /boot, but you can set it to other values
#
# INSTALL_PATH指定更新的内核和system map镜像放置位置。默认是/boot,但你可以将它设置成别的值。
export INSTALL_PATH ?= /boot
#
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots. This is not defined in the
# makefile but the argument can be passed to make if needed.
#
# INSTALL_MOD_PATH指定MODLIB的前缀,MODLIB是构建根目录请求的模块目录。这个值没有在makefile中定义,但
# 如果需要可以传递给它值。
#
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
export MODLIB
#
# INSTALL_MOD_STRIP, if defined, will cause modules to be
# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
# the default option --strip-debug will be used. Otherwise,
# INSTALL_MOD_STRIP will used as the options to the strip command.
#
# INSTALL_MOD_STRIP,如果被定义,将会在模块安装后被strip(PS:strip作用是除去绑定程序和符号调试程序
# 使用的信息)。如果INSTALL_MOD_STRIP是‘1’,默认选项--strip-debug 将被使用。否则,INSTALL_MOD_STRIP
# 将被用作strip命令的选项。
ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $(STRIP) --strip-debug
else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1
else
mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
$(net-y) $(net-m) $(libs-y) $(libs-m)))
vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
$(init-n) $(init-) \
$(core-n) $(core-) $(drivers-n) $(drivers-) \
$(net-n) $(net-) $(libs-n) $(libs-))))
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
drivers-y := $(patsubst %/, %/built-in.o, $(drivers-y))
net-y := $(patsubst %/, %/built-in.o, $(net-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
0 0
- Linux Makefile学习(二)
- 【Linux学习】Makefile学习(二)
- linux驱动学习(二) Makefile高级
- linux驱动学习(二) Makefile高级
- linux驱动学习(二) Makefile高级
- linux Makefile(二)
- Makefile学习(二)
- Makefile学习(二)
- Makefile学习(二)
- makefile学习(二)--Makefile 总述
- makefile学习笔记(二)
- Makefile 学习小记(二)
- Linux Makefile学习(一)
- Linux学习(十三):Makefile
- Makefile 学习笔记(二) Makefile总述
- Linux内核Makefile文件(二)
- Linux下makefile教程(二)
- Linux内核Makefile文件(二)
- win8命令提示符怎么以管理员方式打开
- 关于 Android Studio 鼠标中键的一些技巧
- JSP中特殊字符处理
- vc如何在GUI界面下显示命令窗
- webp格式图片
- Linux Makefile学习(二)
- Back Track下建立“钓鱼”热点测试
- 294 - Divisors(唯一分解定律)
- win7 64位 旗舰版 环境配置(多方学习的小总结)
- C++ I/0 Stream <setf and Manipulators>
- linux服务器操作系统的选择
- jquery如何控制一个元素的高亮显示
- Largest Number —— Leetcode(sort的妙用)
- 堆空间和栈空间的大小