uboot-Makefile学习(3)

学习目标:

uboot顶层Makefile分析

学习内容:

学习使用了正点原子的I.MX6ULL教程及开发平台。
uboot顶层Makefile分析
1、版本号
2、MAKEFLAGES
3、命令输出
4、静默输出
5、设置编译结果输出目录
6、代码检查
7、模块编译
8、获取主机架构和系统
9、设置目标架构、交叉编译器和配置文件
10、调用scripts/Kbuild.include
11、交叉编译工具变量的设置
12、导出其他变量
13、MAKECMDGOALS变量
14、ARCH、CPU、BOARD、VENDOR、SOC

学习时间:

2022-06-04

学习产出:

1、版本号
顶层Makefile代码中,一开始就是uboot的版本号,如下图所示。
在这里插入图片描述
VERSION是主版本号;
PATCHLEVEL是补丁版本号;
SUBLEVEL是次版本号;
这三个一起构成了uboot的版本号,当前的uboot版本就是2016.03版本。
EXTRAVERSION是附加信息,NAME是和名字相关,一般不使用这两个。
2、MAKEFLAGES
make是支持递归调用的,也就是在makefile中使用make命令执行其他的Makefile文件,这个文件一般都是子目录的Makefile文件。加入在当前目录下有一个subdir子目录,这个目录中又有Makefile文件,那么在工程编译的时候其主目录中的Makefile就可以调用子目录中的Makefile,以此来完成子目录中的Makefile编译。主目录中可以使用如下命令来执行子目录中的Makefile:
$(MAKE) -C subdir
$(MAKE)就是调用make命令,-C是指定子目录。
有时候我们需要向子目录中的Makefile传递变量,就需要使用export来导出要传递给子Makefile的变量。如果不希望某个变量传递给子Makefile的话就需要使用unexport来声明不导出。
export VARIABLE //导出变量VARIABLE给其他子Makefile使用
unexport VARIABLE //不导出变量VARIABLE
这里,在Makefile中有两个特殊的变量:SHELL和MAKEFLAGS,默认情况下这两个变量的值始终导出给子Makefile使用,除非使用unexport声明这两个变量不导出。
在顶层Makefile中有如下代码:
在这里插入图片描述
上述代码中使用+=给变量MAKEFLAGS追加了值,-rR表示禁止使用内置的隐含规则和表达式,–include-dir指明搜索路径.
$(CURDIR)表示当前目录。
3、命令输出
uboot默认在编译时是不会在终端显示完整的命令的,都是短命令。可以在使用make命令时加入V=1来实现完整命令的输出,这在调试uboot的时候很有用。
实现这一块的代码在顶层Makefile中,如下图所示。
在这里插入图片描述
上述代码中先使用ifeq来判断
$(origin V)和command line是否相等。这里用到了Makefile的函数origin,此函数用于告诉变量是哪来的,语法为:
$(origin variable)
variable是变量名,origin的返回值就是变量的来源,因此
$(origin V)就是变量V的来源。如果变量V来源于命令行,就和command line相等。那么变量KBUILD_VERBOSR的值就是V的值,KBUILD_VERBOSR=1。如果命令行没有输入V=1则KBUILD_VERBOSR=0。
下面再判断KBUILD_VERBOSR是否为1,如果为1,那么变量quiet和Q的值都为空;如果KBUILD_VERBOSR的值为0,则quiet的值为quiet_,Q的值为@。
综上所述,
V=1 的话:
KBUILD_VERBOSE=1
quiet= 空 。
Q= 空。
V=0 或者命令行不定义 V 的话:
KBUILD_VERBOSE=0
quiet= quiet_。
Q= @。
可以在编译Makefile时,通过打印查看这些值,编译脚本中是写了V=1的,打印结果如下图所示。
在这里插入图片描述
Makefile中会用到变量quiet和Q来控制编译时是否在终端输出完整的命令,在顶层Makefile中有许多如下命令:
在这里插入图片描述
如果V=0或者在命令行中省略V的话,这行命令展开就是:
@ make $(build)=tools
在这行命令前面加了@就不会在终端上输出命令了。当V=1的时候,Q就为空,上述命令展开就是:
make $(build)=tools
因此,在make执行的过程中,命令会被完整的输出在终端上。
4、静默输出
在使用make命令是加入-s参数,即可实现静默输出功能,即在编译uboot的时候不会输出命令。在顶层Makefile下有如下代码,如图所示。
在这里插入图片描述
这段代码就是实现静默输出功能的,首先判断当前编译器的把那本号是否为4.x。这里用到了Makefile中的函数filter,这是个过滤函数,函数格式如下:
$(filter pattern…,text)
filter函数表示以pattern模式过滤text字符串中的单词,仅保留符合模式pattern的单词,可以有多个模式。函数的返回值就是符合pattern的字符串。因此
在这里插入图片描述
这句话的含义就是在MAKE_VERSION中找出符合4.%(%为通配符)的字符,MAKE_VERSION是make工具的版本号,目前ubuntu16.04中自带的make工具版本号为4.1,可以通过make -v命令查看,如图所示。
在这里插入图片描述
回到顶层Makefile代码中,
在这里插入图片描述
这句话就是不为空的,继续向下判断,
在这里插入图片描述
这里又用到了一个新的函数firstword,函数firstword用于获取首单词,函数格式如下:
$(firstword text)
firstword用于取出text字符串中的第一个单词,函数的返回值就是获取到的单词,在使用make -s编译的时候,-s会作为MAKEFLAGS变量的一部分传递给Makefile。在顶层Makefile中添加如下打印代码。
在这里插入图片描述
注意!要在make时加入-s。
回到顶层Makefile,因此判断条件成立,不为空。当加入-s参数在make时,quiet=silent_。
最后一行导出环境变量。
最后去掉-s参数,方便查看make编译时的信息,目前导出的环境变量值如下。
在这里插入图片描述
5、设置编译结果输出目录
uboot可以将编译出来的目标文件输出到指定的目录中,在make时使用-0=dir来指定,就是设置目标文件输出到dir目录中。这么做的目的是为了将源文件和编译产生的文件分开,当然如果不指定的话,编译产生的文件和源文件都将在同一个目录内,一般我们不会指定-O参数。实现这一部分的顶层Makefile代码如下。
在这里插入图片描述
首先通过打印可以知道KBUILD_SRC的值为空,然后判断O是否来源于命令行,如果来源于命令行,条件成立,KBUILD_OUTPUT的值就为
$(O),我们未设置-O,因此KBUILD_OUTPUT的值为空。
下面再判断KBUILD_OUTPUT是否为空,如果不为空的话saved-output的值就是KBUILD_OUTPUT的值,且根据KBUILD_OUTPUT的值创建目录,至此,通过-O指定的目录就会存在。
6、代码检查

