linux 顶层Makefile执行的流程!!!(一)

1、make menuconfig

VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 26
EXTRAVERSION =
NAME = Rotary Wombat

# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
# More info can be located in ./README
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.

# Do not:
# o  use make's built-in rules and variables
#    (this increases performance and avoids hard-to-debug behaviour);
# o  print "Entering directory ...";
MAKEFLAGS += -rR --no-print-directory
#-r禁止使用build-in规则
#--no-print-directory是:不要再屏幕上打印"Entering directory.."
#记住变量SHELL,MAKEFLAGS在整个make的执行过程中
#始终被自动的传递给所有的子make

# We are using a recursive build, so we need to do a little thinking
# to get the ordering right.
#
# Most importantly: sub-Makefiles should only ever modify files in
# their own directory. If in some directory we have a dependency on
# a file in another dir (which doesn't happen often, but it's often
# unavoidable when linking the built-in.o targets which finy
# turn into vmlinux), we will call a sub make in that other dir, and
# after that we are sure that everything which is in that other dir
# is now up to date.
#
# The only cases where we need to modify files which have global
# effects are thus separated out and done before the recursive
# descending is started. They are now explicitly listed as the
# prepare rule.

# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands

ifdef V   #v=1
  ifeq ("$(origin V)", "command line")
    KBUILD_VERBOSE = $(V)   #把V的值作为KBUILD_VERBOSE的值
  endif
endif

ifndef KBUILD_VERBOSE  #即默认我们是不回显的
        #回显即在命令执行前显示要执行的命令
  KBUILD_VERBOSE = 0 
endif
# 函数origin并不操作变量的值,只是告诉你你的这个变量是哪里来的。
# 语法是: $(origin <variable>;)# origin函数的返回值有:
#"undefined"从来没有定义过、“default”是一个默认的定义、“
#"environment"是一个环境变量、
#"file"这个变量被定义在Makefile中
#"command line"这个变量是被命令行定义的
#"override"是被override指示符重新定义的
#"automatic"是一个命令运行中的自动化变量


# Call a source code checker (by default, "sparse") as part of the
# C compilation.调用一个静态分析工具作为c编译器的
#部分
# Use 'make C=1' to enable checking of only re-compiled files.
# Use 'make C=2' to enable checking of *all* source files, regardless
# of whether they are re-compiled or not.
#
# See the file "Documentation/sparse.txt" for more details, including
# where to get the "sparse" utility.
ifdef C
  ifeq ("$(origin C)", "command line")
    KBUILD_CHECKSRC = $(C)
  endif
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif


#用M来指定外部模块的目录
# Use make M=dir to specify directory of external module to build
# Old syntax make ... SUBDIRS=$PWD is still supported
# Setting the environment variable KBUILD_EXTMOD take precedence
#识别这里是定义一个外部模块吗??
#当我们定义了M变量或者SUBDIRS时表示编译一个外部模块

ifdef SUBDIRS
  KBUILD_EXTMOD ?= $(SUBDIRS) #?=为条件赋值操作符仅仅在变量还
  #还没有定义的情况下有效
endif
ifdef M
  ifeq ("$(origin M)", "command line")
    KBUILD_EXTMOD := $(M)
  endif
endif

# kbuild supports saving output files in a separate directory.
# To locate output files in a separate directory two syntaxes are supported.
# In both cases the working directory must be the root of the kernel src.
# 1) O=
# Use "make O=dir/to/store/output/files/"
#
# 2) Set KBUILD_OUTPUT
# Set the environment variable KBUILD_OUTPUT to point to the directory
# where the output files shall be placed.
# export KBUILD_OUTPUT=dir/to/store/output/files/
# make
#
# The O= assignment takes precedence over the KBUILD_OUTPUT environment
# variable.

# KBUILD_SRC is set on invocation of make in OBJ directory
# KBUILD_SRC is not intended to be used by the regular user (for now)
###################make 的最开始###################
####################################################
ifeq ($(KBUILD_SRC),)#如果KBUILD_SRC没有定义则进入下面一层即首次进入
         #时一般都需要两次进入顶层Makefile
         #若定义了则不为空直接跳入下一步
# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
ifdef O #把输出文件放在不同的文件夹内
  ifeq ("$(origin O)", "command line")
    KBUILD_OUTPUT := $(O)  #用于指定我们的输出文件的输出目录
  endif
endif

# That's our default target when none is given on the command line
PHONY := _all
_all:

# Cancel implicit rules on top Makefile取消隐式推倒规则
$(CURDIR)/Makefile Makefile: ;#remake 操作查看当前目录Makefile是否为最新
#CURDIR值为当前的内核源码目录current dir
#为GNU make使用的变量,CURDIR设置当前工作目录的路径名

ifneq ($(KBUILD_OUTPUT),) #如果输出目录不为空即设置了输出目录则检测
# Invoke a second make in the output directory, passing relevant variables
# check that the output directory actually exists
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)#这里是测试此目录是否
            #存在,若存在则赋给K BUILD_OUTPUT
$(if $(KBUILD_OUTPUT),, /#这里的<then-part>为空即表示输出目录不存在
     $(error output directory "$(saved-output)" does not exist))#使用了error函数
#这里的if函数语法为:if<condition>,<then-part>
#或者是if<condition>,<then part>,<else-part>

#make的环境变量叫MAKECMDGOALS 这个变量中会存放你所指定的
#终极目标的列表,如果在命令行上,你没有指定目标,
#那么,这个变量是空值。
PHONY += $(MAKECMDGOALS) sub-make
#将任何在命令行中给出的目标放入变量MAKECMDGOALS
#这里filter-out是返回$(MAKECMDGOALS)中除了Makefile _all sub-make以外的
#其他文件;
$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
$(Q)@:#这里仅仅只是取消回显没有别的意思


