makefile-5.3.12

构建顺序

make menuconfig
menuconfig

代码分析

版本号等的定义,并将默认目标定义好,即_all,最后通过_all的依赖项决定到编译哪个目标。

VERSION = 5
PATCHLEVEL = 3
SUBLEVEL = 12
EXTRAVERSION =
NAME = Bobtail Squid

PHONY := _all
_all:

linux的编译可以指定输出路径的,如果自行指定输出路径,则会在对应路径再次运行make。所以会分为两步进行。同样的,即使不指定输出路径,也会进行两步。分别为make和sub-make。make是用户自行调用的,sub-make是由make调用的在输出路径下的make。

路径确定

# sub_make_done表示当前是否正在进行sub-make
# need-sub-make表示当前make是否需要进行sub-make
ifneq ($(sub_make_done),1)
# 不让make使用隐式规则,这样避免一些难以确定的问题。
MAKEFLAGS += -rR

# 字符集定义
unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC

# 避免环境变量的影响
unexport GREP_OPTIONS

# 通过一些小手段来控制输出的详细程度
ifeq ("$(origin V)", "command line")
  KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSE
  KBUILD_VERBOSE = 0
endif

ifeq ($(KBUILD_VERBOSE),1)
  quiet =
  Q =
else
  quiet=quiet_
  Q = @
endif

ifneq ($(findstring s,$(filter-out --%,$(MAKEFLAGS))),)
  quiet=silent_
endif
export quiet Q KBUILD_VERBOSE

# 指定的输出目录,通过make O=...传入
ifeq ("$(origin O)", "command line")
  KBUILD_OUTPUT := $(O)
endif

ifneq ($(KBUILD_OUTPUT),)
# 保证输出目录存在
abs_objtree := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd)
$(if $(abs_objtree),, \
     $(error failed to create output directory "$(KBUILD_OUTPUT)"))

abs_objtree := $(realpath $(abs_objtree))
else
abs_objtree := $(CURDIR)
endif # ifneq ($(KBUILD_OUTPUT),)

ifeq ($(abs_objtree),$(CURDIR))
MAKEFLAGS += --no-print-directory
else
need-sub-make := 1
endif
# 通过Makefile的路径来确定源码目录,并保证目录没有":"和空格
abs_srctree := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
ifneq ($(words $(subst :, ,$(abs_srctree))), 1)
$(error source directory cannot contain spaces or colons)
endif
# 如果源码目录跟输出目录不同,则需要sub-make
ifneq ($(abs_srctree),$(abs_objtree))
MAKEFLAGS += --include-dir=$(abs_srctree)
need-sub-make := 1
endif
# make 3.x的'MAKEFLAGS += -rR'并不是立马生效 ,所以需要sub-make来屏蔽隐式规则,同时屏蔽当前makefile的隐式规则
ifneq ($(filter 3.%,$(MAKE_VERSION)),)
need-sub-make := 1
$(lastword $(MAKEFILE_LIST)): ;
endif

取消回显没有别的export abs_srctree abs_objtree
export sub_make_done := 1

ifeq ($(need-sub-make),1)

PHONY += $(MAKECMDGOALS) sub-make
$(filter-out _all sub-make $(lastword $(MAKEFILE_LIST)), $(MAKECMDGOALS)) _all: sub-make
	@:
# 在输出目录下调用make
sub-make:
	$(Q)$(MAKE) -C $(abs_objtree) -f $(abs_srctree)/Makefile $(MAKECMDGOALS)

endif # need-sub-make
endif # sub_make_done

正式编译

如果不需要sub-make,则当前的make调用需要进行真正的编译操作。

ifeq ($(need-sub-make),)
...
endif   # need-sub-make
MAKEFLAGS += --no-print-directory
# C=1只检查需要重新编译的文件
# C=2 检查所有的文件
ifeq ("$(origin C)", "command line")
  KBUILD_CHECKSRC = $(C)
endif
ifndef KBUILD_CHECKSRC
  KBUILD_CHECKSRC = 0
endif

确定M的值,确定需要编译的外部模块

ifeq ("$(origin M)", "command line")
  KBUILD_EXTMOD := $(M)
endif
export KBUILD_CHECKSRC KBUILD_EXTMOD

确定源码路径

ifeq ($(abs_srctree),$(abs_objtree))
        # building in the source tree
        srctree := .
	building_out_of_srctree :=
else
        ifeq ($(abs_srctree)/,$(dir $(abs_objtree)))
                # building in a subdirectory of the source tree
                srctree := ..
        else
                srctree := $(abs_srctree)
        endif
	building_out_of_srctree := 1
endif

ifneq ($(KBUILD_ABS_SRCTREE),)
srctree := $(abs_srctree)
endif

objtree		:= .
VPATH		:= $(srctree)

export building_out_of_srctree srctree objtree VPATH
version_h := include/generated/uapi/linux/version.h
old_version_h := include/linux/version.h
# 清理用的target
clean-targets := %clean mrproper cleandocs
# 不需要依赖.config的target
no-dot-config-targets := $(clean-targets) \
			 cscope gtags TAGS tags help% %docs check% coccicheck \
			 $(version_h) headers headers_% archheaders archscripts \
			 %asm-generic kernelversion %src-pkg
# 不需要同步config的target
no-sync-config-targets := $(no-dot-config-targets) install %install \
			   kernelrelease

config-targets  := 0
mixed-targets   := 0
dot-config      := 1
may-sync-config := 1

# 确定是否需要依赖.config
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
		dot-config := 0
	endif
endif
# 确定是否需要同步config
ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)
	ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)
		may-sync-config := 0
	endif
endif
# 如果是构建外部模块,则不需要同步config
ifneq ($(KBUILD_EXTMOD),)
	may-sync-config := 0
endif
# 确定是不是config 与build的混合目标
ifeq ($(KBUILD_EXTMOD),)
        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                config-targets := 1
                ifneq ($(words $(MAKECMDGOALS)),1)
                        mixed-targets := 1
                endif
        endif
endif
# 如 "make -j clean all", "make -j mrproper defconfig all"等,清理target与非清理target也是混合目标
ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)
        ifneq 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值