u-boot的makefile中的一些目录的设定,以及涉及的shell,make语法。

分析U-boot的makefile时,需要确定一些文件的位置,BUILD_DIR,SRCTREE,TOPDIR,LNDIR,obj,src。

首先分析BUILD_DIR是怎么确定的——

指定输出目录有两种方法,分别为make O=dir或者export BUILD_DIR=dir。两种方式指定如果没有指定,则设定为源码的根目录。

By default the build is performed locally and the objects are saved
in the source directory. One of the two methods can be used to change
this behavior and build U-Boot to some external directory:

1. Add O= to the make command line invocations:

    make O=/tmp/build distclean
    make O=/tmp/build NAME_config
    make O=/tmp/build all

2. Set environment variable BUILD_DIR to point to the desired location:

    export BUILD_DIR=/tmp/build
    make distclean
    make NAME_config
    make all

makefile通过以下确定BUILD_DIR的

ifdef O                                   
ifeq ("$(origin O)", "command line")         #命令行里有“O”
BUILD_DIR := $(O)                            #BUILD_DIR指定为命令中的目录
endif
endif

ifneq ($(BUILD_DIR),)                       #如果BUILD_DIR有定义 不等于空
saved-output := $(BUILD_DIR)                #saved-output保存$(BUILD_DIR)

# Attempt to create a output directory.
$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
#此条命令——检测BUILD_DIR是否是一个目录,如果不存在则创建这个BUILD_DIR对应的目录
#[]和test测试命令一样,Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试;
#-d的作用——如果文件存在且为目录则为真;
#||运算符——如果||左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2);或者换句话说,“如果这个命令执行失败了||那么就执行这个命令。 #mkdir的-p参数——需要时创建上层目录,如目录早已存在则不当作错误,例如,我们要在当前目录创建目录Projects/a/src,
#使用命令mkdir -p Project/a/src,例如想要建立目录Project,其中含有4个文件夹a, b, c, d,且这4个文件都含有一个src文件夹。
#
使用命令mkdir -p Project/{a,b,c,d}/src

# Verify
if it was successful. BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)
#如果能cd $(BUILD_DIR),则输出这个目录的路径
#&&运算符——左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;
#换句话说,“如果这个命令执行成功&&那么执行这个命令”。 $(
if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
#检测BUILD_DIR是否为空,如果为空则提示错误并终止make
#if函数——$(if CONDITION,THEN-PART[,ELSE-PART]).如果“CONDITION”的展开结果非空,则将第二个
#参数“THEN-PART”作为函数计算表达式;“CONDITION”的展开结果为空,则执行第三个参数。
#error——$(error TEXT...)产生致命错误,并提示“TEXT...”信息给用户,并退出make执行,没有返回值。 endif # ifneq ($(BUILD_DIR),)

OBJTREE        := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
#如果定义了BUILD_DIR则OBJTREE=$(BUILD_DIR),否则=$(CURDIR)
SRCTREE        := $(CURDIR) #源目录为$(CURDIR)
TOPDIR        := $(SRCTREE) #顶层目录为$(CURDIR)
LNDIR        := $(OBJTREE) #链接目录为$(CURDIR)
export    TOPDIR SRCTREE OBJTREE

MKCONFIG    := $(SRCTREE)/mkconfig
export MKCONFIG

ifneq ($(OBJTREE),$(SRCTREE))
REMOTE_BUILD     := 1
export REMOTE_BUILD
endif

# $(obj) and (src) are defined in config.mk but here in main Makefile
# we also need them before config.mk is included which is the case for
# some targets like unconfig, clean, clobber, distclean, etc.
ifneq ($(OBJTREE),$(SRCTREE)) #如果$(OBJTREE)不等于$(SRCTREE)
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src
懒惰不会让你一下子跌到 但会在不知不觉中减少你的收获; 勤奋也不会让你一夜成功 但会在不知不觉中积累你的成果 越努力,越幸运。
原文地址:https://www.cnblogs.com/Rainingday/p/7661937.html