makefile分析

来源:互联网 发布:mysql left join很慢 编辑:程序博客网 时间:2024/05/22 12:14
# ---------------------------------------------------------------------------
# Modules
ifdef CONFIG_MODULES
# ifdef是Makefile中的一个条件关键词,其语法是:ifdef <variable-name>;
# 如果变量<variable-name>;的值非空,那到表达式为真。否则,表达式为假。
# By default, build modules as well
all: modules
# 定义了一个依赖关系,目标是all,依赖文件是modules
# Build modules
PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
@echo ' Building modules, stage 2.';
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# 为变量PHONY追加值
# 定义了一个规则,目标是modules。
# if是Makefile中的一个函数,其语法是:$(if <condition>;,<then-part>;,<else-part>;)
# <condition>;参数是if的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,
# 于是,<then-part>;会被计算,否则<else-part>;会被计算。
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。

# Target to prepare building external modules
PHONY += modules_prepare
modules_prepare: prepare scripts
# 为变量PHONY追加值
# 第二行定义了依赖关系,目标是modules_prepare,依赖文件是prepare scripts
# Target to install modules
PHONY += modules_install
modules_install: _modinst_ _modinst_post
# 第一行为变量追加值。
# 第二行定义了依赖关系,目标是modules_install,依赖文件是_modinst_ _modinst_post
PHONY += _modinst_
_modinst_:
@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
   echo "Warning: you may need to install module-init-tools"; \
   echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
   sleep 1; \
fi
@rm -rf $(MODLIB)/kernel
@rm -f $(MODLIB)/source
@mkdir -p $(MODLIB)/kernel
@ln -s $(srctree) $(MODLIB)/source
@if [ ! $(objtree) -ef $(MODLIB)/build ]; then \
   rm -f $(MODLIB)/build ; \
   ln -s $(objtree) $(MODLIB)/build ; \
fi
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
# 第一行为变量PHONY追加值。
# 第二行定义了伪目标_modinst_。
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。
# rm是linux shell中的用于删除文件或目录的命令。其语法是:rm [选项]... [要删除的文件]...
# mkdir是linux shell中的用于创建目录的命令,其语法是:mkdir [OPTION] DIRECTORY...
# ln是linux shell中的用于创建一个链接,其语法是:ln [OPTION]... [-T] TARGET LINK_NAME
# If System.map exists, run depmod. This deliberately does not have a
# dependency on System.map since that would run the dependency tree on
# vmlinux. This depmod is only for convenience to give the initial
# boot a modules.dep even before / is mounted read-write. However the
# boot script depmod is the master version.
ifeq "$(strip $(INSTALL_MOD_PATH))" ""
depmod_opts :=
else
depmod_opts := -b $(INSTALL_MOD_PATH) -r
endif
PHONY += _modinst_post
_modinst_post: _modinst_
if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
# ifeq是Makefile中的一个条件关键词,其语法是:ifeq "<arg1>;" "<arg2>;"
# strip是Makefile中的用于去掉空格的函数。其语法是:$(strip <string>;)
# 第二四行分别在不同的情况下给变量depmod_opts赋值。
# 第六行给变量PHONY追加值。
# 第七行定义了一个规则,目标是_modinst_post,依赖文件是_modinst_
else # CONFIG_MODULES
# 上面这个else与ifdef CONFIG_MODULES对应。
# Modules not configured
# ---------------------------------------------------------------------------
modules modules_install: FORCE
@echo
@echo "The present kernel configuration has modules disabled."
@echo "Type 'make config' and enable loadable module support."
@echo "Then build a kernel with module support enabled."
@echo
@exit 1
# 定义了一个规则,目标是modules modules_install,依赖文件是FORCE
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。
# echo是Makefile中的一个将输入的字符串送往标准输出关键字,其语法是:echo [-ne][字符串]
# exit是linux shell中的一个退出目前的shell的命令,其语法是:exit [状态值]
endif # CONFIG_MODULES
# 上面这个endif与ifdef CONFIG_MODULES对应。
###
# Cleaning is done on three levels.
# make clean     Delete most generated files
#                Leave enough to build external modules
# make mrproper Delete the current configuration, and all generated files
# make distclean Remove editor backup files, patch leftover files and the like
# Directories & files removed with 'make clean'
CLEAN_DIRS += $(MODVERDIR)
CLEAN_FILES += vmlinux System.map \
                .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
# 第一行将变量MODVERDIR的值追加给变量CLEAN_DIRS
# 第二行给变量CLEAN_FILES追加值。
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2 usr/include
MRPROPER_FILES += .config .config.old include/asm .version .old_version \
                  include/linux/autoconf.h include/linux/version.h      \
                  include/linux/utsrelease.h                            \
    Module.symvers tags TAGS cscope*
# 上面的是给变量MRPROPER_DIRS和MRPROPER_FILES追加值,
# 字符“\”有两个功能:一是:续行;二是:转义。
# clean - Delete most, but leave enough to build external modules
#
clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES)
clean-dirs      := $(addprefix _clean_,$(srctree) $(vmlinux-alldirs))
# 第一二行分别定义了一个规则,每个规则的命令都是给依赖文件赋值。
# 第三行定义了一个依赖关系。
PHONY += $(clean-dirs) clean archclean
$(clean-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
# 第一行给变量PHONY追加值。
# 第二行定义了一个伪目标$(clean-dirs)。
clean: archclean $(clean-dirs)
$(call cmd,rmdirs)
$(call cmd,rmfiles)
@find . $(RCS_FIND_IGNORE) \
   \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
   -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
   -o -name '*.symtypes' \) \
   -type f -print | xargs rm -f