uboot支持代码检查,使用命令make C=1使能代码检查,检查那些需要重新编译的文件。make C=2用于检查所有的源文件,顶层Makefile中的代码如下:
在这里插入图片描述
首先判断C是否来源于命令行,如果C来源于命令行那么就将C的值赋值给KBUILD_CHECKSRC,如果没有的话,KBUILD_CHECKSRC的值就为0。
7、模块编译
在uboot中允许单独编译某个模块,使用命令make M=dir即可,就的语法make SUBDIRS=dir也是支持的。顶层Makefile有如下代码:
在这里插入图片描述
首先判断是否定义了SUBDIRS,如果定义了SUBDIRS,变量KBUILD_EXTMOD的值就是SUBDIRS的值,这是为了支持老语法。
下面继续判断M是否来源于命令行,来源于命令行的话,KBUILD_EXTMOD的值就是M的值。
再判断KBUILD_EXTMOD是否为空,为空的话继续执行下面。默认目标_all依赖于all,因此会先编译出all。不为空的话,默认目标_all依赖于modules,要先编译出modules,也就是模块编译。一般情况下,不会再uboot中使用模块编译。所以会先编译all这个目标。
下面判断KBUILD_SRC是否为空,如果为空的话就设置变量srctree为当前目录,即srctree为.,一般也不设置KBUILD_SRC。
下面设置objtree为.。src和obj也为.。设置VPATH的值,然后导出环境变量。
导出的环境变量的值如下图所示。
在这里插入图片描述
8、获取主机架构和系统
接下来顶层Makefile会获取ubuntu的主机架构和系统,有如下代码。
在这里插入图片描述
定义了一个变量HOSTARCH用于保存主机架构,这里调用shell命令uname -m获取主机架构,如图所示。
在这里插入图片描述
可以看出当前主机架构是x86_64的。shell中的 | 表示管道,意思是将左边的输出作为右边的输入,sed -e是替换命令,“sed -e s/i.86/x86”表示将管道输入的字符串中的i.86替换为x86。当前此主机架构就为HOSTARCH=x86_64。
定义变量HOSTOS用来保存主机的操作系统,先使用shell命令获取主机的操作系统,如下图所示。
在这里插入图片描述
可以看出当前主机的操作系统为Linux,"tr ‘[:upper]’‘[:lower:]’"表示将所有的大写字母替换为小写字母,因此HOSTOS的值为linux。
最后导出HOSTARCH为x86_64,HOSTOS为linux。
9、设置目标架构、交叉编译器和配置文件
在编译uboot的时候需要设置目标板的架构和交叉编译器,“make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-”,就是用于设置ARCH和CROSS_COMPILE的值,再顶层Makefile中代码如下。
在这里插入图片描述
首先判断HOSTARCH和ARCH是否相等,主机的HOSTARCH是x86_64,ARCH是arm,肯定不相等。所以CROSS_COMPILE=arm-linux-gnueabihf-。这里我们也可以在顶层Makefile中直接设置ARCH和CROSS_COMPILE的值,这样就不用在每次make时设置这两个变量的值,如图所示。
在这里插入图片描述
下面定义变量KCONFIG_CONFIG的值为.config,uboot是可以配置的,这里的配置文件就是.config,.config文件默认是没有的,需要使用命令make xxx_defcong,对uboot配置生成.config文件。默认情况下,.config文件和xxx_defconfig内容是一样的,因为.config文件就是从xxx_defconfg文件复制过来的。如果后面Makefile在配置过程中调整了一些参数,这些调整的参数就会写道.config文件中,而不是xxx_defconfig文件中。相当于xxx_defconfig只是一些初始参数的配置,而.config中才是实时有效的配置。
10、调用scripts/Kbuild.include
顶层Makefile会调用文件scripts/Kbuild.include文件,代码如下。
在这里插入图片描述
上图中使用include包含了文件scripts/Kbuild.include,此文件中定义了很多变量,如图所示。
在这里插入图片描述
在uboot编译的过程中会用到这些变量。
11、交叉编译工具变量的设置
在上面设置交叉编译器的时候,只是设置了CROSS_COMPILE的名字,但是交叉编译器的其他工具都还没有设置,顶层Makefile下有如下代码。
在这里插入图片描述
12、导出其他变量
接下来Makefile会导出大量的变量,代码如下:
在这里插入图片描述
将uboot需要打印的环境变量全部打印出其值。
在顶层Makefile中最后中加入打印信息。

