zoukankan      html  css  js  c++  java
  • Makefile 语法分析 第三部分

    Makefile 语法分析 第三部分
    ifeq ($(mixed-targets),1)
    # 条件关键词ifeq判断变量mixed-targets的值与1是否相同,即是否为1
    # ===========================================================================
    # We're called with mixed targets (*config and build targets).
    # Handle them one by one.
    else
    ifeq ($(config-targets),1)
    # 如果变量mixed-targets的值与1不相同,则执行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/$(ARCH)/Makefile
    export KBUILD_DEFCONFIG
    # 如果变量config-targets的值与1相同,则执行从第一行开始直到遇到下面的else结束。
    # 关键词include将文件$(srctree)/arch/$(ARCH)/Makefile包含进来,
    # 文件$(srctree)/arch/$(ARCH)/Makefile被原模原样的放在当前文件的包含位置。
    # 关键词export声明变量KBUILD_DEFCONFIG使得变量KBUILD_DEFCONFIG能传到下级Makefile中。

    config %config: scripts_basic outputmakefile FORCE
    $(Q)mkdir -p include/linux include/config
    $(Q)$(MAKE) $(build)=scripts/kconfig $@
    # 定义了一个规则,目标位config %config其中有个通配符%。
    # 通配符%只能代表一个字符,config %config可以表示xconfig和gconfig、menuconfig和oldconfig等。
    # 二三行将变量展开后就规则得到要执行的命令。

    else
    # 如果变量config-targets的值与1不相同,则执行下面的
    # ===========================================================================
    # Build targets only - this includes vmlinux, arch specific targets, clean
    # targets and others. In general all targets except *config targets.

    ifeq ($(KBUILD_EXTMOD),)
    # 条件关键词ifeq判断变量KBUILD_EXTMOD的值与空是否相同。
    # Additional helpers built in scripts/
    # Carefully list dependencies so we do not try to build scripts twice
    # in parallel
    PHONY += scripts
    scripts: scripts_basic include/config/auto.conf
    $(Q)$(MAKE) $(build)=$(@)
    # 第一行给变量PHONY追加scripts。
    # 定义了一个规则。目标是scripts,依赖文件是scripts_basic include/config/auto.conf
    # 将第三行的所有命令展开就得到规则的命令。

    # Objects we will link into vmlinux / subdirs we need to visit
    init-y   := init/
    drivers-y := drivers/ sound/
    net-y   := net/
    libs-y   := lib/
    core-y   := usr/
    endif # KBUILD_EXTMOD
    # 为变量赋值。
    # 上面的endif与ifeq ($(KBUILD_EXTMOD),)相对应。

    ifeq ($(dot-config),1)
    # Read in config
    -include include/config/auto.conf
    # 条件关键词ifeq判断变量dot-config的值与1是否相同,如果相同这执行上面这一条。
    # 关键词include将文件include/config/auto.conf包含进来,该文件会原模原样的放在当前文件的包含位置。
    # 关键词include前面的减号的作用是让make不理那些无法读取的文件,而继续执行。

    ifeq ($(KBUILD_EXTMOD),)
    # Read in dependencies to all Kconfig* files, make sure to run
    # oldconfig if changes are detected.
    -include include/config/auto.conf.cmd
    # 条件关键词ifeq判断变量KBUILD_EXTMOD的值与0是否相同,如果相同这执行上面这一条。
    # 关键词include将文件include/config/auto.conf.cmd包含进来,该文件会原模原样的放在当前文件的包含位置。
    # 关键词include前面的减号的作用是让make不理那些无法读取的文件,而继续执行。

    # To avoid any implicit rule to kick in, define an empty command
    $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
    # 定义了一个规则,目标是$(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
    include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
    $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
    else
    # 第一二行定义了一个规则。
    # 目标是include/config/auto.conf,依赖文件是$(KCONFIG_CONFIG) include/config/auto.conf.cmd
    # 将第二行的变量展开就得到命令。
    # 上面的else与ifeq ($(KBUILD_EXTMOD),)对应
    # 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
    PHONY += include/config/auto.conf
    # 为变量PHONY追加值include/config/auto.conf

    include/config/auto.conf:
    # 定义了一个伪目标
    $(Q)test -e include/linux/autoconf.h -a -e $@ || (   \
    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)
    # 自动变量$@表示当前规则的目标变量名。
    # echo是shell中的显示命令,显示echo后面的字符串。

    endif # KBUILD_EXTMOD
    # 上面的endif与ifeq ($(KBUILD_EXTMOD),)对应。
    else
    # Dummy target needed, because used as prerequisite
    include/config/auto.conf: ;
    endif # $(dot-config)
    # 定义了一个伪目标include/config/auto.conf,该规则没有依赖文件和命令。
    # 上面的endif与ifeq ($(dot-config),1)对应。

    # 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 vmlinux but it is usually overridden in the arch makefile
    all: vmlinux
    # 定义了一个依赖关系,目标是all,依赖文件是vmlinux。

    ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
    CFLAGS   += -Os
    else
    CFLAGS   += -O2
    endif
    # 条件关键字ifdef只检验变量CONFIG_CC_OPTIMIZE_FOR_SIZE是否被赋值(非空)。
    # 分别在两种情况下为变量CFLAGS追加不同的值。

    include $(srctree)/arch/$(ARCH)/Makefile
    # 用关键字声明文件$(srctree)/arch/$(ARCH)/Makefile,使得该文件能传递到下级Makefile

    ifdef CONFIG_FRAME_POINTER
    CFLAGS   += -fno-omit-frame-pointer $(call cc-option,-fno-optimize-sibling-calls,)
    else
    CFLAGS   += -fomit-frame-pointer
    endif
    # 条件关键字ifdef只检验变量CONFIG_FRAME_POINTER是否被赋值(非空)。
    # 分别在两种情况下为变量CFLAGS追加不同的值。

    ifdef CONFIG_DEBUG_INFO
    CFLAGS   += -g
    endif
    # 条件关键字ifdef只检验变量CONFIG_DEBUG_INFO是否被赋值(非空)。
    # 为变量CFLAGS追加-g

    # Force gcc to behave correct even for buggy distributions
    CFLAGS          += $(call cc-option, -fno-stack-protector)
    # 为变量CFLAGS追加$(call cc-option, -fno-stack-protector)。

    # arch Makefile may override CC so keep this after arch Makefile is included
    NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
    CHECKFLAGS     += $(NOSTDINC_FLAGS)
    # 分别为变量追加值
    # 函数shell新生成一个Shell程序来执行由变量CC展开后形成的命令。

    # warn about C99 declaration after statement
    CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
    # 为变量CFLAGS追加call函数返回的函数call的返回值。
    # 函数call的语法:$(call <expression>;,<parm1>;,<parm2>;,<parm3>;...)。
    # 函数call的功能是:参数cc-option中的变量被字符串-Wdeclaration-after-statement和逗号后面的空格依次取代。
    # 函数call的返回值是:被取代后的参数。

    # disable pointer signed / unsigned warnings in gcc 4.0
    CFLAGS += $(call cc-option,-Wno-pointer-sign,)
    # 为变量CFLAGS追加call函数返回的函数call的返回值。
    # 函数call的语法:$(call <expression>;,<parm1>;,<parm2>;,<parm3>;...)。
    # # 函数call的功能是:参数cc-option中的变量被字符串-Wno-pointer-sign和逗号后面的空格依次取代。

    # 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
    export KBUILD_IMAGE ?= vmlinux
    # 用关键字声明了变量KBUILD_IMAGE,使得该变量能传递到下级Makefile中。
    # 符号“?=”在变量KBUILD_IMAGE没有赋值的情况下给变量KBUILD_IMAGE赋值,如果已经赋值了则什么也不做。

    #
    # INSTALL_PATH specifies where to place the updated kernel and system map
    # images. Default is /boot, but you can set it to other values
    export INSTALL_PATH ?= /boot
    # 用关键字声明了变量INSTALL_PATH,使得该变量能传递到下级Makefile中。
    # 符号“?=”在变量INSTALL_PATH没有赋值的情况下给变量INSTALL_PATH赋值,如果已经赋值了则什么也不做。

    #
    # 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
    # 给变量MODLIB赋值
    # 用关键字声明变量MODLIB使得变量能够传到下级Makefile

    #
    # 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.

    ifdef INSTALL_MOD_STRIP
    ifeq ($(INSTALL_MOD_STRIP),1)
    mod_strip_cmd = $(STRIP) --strip-debug
    else # 这个else与ifeq ($(INSTALL_MOD_STRIP),1)对应。
    mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
    endif # INSTALL_MOD_STRIP=1
    else # 这个else与ifdef INSTALL_MOD_STRIP对应。
    mod_strip_cmd = true
    endif # INSTALL_MOD_STRIP
    export mod_strip_cmd
    # 条件关键字ifdef判断变量INSTALL_MOD_STRIP是否被赋值,
    # 条件关键字ifeq判断变量INSTALL_MOD_STRIP与1是否相同。
    # 如果相同或被赋值则执行紧接着的命令,否则执行同一级的else后的命令。
    # 上面命令就是在不同情况下给变量mod_strip_cmd赋值。


  • 相关阅读:
    速查快递
    浅谈C#中常见的委托<Func,Action,Predicate>(转)
    C#用扩展方法进行自动生成添加删除对象转换的功能
    sql字符串分组
    PowerDesigner连接SQL Server
    老程序员的下场(转)
    界面设计:一个像素之差产生的距离(转)
    程序员如何活得明白(转)
    真实死锁案例记录
    分享java常用技术教程:dubbo、zookeeper、ActiveMq、多线程、Redis、PowerDesigner等
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124516.html
Copyright © 2011-2022 走看看