2.4.uboot配置和编译过程详解(2021-4-18)

本文详细解析了 U-Boot 的 Makefile 构造,包括版本号定义、编译环境配置、目标文件管理和编译流程。重点介绍了如何通过 Makefile 控制编译流程、配置开发板参数以及自定义编译选项。

2.4.1、uboot主Makefile分析1

2.4.1.1、uboot version确定(Makefile的24-29行)

在这里插入图片描述

//uboot中的Makefile部分代码
VERSION = 1          //主版本号   Makefile定义和使用变量,直接定义和使用,引用变量时用%var
PATCHLEVEL = 3       //次版本号   Mkaefile不要求赋值运算符两边一定要有空格或者无空格
SUBLEVEL = 4         //再次版本号
EXTRAVERSION =       //附加的版本信息
U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)   //最终版本号

//version_autogenerated.h在uboot的头文件include下面
///root/x210v3_bsp/uboot/include
//用=赋值的变量,在被解析时他的值取决于最后一次赋值时的值,
//所以你看变量引用时的值不能只往前面看,还要往后面看
VERSION_FILE = $(obj)include/version_autogenerated.h        //=往后面找

2.4.1.2、HOSTARCH和HOSTOS

在这里插入图片描述

//uname -m:得到当前CPU的版本号
root@xfj-virtual-machine:/mnt/hgfs/winshare/s5pv210/uboot/4.makefile/4.1# uname -m
x86_64

//uname -s: 显示当前内核名称
root@xfj-virtual-machine:/mnt/hgfs/winshare/s5pv210/uboot/4.makefile/4.1# uname -s
Linux


#var=`pwd`

#var=$(shell pwd)

# X86_64
HOSTARCH := $(shell uname -m | \
        sed -e s/i.86/i386/ \
            -e s/sun4u/sparc64/ \
            -e s/arm.*/arm/ \
            -e s/sa110/arm/ \
            -e s/powerpc/ppc/ \
            -e s/ppc64/ppc/ \
            -e s/macppc/ppc/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
            sed -e 's/\(cygwin\).*/cygwin/')

all:
        #echo $(var)
        echo $(HOSTARCH)
        echo $(HOSTOS)

//uboot中的Makefile部分代码
HOSTARCH := $(shell uname -m | \
	sed -e s/i.86/i386/ \
	    -e s/sun4u/sparc64/ \
	    -e s/arm.*/arm/ \
	    -e s/sa110/arm/ \
	    -e s/powerpc/ppc/ \
	    -e s/ppc64/ppc/ \
	    -e s/macppc/ppc/)

HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \
	    sed -e 's/\(cygwin\).*/cygwin/')
//Makefile中用export导出的就是环境变量。
//环境变量类似于整个工程中所有Makefile之间可以共享的全局变量
//定义了一个环境变量会影响工程中别的Makefile文件
export	HOSTARCH HOSTOS                                     //导出环境变量

2.4.2、uboot主Makefile分析2

2.4.2.1、静默编译(50-54行)

在这里插入图片描述

#########################################################################
# Allow for silent builds        允许静默编译
ifeq ( , $(findstring s,$(MAKEFLAGS)))    
XECHO = echo                     //如果在输入的命令行中MAKEFLAGS中没有找到s,其为空,与前面的相等,执行此句
else
XECHO = :                        //如果在输入的命令行中在MAKEFLAGS中找到s,其不为空,与前面的不相等,执行此句
endif

#########################################################################

2.4.2.2、2种编译方法(原地编译和单独输出文件夹编译)

在这里插入图片描述