info:
	$(info MAKEFLAGS=$(MAKEFLAGS))
	$(info SHELL=$(SHELL))
	$(info LC_COLLATE =$(LC_COLLATE))
	$(info LC_NUMERIC=$(LC_NUMERIC))
	$(info quiet =$(quiet))
	$(info Q=$(Q))
	$(info KBUILD_VERBOSE=$(KBUILD_VERBOSE))
	$(info srctree =$(srctree))
	$(info objtree=$(objtree))
	$(info VPATH=$(VPATH))
	$(info HOSTARCH =$(HOSTARCH))
	$(info HOSTOS=$(HOSTOS))
	$(info KCONFIG_CONFIG=$(KCONFIG_CONFIG))
	$(info KBUILD_MODULES =$(KBUILD_MODULES))
	$(info KBUILD_BUILTIN=$(KBUILD_BUILTIN))
	$(info KBUILD_CHECKSRC =$(KBUILD_CHECKSRC))
	$(info KBUILD_SRC =$(KBUILD_SRC))
	$(info KBUILD_EXTMOD=$(KBUILD_EXTMOD))
	$(info VERSION =$(VERSION))
	$(info PATCHLEVEL =$(PATCHLEVEL))
	$(info SUBLEVEL  =$(SUBLEVEL))
	$(info UBOOTRELEASE =$(UBOOTRELEASE))
	$(info UBOOTVERSION=$(UBOOTVERSION))
	$(info ARCH =$(ARCH))
	$(info CPU =$(CPU))
	$(info BOARD =$(BOARD))
	$(info VENDOR =$(VENDOR))
	$(info SOC=$(SOC))
	$(info CPUDIR =$(CPUDIR))
	$(info BOARDDIR=$(BOARDDIR))
	$(info CONFIG_SHELL =$(CONFIG_SHELL))
	$(info HOSTCC =$(HOSTCC))
	$(info HOSTCFLAGS =$(HOSTCFLAGS))
	$(info HOSTLDFLAGS =$(HOSTLDFLAGS))
	$(info CROSS_COMPILE =$(CROSS_COMPILE))
	$(info AS =$(AS))
	$(info LD =$(LD))
	$(info CC=$(CC))
	$(info CPP =$(CPP))
	$(info AR=$(AR))
	$(info NM =$(NM))
	$(info LDR =$(LDR))
	$(info STRIP=$(STRIP))
	$(info OBJCOPY =$(OBJCOPY))
	$(info OBJDUMP =$(OBJDUMP))
	$(info MAKE  =$(MAKE))
	$(info AWK  =$(AWK))
	$(info PERL  =$(PERL))
	$(info PYTHON =$(PYTHON))
	$(info HOSTCXX  =$(HOSTCXX))
	$(info HOSTCXXFLAGS  =$(HOSTCXXFLAGS))
	$(info DTC  =$(DTC))
	$(info CHECK =$(CHECK))
	$(info CHECKFLAGS =$(CHECKFLAGS))
	$(info KBUILD_CPPFLAGS  =$(KBUILD_CPPFLAGS))
	$(info NOSTDINC_FLAGS  =$(NOSTDINC_FLAGS))
	$(info UBOOTINCLUDE  =$(UBOOTINCLUDE))
	$(info OBJCOPYFLAGS  =$(OBJCOPYFLAGS))
	$(info LDFLAGS =$(LDFLAGS))
	$(info KBUILD_CFLAGS  =$(KBUILD_CFLAGS))
	$(info KBUILD_AFLAGS =$(KBUILD_AFLAGS))
	$(info MODVERDIR  =$(MODVERDIR))
	$(info RCS_FIND_IGNORE  =$(RCS_FIND_IGNORE))
	$(info RCS_TAR_IGNORE  =$(RCS_TAR_IGNORE))
	$(info KBUILD_DEFCONFIG =$(KBUILD_DEFCONFIG))
	$(info KBUILD_KCONFIG =$(KBUILD_KCONFIG))
	$(info PLATFORM_LIBS =$(PLATFORM_LIBS))
	$(info PLATFORM_LIBGCC =$(PLATFORM_LIBGCC))
	$(info HOST_TOOLS_ALL=y =$(HOST_TOOLS_ALL=y))
	$(info CROSS_BUILD_TOOLS=y =$(CROSS_BUILD_TOOLS=y))