# 第一行定义了一个规则,目标是clean,依赖文件是archclean和$(clean-dirs)
# call是Makefile的一个用来创建新的参数化的函数,
# 其语法是:$(call <expression>;,<parm1>;,<parm2>;,<parm3>;...)
# <expression>;参数中的变量,会被参数<parm1>;,<parm2>;,<parm3>;依次取代。
# find是linux shell中的一个查找命令,其语法是:find path option [-print -exec -ok]
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。
# 字符“\”有两个功能:一是:续行;二是:转义。
# mrproper - Delete all generated files, including .config
#
mrproper: rm-dirs := $(wildcard $(MRPROPER_DIRS))
mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
mrproper-dirs      := $(addprefix _mrproper_,Documentation/DocBook scripts)
# 第一二行分别定义了一个规则,它们的命令分别是给依赖文件赋值。
# 第三行给变量mrproper-dirs 赋值。
PHONY += $(mrproper-dirs) mrproper archmrproper
$(mrproper-dirs):
$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
# 第一行给变量PHONY赋值。
# 第二行定义了一个伪目标$(mrproper-dirs)。
# patsubst是Makefile中的一个模式字符串替换函数,
# 其语法是:$(patsubst <pattern>;,<replacement>;,<text>;)
# 查找<text>;中的单词是否符合模式<pattern>;,如果匹配的话,则以<replacement>;替换。
mrproper: clean archmrproper $(mrproper-dirs)
$(call cmd,rmdirs)
$(call cmd,rmfiles)
# 定义了一个规则,目标是mrproper。
# call是Makefile的一个用来创建新的参数化的函数,
# 其语法是:$(call <expression>;,<parm1>;,<parm2>;,<parm3>;...)
# <expression>;参数中的变量,会被参数<parm1>;,<parm2>;,<parm3>;依次取代。
# distclean
#
PHONY += distclean
# 给变量PHONY追加值
distclean: mrproper
@find $(srctree) $(RCS_FIND_IGNORE) \
   \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
   -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
   -o -name '.*.rej' -o -size 0 \
   -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
   -type f -print | xargs rm -f
# 上面定义了一个规则,目标是distclean,依赖文件是mrproper。
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。
# find是linux shell中的一个查找命令,其语法是:find path option [-print -exec -ok]
# 字符”\“有两个用途:一是:转义;二是:续行。
# Packaging of the kernel to various formats
# ---------------------------------------------------------------------------
# rpm target kept for backward compatibility
package-dir := $(srctree)/scripts/package
%pkg: include/config/kernel.release FORCE
$(Q)$(MAKE) $(build)=$(package-dir) $@
rpm: include/config/kernel.release FORCE
$(Q)$(MAKE) $(build)=$(package-dir) $@
# 上面定义了两个规则,目标分别是%pkg和rpm。
@ $@是Makefile的自动化变量,表示当前规则的目标集。
# Brief documentation of the typical targets used
# ---------------------------------------------------------------------------
boards := $(wildcard $(srctree)/arch/$(ARCH)/configs/*_defconfig)
boards := $(notdir $(boards))
# 上面两行分别给变量boards赋值。
# wildcard是Makefile中的关键字,用于让通配符在变量中展开。
# notdir是Makefile中的取文件函数,其语法是:$(notdir <names...>;)
# 功能:从文件名序列<names>;中取出非目录部分。非目录部分是指最后一个反斜杠(“/”)之后的部分。
help:
@echo 'Cleaning targets:'
@echo ' clean    - Remove most generated files but keep the config and'
@echo '                    enough build support to build external modules'
@echo ' mrproper   - Remove all generated files + config + various backup files'
@echo ' distclean   - mrproper + remove editor backup and patch files'
@echo ''
@echo 'Configuration targets:'
@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
@echo ''
@echo 'Other generic targets:'
@echo ' all    - Build all targets marked with [*]'
@echo '* vmlinux   - Build the bare kernel'
@echo '* modules   - Build all modules'
@echo ' modules_install - Install all modules to INSTALL_MOD_PATH (default: /)'
@echo ' dir/            - Build all files in dir and below'
@echo ' dir/file.[ois] - Build specified target only'
@echo ' dir/file.ko     - Build module including final link'
@echo ' rpm    - Build a kernel as an RPM package'
@echo ' tags/TAGS   - Generate tags file for editors'
@echo ' cscope   - Generate cscope index'
@echo ' kernelrelease   - Output the release version string'
@echo ' kernelversion   - Output the version stored in Makefile'
@if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
echo ' headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH'; \
echo '                    (default: $(INSTALL_HDR_PATH))'; \
fi
@echo ''
@echo 'Static analysers'
@echo ' checkstack      - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
@if [ -r $(srctree)/include/asm-$(ARCH)/Kbuild ]; then \
echo ' headers_check   - Sanity check on exported headers'; \
fi
@echo ''
@echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help
@echo ''
@echo 'Documentation targets:'
@$(MAKE) -f $(srctree)/Documentation/DocBook/Makefile dochelp
@echo ''
@echo 'Architecture specific targets ($(ARCH)):'
@$(if $(archhelp),$(archhelp),\
   echo ' No architecture specific help defined for $(ARCH)')
@echo ''
@$(if $(boards), \
   $(foreach b, $(boards), \
   printf " %-24s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \
   echo '')
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
@echo ' make V=2   [targets] 2 => give reason for rebuild of target'
@echo ' make O=dir [targets] Locate all output files in "dir", including .config'
@echo ' make C=1   [targets] Check all c source with $$CHECK (sparse by default)'
@echo ' make C=2   [targets] Force check of all c source with $$CHECK'
@echo ''
@echo 'Execute "make" or "make all" to build all targets marked with [*] '
@echo 'For further info see the ./README file'
# 第一行定义了一个伪目标help。
# 当“@”字符在命令行前,那么这个命令将不被make显示出来。
#
原创粉丝点击