@cyysu
2017-10-17T06:41:22.000000Z
字数 13236
阅读 1322
- 时间:22017年10月17日
- 作者:Kali
- 邮箱:cyysu.github.io@gmail.com
- 版本:3.0
- 描述:Makefile-项目五,继Makefile项目篇四的Makefile
Makefile系列教程
大多数知识点我已经在基础篇五里面讲解过了,在分析内核的Makefile时最好有一个源码分析工具,还有遇到问题先不要纠结,继续向下面看,然后在回来思考那个问题,问题可能就会换了一个角度。
# 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 filesinclude/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfigelse# external modules needs include/generated/autoconf.h and include/config/auto.conf# but do not care if they are up-to-date. Use auto.conf to trigger the testPHONY += include/config/auto.confinclude/config/auto.conf:$(Q)test -e include/generated/autoconf.h -a -e $@ || ( \echo >&2; \echo >&2 " ERROR: Kernel configuration is invalid."; \echo >&2 " include/generated/autoconf.h or $@ are missing.";\echo >&2 " Run 'make oldconfig && make prepare' on kernel src to fix it."; \echo >&2 ; \/bin/false)endif # KBUILD_EXTMODelse# Dummy target needed, because used as prerequisiteinclude/config/auto.conf: ;endif # $(dot-config)# The all: target is the default when no target is given on the# command line.# This allow a user to issue only 'make' to build a kernel including modules# Defaults to vmlinux, but the arch makefile usually adds further targetsall: vmlinux# The arch Makefile can set ARCH_{CPP,A,C}FLAGS to override the default# values of the respective KBUILD_* variablesARCH_CPPFLAGS :=ARCH_AFLAGS :=ARCH_CFLAGS :=# 这个地方涉及到了 编译过程中的make -f ./scripts/Makefile.build obj=arch/x86/tools relocsinclude arch/$(SRCARCH)/Makefile# 这里的call函数,就是可以用后面的参数更新前面的变量KBUILD_CFLAGS += $(call cc-option,-fno-delete-null-pointer-checks,)KBUILD_CFLAGS += $(call cc-disable-warning,maybe-uninitialized,)KBUILD_CFLAGS += $(call cc-disable-warning,frame-address,)KBUILD_CFLAGS += $(call cc-disable-warning, format-truncation)KBUILD_CFLAGS += $(call cc-disable-warning, format-overflow)KBUILD_CFLAGS += $(call cc-disable-warning, int-in-bool-context)ifdef CONFIG_CC_OPTIMIZE_FOR_SIZEKBUILD_CFLAGS += -Oselseifdef CONFIG_PROFILE_ALL_BRANCHESKBUILD_CFLAGS += -O2elseKBUILD_CFLAGS += -O2endifendif# Tell gcc to never replace conditional load with a non-conditional oneKBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)# check for 'asm goto'ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) $(KBUILD_CFLAGS)), y)KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTOKBUILD_AFLAGS += -DCC_HAVE_ASM_GOTOendififdef CONFIG_READABLE_ASM# Disable optimizations that make assembler listings hard to read.# reorder blocks reorders the control in the function# ipa clone creates specialized cloned functions# partial inlining inlines only parts of functionsKBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \$(call cc-option,-fno-ipa-cp-clone,) \$(call cc-option,-fno-partial-inlining)endififneq ($(CONFIG_FRAME_WARN),0)KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN})endif# Handle stack protector mode.## Since kbuild can potentially perform two passes (first with the old# .config values and then with updated .config values), we cannot error out# if a desired compiler option is unsupported. If we were to error, kbuild# could never get to the second pass and actually notice that we changed# the option to something that was supported.## Additionally, we don't want to fallback and/or silently change which compiler# flags will be used, since that leads to producing kernels with different# security feature characteristics depending on the compiler used. ("But I# selected CC_STACKPROTECTOR_STRONG! Why did it build with _REGULAR?!")## The middle ground is to warn here so that the failed option is obvious, but# to let the build fail with bad compiler flags so that we can't produce a# kernel when there is a CONFIG and compiler mismatch.#ifdef CONFIG_CC_STACKPROTECTOR_REGULARstackp-flag := -fstack-protectorifeq ($(call cc-option, $(stackp-flag)),)$(warning Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: \-fstack-protector not supported by compiler)endifelseifdef CONFIG_CC_STACKPROTECTOR_STRONGstackp-flag := -fstack-protector-strongifeq ($(call cc-option, $(stackp-flag)),)$(warning Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: \-fstack-protector-strong not supported by compiler)endifelse# Force off for distro compilers that enable stack protector by default.stackp-flag := $(call cc-option, -fno-stack-protector)endifendifKBUILD_CFLAGS += $(stackp-flag)ifeq ($(cc-name),clang)KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)KBUILD_CFLAGS += $(call cc-disable-warning, unused-variable)KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier)KBUILD_CFLAGS += $(call cc-disable-warning, gnu)# Quiet clang warning: comparison of unsigned expression < 0 is always falseKBUILD_CFLAGS += $(call cc-disable-warning, tautological-compare)# CLANG uses a _MergedGlobals as optimization, but this breaks modpost, as the# source of a reference will be _MergedGlobals and not on of the whitelisted names.# See modpost pattern 2KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)else# These warnings generated too much noise in a regular build.# Use make W=1 to enable them (see scripts/Makefile.build)KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)endififdef CONFIG_FRAME_POINTERKBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-callselse# Some targets (ARM with Thumb2, for example), can't be built with frame# pointers. For those, we don't have FUNCTION_TRACER automatically# select FRAME_POINTER. However, FUNCTION_TRACER adds -pg, and this is# incompatible with -fomit-frame-pointer with current GCC, so we don't use# -fomit-frame-pointer with FUNCTION_TRACER.ifndef CONFIG_FUNCTION_TRACERKBUILD_CFLAGS += -fomit-frame-pointerendifendifKBUILD_CFLAGS += $(call cc-option, -fno-var-tracking-assignments)ifdef CONFIG_DEBUG_INFOifdef CONFIG_DEBUG_INFO_SPLITKBUILD_CFLAGS += $(call cc-option, -gsplit-dwarf, -g)elseKBUILD_CFLAGS += -gendifKBUILD_AFLAGS += -Wa,-gdwarf-2endififdef CONFIG_DEBUG_INFO_DWARF4KBUILD_CFLAGS += $(call cc-option, -gdwarf-4,)endififdef CONFIG_DEBUG_INFO_REDUCEDKBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly) \$(call cc-option,-fno-var-tracking)endififdef CONFIG_FUNCTION_TRACERifndef CC_FLAGS_FTRACECC_FLAGS_FTRACE := -pgendifexport CC_FLAGS_FTRACEifdef CONFIG_HAVE_FENTRYCC_USING_FENTRY := $(call cc-option, -mfentry -DCC_USING_FENTRY)endifKBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_USING_FENTRY)KBUILD_AFLAGS += $(CC_USING_FENTRY)ifdef CONFIG_DYNAMIC_FTRACEifdef CONFIG_HAVE_C_RECORDMCOUNTBUILD_C_RECORDMCOUNT := yexport BUILD_C_RECORDMCOUNTendifendifendif# We trigger additional mismatches with less inliningifdef CONFIG_DEBUG_SECTION_MISMATCHKBUILD_CFLAGS += $(call cc-option, -fno-inline-functions-called-once)endif# arch Makefile may override CC so keep this after arch Makefile is includedNOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)CHECKFLAGS += $(NOSTDINC_FLAGS)# warn about C99 declaration after statementKBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)# disable pointer signed / unsigned warnings in gcc 4.0KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)# disable invalid "can't wrap" optimizations for signed / pointersKBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)# conserve stack if availableKBUILD_CFLAGS += $(call cc-option,-fconserve-stack)# disallow errors like 'EXPORT_GPL(foo);' with missing headerKBUILD_CFLAGS += $(call cc-option,-Werror=implicit-int)# require functions to have arguments in prototypes, not empty 'int foo()'KBUILD_CFLAGS += $(call cc-option,-Werror=strict-prototypes)# Prohibit date/time macros, which would make the build non-deterministicKBUILD_CFLAGS += $(call cc-option,-Werror=date-time)# use the deterministic mode of AR if availableKBUILD_ARFLAGS := $(call ar-option,D)include scripts/Makefile.kasaninclude scripts/Makefile.extrawarn# Add any arch overrides and user supplied CPPFLAGS, AFLAGS and CFLAGS as the# last assignmentsKBUILD_CPPFLAGS += $(ARCH_CPPFLAGS) $(KCPPFLAGS)KBUILD_AFLAGS += $(ARCH_AFLAGS) $(KAFLAGS)KBUILD_CFLAGS += $(ARCH_CFLAGS) $(KCFLAGS)# Use --build-id when available.LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\$(call cc-ldoption, -Wl$(comma)--build-id,))KBUILD_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 valueexport 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 valuesexport INSTALL_PATH ?= /boot## INSTALL_DTBS_PATH specifies a prefix for relocations required by build roots.# Like INSTALL_MOD_PATH, it isn't defined in the Makefile, but can be passed as# an argument if needed. Otherwise it defaults to the kernel install path#export INSTALL_DTBS_PATH ?= $(INSTALL_PATH)/dtbs/$(KERNELRELEASE)## 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.#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 value will be used as the options to the strip command.ifdef INSTALL_MOD_STRIPifeq ($(INSTALL_MOD_STRIP),1)mod_strip_cmd = $(STRIP) --strip-debugelsemod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)endif # INSTALL_MOD_STRIP=1elsemod_strip_cmd = trueendif # INSTALL_MOD_STRIPexport mod_strip_cmd# CONFIG_MODULE_COMPRESS, if defined, will cause module to be compressed# after they are installed in agreement with CONFIG_MODULE_COMPRESS_GZIP# or CONFIG_MODULE_COMPRESS_XZ.mod_compress_cmd = trueifdef CONFIG_MODULE_COMPRESSifdef CONFIG_MODULE_COMPRESS_GZIPmod_compress_cmd = gzip -n -fendif # CONFIG_MODULE_COMPRESS_GZIPifdef CONFIG_MODULE_COMPRESS_XZmod_compress_cmd = xz -fendif # CONFIG_MODULE_COMPRESS_XZendif # CONFIG_MODULE_COMPRESSexport mod_compress_cmd# Select initial ramdisk compression format, default is gzip(1).# This shall be used by the dracut(8) tool while creating an initramfs image.#INITRD_COMPRESS-y := gzipINITRD_COMPRESS-$(CONFIG_RD_BZIP2) := bzip2INITRD_COMPRESS-$(CONFIG_RD_LZMA) := lzmaINITRD_COMPRESS-$(CONFIG_RD_XZ) := xzINITRD_COMPRESS-$(CONFIG_RD_LZO) := lzoINITRD_COMPRESS-$(CONFIG_RD_LZ4) := lz4# do not export INITRD_COMPRESS, since we didn't actually# choose a sane default compression above.# export INITRD_COMPRESS := $(INITRD_COMPRESS-y)ifdef CONFIG_MODULE_SIG_ALL$(eval $(call config_filename,MODULE_SIG_KEY))mod_sign_cmd = scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODULE_SIG_KEY_SRCPREFIX)$(CONFIG_MODULE_SIG_KEY) certs/signing_key.x509elsemod_sign_cmd = trueendifexport mod_sign_cmdifeq ($(KBUILD_EXTMOD),)core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/# patsubst 函数表示字符串匹配替换vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \$(core-y) $(core-m) $(drivers-y) $(drivers-m) \$(net-y) $(net-m) $(libs-y) $(libs-m) $(virt-y)))vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \$(init-) $(core-) $(drivers-) $(net-) $(libs-) $(virt-))))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)virt-y := $(patsubst %/, %/built-in.o, $(virt-y))# Externally visible symbols (used by link-vmlinux.sh)export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y) $(virt-y)export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.ldsexport LDFLAGS_vmlinux# used by scripts/pacmage/Makefileexport KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools)# 它是由内核代码下的每个顶级目录的built-in.o组成的。vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)# Final link of vmlinuxcmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)quiet_cmd_link-vmlinux = LINK $@# Include targets which we want to# execute if the rest of the kernel build went well.vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCEifdef CONFIG_HEADERS_CHECK$(Q)$(MAKE) -f $(srctree)/Makefile headers_checkendififdef CONFIG_SAMPLES$(Q)$(MAKE) $(build)=samplesendififdef CONFIG_BUILD_DOCSRC$(Q)$(MAKE) $(build)=Documentationendififdef CONFIG_GDB_SCRIPTS$(Q)ln -fsn `cd $(srctree) && /bin/pwd`/scripts/gdb/vmlinux-gdb.pyendif+$(call if_changed,link-vmlinux)# The actual objects are generated when descending,# make sure no implicit rule kicks in# 可以看到 $(vmlinux-deps)这个目标依赖于$(vmlinux-dirs)这个目标$(sort $(vmlinux-deps)): $(vmlinux-dirs) ;# Handle descending into subdirectories listed in $(vmlinux-dirs)# Preset locale variables to speed up the build process. Limit locale# tweaks to this spot to avoid wrong language settings when running# make menuconfig etc.# Error messages still appears in the original language# $(vmlinux-dirs)这个目标依赖于 prepare scripts这两个目标PHONY += $(vmlinux-dirs)$(vmlinux-dirs): prepare scripts$(Q)$(MAKE) $(build)=$@define filechk_kernel.releaseecho "$(KERNELVERSION)$$($(CONFIG_SHELL) $(srctree)/scripts/setlocalversion $(srctree))"endef# Store (new) KERNELRELEASE string in include/config/kernel.releaseinclude/config/kernel.release: include/config/auto.conf FORCE$(call filechk,kernel.release)# Things we need to do before we recursively start building the kernel# or the modules are listed in "prepare".# A multi level approach is used. prepareN is processed before prepareN-1.# archprepare is used in arch Makefiles and when processed asm symlink,# version.h and scripts_basic is processed / created.
支付宝 微信