然后将编译的脚本文件修改为:

  #!/bin/bash
  make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
  make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mx6ull_14x14_ddr512_emmc_defconfig
  #make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j12
  make V=1 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- info

执行此脚本,如下所示。

MAKEFLAGS=rR -I/home/maqinggong/linux/IMX6ULL/uboot/alientek_uboot --no-print-directory -- CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm V=1
SHELL=/bin/sh
LC_COLLATE =C
LC_NUMERIC=C
quiet =
Q=
KBUILD_VERBOSE=1
srctree =.
objtree=.
VPATH=.
HOSTARCH =x86_64
HOSTOS=linux
KCONFIG_CONFIG=.config
KBUILD_MODULES =
KBUILD_BUILTIN=1
KBUILD_CHECKSRC =0
KBUILD_SRC =
KBUILD_EXTMOD=
VERSION =2016
PATCHLEVEL =03
SUBLEVEL  =
UBOOTRELEASE =
UBOOTVERSION=2016.03
ARCH =arm
CPU =armv7
BOARD =mx6ullevk
VENDOR =freescale
SOC=mx6
CPUDIR =arch/arm/cpu/armv7
BOARDDIR=freescale/mx6ullevk
CONFIG_SHELL =/bin/bash
HOSTCC =cc
HOSTCFLAGS =-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTLDFLAGS =
CROSS_COMPILE =arm-linux-gnueabihf-
AS =arm-linux-gnueabihf-as
LD =arm-linux-gnueabihf-ld.bfd
CC=arm-linux-gnueabihf-gcc
CPP =arm-linux-gnueabihf-gcc -E
AR=arm-linux-gnueabihf-ar
NM =arm-linux-gnueabihf-nm
LDR =arm-linux-gnueabihf-ldr
STRIP=arm-linux-gnueabihf-strip
OBJCOPY =arm-linux-gnueabihf-objcopy
OBJDUMP =arm-linux-gnueabihf-objdump
MAKE  =make
AWK  =awk
PERL  =perl
PYTHON =python
HOSTCXX  =c++
HOSTCXXFLAGS  =-O2
DTC  =dtc
CHECK =sparse
CHECKFLAGS =-D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise -Wno-return-void -D__CHECK_ENDIAN__   -nostdinc -isystem /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/include
KBUILD_CPPFLAGS  =-D__KERNEL__ -D__UBOOT__ 
NOSTDINC_FLAGS  = -nostdinc -isystem /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4/include
UBOOTINCLUDE  =-Iinclude   -I./arch/arm/include -include ./include/linux/kconfig.h
OBJCOPYFLAGS  = -j .text -j .secure_text -j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn
LDFLAGS = 
KBUILD_CFLAGS  =-Wall -Wstrict-prototypes -Wno-format-security -fno-builtin -ffreestanding -Os -fno-stack-protector -fno-delete-null-pointer-checks -g -fstack-usage -Wno-format-nonliteral -Werror=date-time 
KBUILD_AFLAGS =-D__ASSEMBLY__ -g 
MODVERDIR  =.tmp_versions
RCS_FIND_IGNORE  =\( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
RCS_TAR_IGNORE  =--exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
KBUILD_DEFCONFIG =
KBUILD_KCONFIG =
PLATFORM_LIBS =arch/arm/lib/eabi_compat.o  -L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4 -lgcc
PLATFORM_LIBGCC =-L /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/4.9.4 -lgcc
HOST_TOOLS_ALL=y =
CROSS_BUILD_TOOLS=y =

13、MAKECMDGOALS变量
此变量是makefile中的一个特殊变量,该变量保存了命令行参数指定的终极目标列表,没有指定目标时,该变量为空。
在顶层makefile中有如下代码。

no-dot-config-targets := clean clobber mrproper distclean \
			 help %docs check% coccicheck \
			 ubootversion backup
$(info #########################1#############################)
$(info no-dot-config-targets=$(no-dot-config-targets))
$(info MAKECMDGOALS=$(MAKECMDGOALS))

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

ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
		dot-config := 0
	endif
endif
$(info dot-config=$(dot-config))
$(info KBUILD_EXTMOD=$(KBUILD_EXTMOD))

ifeq ($(KBUILD_EXTMOD),)
        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
                config-targets := 1
                ifneq ($(words $(MAKECMDGOALS)),1)
                        mixed-targets := 1
                endif
        endif
endif
$(info config-targets=$(config-targets))
$(info mixed-targets=$(mixed-targets))

ifeq ($(mixed-targets),1)
# ===========================================================================
# We're called with mixed targets (*config and build targets).
# Handle them one by one.

PHONY += $(MAKECMDGOALS) __build_one_by_one

$(filter-out __build_one_by_one, $(MAKECMDGOALS)): __build_one_by_one
	@:

__build_one_by_one:
	$(Q)set -e; \
	for i in $(MAKECMDGOALS); do \
		$(MAKE) -f $(srctree)/Makefile $$i; \
	done

else
ifeq ($(config-targets),1)
# ===========================================================================
# *config targets only - make sure prerequisites are updated, and descend
# in scripts/kconfig to make the *config target

KBUILD_DEFCONFIG := sandbox_defconfig
export KBUILD_DEFCONFIG KBUILD_KCONFIG

config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

%config: scripts_basic outputmakefile FORCE
	$(Q)$(MAKE) $(build)=scripts/kconfig $@

else
# ===========================================================================
# Build targets only - this includes vmlinux, arch specific targets, clean
# targets and others. In general all targets except *config targets.

ifeq ($(dot-config),1)
# Read in config
-include include/config/auto.conf

# Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected.
-include include/config/auto.conf.cmd

# 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 files
include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
	@# If the following part fails, include/config/auto.conf should be
	@# deleted so "make silentoldconfig" will be re-run on the next build.
	$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf || \
		{ rm -f include/config/auto.conf; false; }
	@# include/config.h has been updated after "make silentoldconfig".
	@# We need to touch include/config/auto.conf so it gets newer
	@# than include/config.h.
	@# Otherwise, 'make silentoldconfig' would be invoked twice.
	$(Q)touch include/config/auto.conf

-include include/autoconf.mk
-include include/autoconf.mk.dep

# We want to include arch/$(ARCH)/config.mk only when include/config/auto.conf
# is up-to-date. When we switch to a different board configuration, old CONFIG
# macros are still remaining in include/config/auto.conf. Without the following
# gimmick, wrong config.mk would be included leading nasty warnings/errors.
ifneq ($(wildcard $(KCONFIG_CONFIG)),)
ifneq ($(wildcard include/config/auto.conf),)
autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \
						include/config/auto.conf)
$(info autoconf_is_old=$(autoconf_is_old))						
ifeq ($(autoconf_is_old),)
$(info ##########################################2################################################)
include config.mk
include arch/$(ARCH)/Makefile
endif
endif
endif

变量no-dot-config-targets保存的值为:
clean clobber mrproper distclean
help %docs check% coccicheck
ubootversion backup
变量config-targets的初值为0;
变量mixed-targets的初值为0;
变量dot-config的初值为1。
(1)、make distclean
在执行此条命令时,因为MAKECMDGOALS保存的是命令行的目标,所以其值为distclean。则下面

ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)

此条语句,从MAKECMDGOALS中过滤处符合no-dot-config-targets的值,很明显distclean在变量no-dot-config-targets中,结果不为空。继续执行下面的语句。

ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)