#########################################################################
#
# U-boot build supports producing a object files to the separate external
# directory. Two use cases are supported:
# U-boot构建支持在单独的外部目录中生成目标文件。支持两种用例:
#
# 1) Add O= to the make command line  将O =添加到生成命令行
# 'make O=/tmp/build all'
#
# 2) Set environement variable BUILD_DIR to point to the desired location
# 将环境变量BUILD_DIR设置为指向所需位置
# 'export BUILD_DIR=/tmp/build'       设置方法
# 'make'
#
# The second approach can also be used with a MAKEALL script  
# 第二种方法也可以用于MAKEALL脚本
# 'export BUILD_DIR=/tmp/build'
# './MAKEALL'
#
# Command line 'O=' setting overrides BUILD_DIR environent variable.
# 命令行“O=”设置覆盖BUILD_DIR环境变量。
#
# When none of the above methods is used the local build is performed and
# the object files are placed in the source directory.
# 当不使用上述任何方法时,将执行本地构建,并将目标文件放在源目录中。

//这是第一种方法的实现过程,$(origin O)是输出变量O的定义来源,假设在命令行模式输
//入#make O=/tmp/build all来编译,
//那么O的定义来源是命令行,函数的输出是command line。
ifdef O                                 //如果定义了O
ifeq ("$(origin O)", "command line")    //比如make O=/tmp/build all
//:=用来赋值,就是直接就地解析,只用往前看即可
BUILD_DIR := $(O)                       //将O的值赋值给BUILD_DIR
endif
endif

//倘若BUILD_DIR定义过了,也就是不希望目标文件与源文件混在一起,
//那么直到“endif # //ifneq ($(BUILD_DIR),)”
//的内容都有效;倘若没有定义BUILD_DIR,那么这部分代码将不起作用。
ifneq ($(BUILD_DIR),)                   //如果BUILD_DIR不为空的话
//:=用来赋值,就是直接就地解析,只用往前看即可
saved-output := $(BUILD_DIR)            //将BUILD_DIR保存在saved-output变量中

# Attempt to create a output directory.
# 尝试创建输出目录
//-d是判断BUILD_DIR是否存在,倘若不存在就就创建。mkdir的-p参数代表若路径中的某些目录不存在
//也一并创建
$(shell [ -d ${
   
   BUILD_DIR} ] || mkdir -p ${
   
   BUILD_DIR}) 

# Verify if it was successful.验证是否成功。
//试图进入$(BUILD_DIR),倘若能进入,则将它的路径赋给BUILD_DIR,注意这时的BUILD_DIR已经是一个
//真实存在目录的代言人,而之前的只是希望创建的目录。需要说明的是倘若BUILD_DIR还没有创建,
//那么cd $(BUILD_DIR)将执行错误,返回值是空,虽然这时发生错误,
//但是编译会忽略这个错误还能继续进行。
BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)

//如果没有创建成功,就执行error函数,输出信息output directory "$(saved-output)" does not exist),然后编译终止
$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)

//如果BUILD_DIR不为空,目标目录就等于BUILD_DIR;倘若没定义,就取为当前目录
OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE		:= $(CURDIR)   //源文件目录等于当前文件夹
TOPDIR		:= $(SRCTREE)  //顶层目录等于源文件目录
LNDIR		:= $(OBJTREE)  //连接目录等于BUILD_DIR
export	TOPDIR SRCTREE OBJTREE //将这三个变量导出

MKCONFIG	:= $(SRCTREE)/mkconfig  //指定mkconfig的位置
export MKCONFIG            //将MKCONFIG变量导出

ifneq ($(OBJTREE),$(SRCTREE))   //如果目标目录和源文件目录不相等
REMOTE_BUILD	:= 1            //就定义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.
//$(obj)和(src)是在config.mk中定义的,但是在主Makefile中,我们在包含config.mk
//之前也需要它们,这是一些目标的情况,比如unpack、clean、clobber、distclean等。

//定义变量obj和src,并将这两个变量导出,obj是编译目标文件的前缀,从而实现生成的目标文件在于
//源文件相区别的目录中
ifneq ($(OBJTREE),$(SRCTREE))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src 

# Make sure CDPATH settings don't interfere 确保CDPATH设置不会干扰
u
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值