#$(KBUILD_VERBOSE:1=)为变量替换,如果为1就替换为空
#if KBUILD_VERBOSE = 1 or KBUILD_VERBOSE is NULL
#then
#$(MAKE) -C $(KBUILD_OUTPUT) //回显
#else
#@ $(MAKE) -C $(KBUILD_OUTPUT)//即不回显
#endif
sub-make: FORCE
$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) /#KBUILD_OUTPUT==dir前面测试了
KBUILD_SRC=$(CURDIR) /
KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile /#
$(filter-out _all sub-make,$(MAKECMDGOALS))#这里是表示要生成的目标
#make -C dir KBUILD_SRC=`pwd` KBUILD_EXTMOD="" -f `pwd`/Makefile [Targets]
#这里表示再次执行Makefile 但此时我们的KBUILD
#此时再次执行完make后skip-makefile := 1从而
# Leave processing to above invocation of make结束子make返回根目录的make
skip-makefile := 1
endif # ifneq ($(KBUILD_OUTPUT),)这里是ifneq
endif # ifeq ($(KBUILD_SRC),)#这里是ifeq的结束处
####################################################
####################################################

ifeq ($(skip-makefile),)#如果为空则开始分类执行!!!!!!
#endif # skip-makefile在1813行处结束最大的ifeq结构
# If building an external module we do not care about the all: rule
# but instead _all depend on modules
PHONY += all       #声明一个伪目标all
ifeq ($(KBUILD_EXTMOD),) #如果外部模块定义为空则_all依赖于all
_all: all                                                               
else
_all: modules                   #否则依赖于modules
endif

srctree  := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))#看KBUILD_SRC是否为空,             #设置源码目录
TOPDIR  := $(srctree)   #顶层目录
# FIXME - TOPDIR is obsolete, use srctree/objtree
objtree  := $(CURDIR)   #CURDIR为make的默认环境变量

src  := $(srctree) #源文件的目录也设置为当前目录        
obj  := $(objtree)#目标文件的输出目录设置当前目录

VPATH  := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
#这里是说当前目录找不到源文件时的搜索目录
export srctree objtree VPATH TOPDIR
#export用于要将指定变量输出给子make,


# SUBARCH tells the usermode build what the underlying arch is.  That is set
# first, and if a usermode build is happening, the "ARCH=um" on the command
# line overrides the setting of ARCH below.  If a native build is happening,
# then ARCH is assigned, getting whatever value it gets normally, and
# SUBARCH is subsequently ignored.
#这里是获取cpu的具体型号存在变量SUBARCH中
#sed -e s表示替换,这里表示出现i.86的用i386替换
#出现sun4u的用sparc64替换
#一般写成sed -e 's/i.86/i386' 用''括起来
SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ /
      -e s/arm.*/arm/ -e s/sa110/arm/ /
      -e s/s390x/s390/ -e s/parisc64/parisc/ /
      -e s/ppc.*/powerpc/ -e s/mips.*/mips/ /
      -e s/sh.*/sh/ )

# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
#
# When performing cross compilation for other architectures ARCH shall be set
# to the target architecture. (See arch/* for the possibilities).
# ARCH can be set during invocation of make:
# make ARCH=ia64
# Another way is to have ARCH set in the environment.
# The default ARCH is the host where make is executed.

# CROSS_COMPILE specify the prefix used for all executables used
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CROSS_COMPILE).
# CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
export KBUILD_BUILDHOST := $(SUBARCH) #这里是把宿主机的cpu结构导出到
           #KBUILD_BUILDHOST变量,并传入子make
ARCH  ?= $(SUBARCH)    
# 设置变量 ARCH 的方法有两种,
# 一:在命令行中 如: make ARCH=ia64 ;
# 二:设置环境变量,在环境变量中默认
#的 ARCH 的值是执行 make 的 cpu 架构
#   "?="表示为ARCH 条件赋值 如果ARCH前面没有赋值则这里赋值
#成功,否则不重新赋值
CROSS_COMPILE ?=                    #交叉编译工具的设置在嵌入式系统
         #经常要修改此处设置交叉编译器的路径

# Architecture as present in compile.h
UTS_MACHINE  := $(ARCH)
SRCARCH  := $(ARCH)

# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
        SRCARCH := x86
endif

ifeq ($(ARCH),x86_64)
        SRCARCH := x86
endif

KCONFIG_CONFIG ?= .config  #这里是生成的配置文件

# SHELL used by kbuild 这里shel中的if [ -x file ]测试file是否可执行
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; /
   else if [ -x /bin/bash ]; then echo /bin/bash; /
   else echo sh; fi ; fi)

HOSTCC       = gcc
HOSTCXX      = g++
HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2

# Decide whether to build built-in, modular, or both.
# Normally, just do built-in.
KBUILD_MODULES :=
KBUILD_BUILTIN := 1

# If we have only "make modules", don't compile built-in objects.编译内置对象
# When we're building modules with modversions, we need to consider
# the built-in objects during the descend as well, in order to
# make sure the checksums are up to date before we record them.

#如果执行”make modules”则这里在这里重新处理KBUILD_BUILTIN :=1
ifeq ($(MAKECMDGOALS),modules)
  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
endif


# If we have "make <whatever> modules", compile modules
# in addition to whatever we do anyway.
# Just "make" or "make all" shall build modules as well


#如果执行"make all","make _all","make modules","make"中任一个命令
#则在这里重新处理KBUILD_MODULES
ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)#filter过滤出指定的字符串
          #这里表示如果不为空则编译模块
  KBUILD_MODULES := 1
endif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值