这条语句判断MAKECMDGOALS中除了符合变量no-dot-config-targets中的值外还有没有其他的目标,很明显目标中除了distclean没有其它的目标了,此处条件成立。所以下面dot-config := 0
KBUILD_EXTMOD用于模块编译,当前未使用,其值为空,则ifeq ($(KBUILD_EXTMOD),)成立,继续向下执行ifneq ($(filter config %config,$(MAKECMDGOALS)),),这里将MAKECMDGOALS中符合config和%config的部分过滤出来,如果不为空继续执行,此处为空,不执行剩下的两个判断。
到此为止,
dot-config=0;
config-targets=0;
mixed-targets=0。
下面判断ifeq ($(mixed-targets),1),很明显不相等,不执行ifeq条件里面的语句。继续判断else ifeq ($(config-targets),1),很明显也不相等,继续下一个语句else ifeq ($(dot-config),1),很明显也不相等。
至此上面的这块代码在在make clean时结束。
(2)、make mx6ull_14x14_ddr512_emmc_defconfig
执行此条配置命令时,这条语句ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),),因为MAKECMDGOALS的值为mx6ull_14x14_ddr512_emmc_defconfig,在变量no-dot-config-targets中没有与之匹配的,所以不会执行语句内的内容,因此变量dot-config值仍为1。
之后判断ifeq ($(KBUILD_EXTMOD),),条件成立,继续执行ifneq ($(filter config %config,$(MAKECMDGOALS)),),条件成立,使config-targets的值为1,然后执行ifneq ($(words $(MAKECMDGOALS)),1),这条语句统计MAKECMDGOALS中的单词个数,MAKECMDGOALS中的单词个数为1,条件不成立。
至此,
config-targets=1;
mixed-targets=0。
下面执行ifeq ($(mixed-targets),1),条件不成立,继续判断else ifeq ($(config-targets),1),条件成立,执行其中的语句,里面的语句详解,请看后面一篇make xxx_defconfig的分析。
(3)、make
首先判断ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),),很明显条件不成立,此时dot-config=1。接下来判断ifeq ($(KBUILD_EXTMOD),),是否为空,条件成立。再判断ifneq ($(filter config %config,$(MAKECMDGOALS)),),条件不成立,config-targets=0,mixed-targets=0。然后判断ifeq ($(mixed-targets),1),条件不成立,继续判断else ifeq ($(config-targets),1),条件不成立,继续判断else ifeq ($(dot-config),1),条件成立,进入执行ifneq ($(wildcard $(KCONFIG_CONFIG)),),这句话是判断是否存在.config文件,条件成立,继续判断ifneq ($(wildcard include/config/auto.conf),),是否存在auto.conf,条件成立,继续。autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \ include/config/auto.conf),这句话当.config文件比include/config/auto.conf新的时候,autoconf_is_old 为.config,否则为空。因为.config文件在配置uboot的时候已经生成,而include/config/auto.conf文件是在执行语句$(Q)touch include/config/auto.conf时刚生成的,所以autoconf_is_old的值为空。继续判断语句ifeq ($(autoconf_is_old),),条件成立,继续执行语句include config.mkinclude arch/$(ARCH)/Makefile,这里的ARCH的值就是arm。
综上,在执行make编译时,包含了文件config.mk和arch/arm/Makefile。

14、ARCH、CPU、BOARD、VENDOR、SOC
之前使用make命令在打印makefile中导出的变量值时,会发现ARCH、CPU、BOARD、VENDOR和SOC并没有子makefile中被赋值。
注意!!这几个环境变量的值只有在完成make xxx_defconfig,然后再make时才可正确打印,因为几个导出的变量需要在配置时生成的.config文件和在make时包含的config.mk文件。
前面已经分析过,在make时会包含config.mk文件,通过配置生成.config文件的过程下一篇会写,这里先知道有这个事情。
在config.mk文件中,有如下代码:

ARCH := $(CONFIG_SYS_ARCH:"%"=%)
CPU := $(CONFIG_SYS_CPU:"%"=%)
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_TEGRA
CPU := arm720t
endif
endif
BOARD := $(CONFIG_SYS_BOARD:"%"=%)
ifneq ($(CONFIG_SYS_VENDOR),)
VENDOR := $(CONFIG_SYS_VENDOR:"%"=%)
endif
ifneq ($(CONFIG_SYS_SOC),)
SOC := $(CONFIG_SYS_SOC:"%"=%)
endif
CPUDIR=arch/$(ARCH)/cpu$(if $(CPU),/$(CPU),)

定义ARCH变量时,值为$(CONFIG_SYS_ARCH:“%”=%),也就是提取CONFIG_SYS_ARCH里面双引号之间的内容,然后赋值给ARCH。比如CONFIG_SYS_ARCH的值为“arm”,那么,ARCH=arm。
同理,

CPU := $(CONFIG_SYS_CPU:"%"=%)
BOARD := $(CONFIG_SYS_BOARD:"%"=%)
VENDOR := $(CONFIG_SYS_VENDOR:"%"=%)
SOC := $(CONFIG_SYS_SOC:"%"=%)
CPUDIR=arch/$(ARCH)/cpu$(if $(CPU),/$(CPU),)

那么接下来需要确认,CONFIG_SYS_ARCH、CONFIG_SYS_CPU、CONFIG_SYS_BOARD、CONFIG_SYS_VENDOR、CONFIG_SYS_SOC这五个的值。这五个变量的值在.config中有定义,

CONFIG_SYS_ARCH="arm"
CONFIG_SYS_CPU="armv7"
CONFIG_SYS_SOC="mx6"
CONFIG_SYS_VENDOR="freescale"
CONFIG_SYS_BOARD="mx6ullevk"

由此,
ARCH = arm
CPU = armv7
BOARD = mx6ullevk
VENDOR = freescale
SOC = mx6
CPUDIR = arch/arm/cpu/armv7
BOARDDIR = freescale/mx6ullevk

在 config.mk 中读取的文件有:
arch/arm/config.mk
arch/arm/cpu/armv7/config.mk
arch/arm/cpu/armv7/mx6/config.mk (此文件不存在)
board/ freescale/mx6ullevk/config.mk (此文件不存在)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值