(五)uboot编译和配置1(Makefile源码分析)

注意:之后分析的源码都是用notepad++打开的

一、Makefile的版本分析

由图的这四部分构成了最终的一个版本号;

U_BOOT_VERSION “1.3.4后面自己写”

也就是知道uboot的版本号分了三个基本,分别是Version 、patchlevel(补丁版本号)、sublevel(最后的版本号)。它们最终共同构成了版本号;

 

EXTRAVERSION表示一些附加的信息;

如写一个recha这个名字。

 

 

对于

可以看到一个用了一个变量obj,(等号,往后边走,现在可以暂时认为什么都没有)。对于后面的include,则是根目录(Makefile所在位置)下边的include,可是下面没有找到version_aurogenerated.h,那么这个文件是编译过程中自动生成的一个文件,所以源目录中没有,但是编译后就有了。它里面的内容是一个宏定义,宏定义的值内容就是我们在配置Makefile中配置的uboot的版本号。

下图可以看到有这个文件:

这是文件里的内容:

验证方法:自己修改主Makefile中几个有关的变量,然后重新编译uboot,然后烧录SD卡中,从SD卡启动,然后去看启动时候uboot打印出来的版本信息,看看变化是不是和自己的分析一致~~~

 

二、HOSTARCH环境变量分析

两个环境变量,后面有两个export导出的。

uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。

uname -s意思是打印操作系统

在这里会输出操作系统的信息

 

对HOSTARCH的解读:

 

(1)直接在shell中执行 uname -m得到i686,得到的值其实是你当前执行这个命令的电脑的CPU的版本号(如i7的是i686)。

 

(2)shell中的|是管道,作用是把前一个运算式的输出做为后一个的输入再去做处理,最终的输出才是我们整个式子的输出;

 

 

之后通过管道,将上面得到的结果中的i.86替换为i386,如果结果中没有i.86子串就不做替换。
 

首先,红箭头指向的这两种写法是一回事,会打印出所在目录;

 

三、静默编译

静默编译

平时默认编译时候会出很多编译信息,但有时候我们不希望看到这些编译信息,就后台编译即可。

 

实现静默编译的代码就是上图

MAKEFLAGS就是我们传的参数(找s)

make -s

当执行上句时候找到s这个属性

使用方法就是编译时make -s   -s作为makeflags传给makefile。

findstring函数

功能:在字串<in>中查找<find>字串。

返回:如果找到,那么返回<find>,否则返回空字符串。

因为ifeq(,s) 为假 ,所以执行 else 。

于是实现静默编译

 

四、两种编译方法

(1)编译复杂项目,Makefile提供两种编译方法,默认情况是当前文件夹中的.c文件编译出来的.o文件会放在同一文件夹下。这种方法原地编译的好处是处理起来简单。

(2)原地编译有一些坏处,第一是污染了源文件目录,第二是有的源代码会复用。

 

(3)为了解决以上两种缺陷,uboot支持单独输出文件夹方式的编译(linux kernel也支持,而且uboot的这种技术是从linux kernel学习来的)。基本思路是在编译时另外指定一个输出目录下去。源代码目录不做任何污染,这样就输出目录就承载了本次配置编译的所有结果。

 

(4)用法:有两种方式来指定输出目录

第一:make O=输出目录

要用第一种方法配置时候也得加O=XXX;不然会提示没有编译。除此之外,还要注意XXX这个文件要用mkdir XXX -p提前先创建出来;

第二:export BUILD_DIR=输出目录   export导出一个环境变量,然后指定输出目录,然后再make

如果两个都指定了(既有BUILD_DIR又有O=XXX)则O=XXX有更高的优先级。

如下图所示:

 

代码解读:如果make O=XXX 那么ifdef成立,O不为空。接下来BUILD_DIR会传递给saved-output .

ifdef O
ifeq ("$(origin O)", "command line")
BUILD_DIR := $(O)
endif
endif

ifneq ($(BUILD_DIR),)
saved-output := $(BUILD_DIR)

然后通过SHELL命令创建出来BUILD_DIR=的这个文件夹。 这里的shell是个函数,如果BUILD_DIR是一个目录名称,就把该目录创建出来

$(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})

然后进入相应文件夹,如果前一句的BUILD_DIR是相对路径,那么就把它通过&&后的/bin/pwd转换成绝对路径(shell命令的意思是先进入到BUILD_DIR目录,然后调用pwd命令显示当前路径名,并把当前路径名作为shell函数的返回值赋给BUILD_DIR变量)。

BUILD_DIR := $(shell cd $(BUILD_DIR) && /bin/pwd)

If语句判断BUILD_DIR是否存在,如果还为空就显示错误(命令里面两个逗号之间表示空)if在这里是if函数,含有三个参数,第一个参数是Condition,第二参数是then-part,第三个参数是else-part.
<condition>参数是 if 的表达式,如果其返回的为非空字符串,那么这个表达式就相当于返回真,于是,<then-part>会被计算,否则<else-part>会被计算。
(If <Condition>,<then-part>,<else-part>)

$(if $(BUILD_DIR),,$(error output directory "$(saved-output)" does not exist))
endif # ifneq ($(BUILD_DIR),)

注意:CURIDR变量是MAKEFILE的内嵌变量,代表当前路径。

如果定义了BUILD_DIR输出目录,则将BUILD_DIR赋给OBJTREE。如果BUILD_DIR为空,则将当前Makefile所在的路径传给OBJTREE。

CURDIR是源码的目录,SRCTREE是根目录,OBJTREE表示放连接的目录。

所以如果编译时没有定义编译路径,即没有定义BUILD_DIR,则以上所有变量都是CURDIR,即当前目录,也就是uboot的顶层目录

OBJTREE:编译出的.o文件存放目录的根目录。在默认编译下OBJTREE等于当前目录,在O=XXX目录下为我们设置的那个输出目录;

SRCTREE:源码目录。在默认编译下OBJTREE和SRCTREE是一样的。在O=XXX目录下不同。 

TOPDIR: 源码的顶层目录

OBJTREE		:= $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
SRCTREE		:= $(CURDIR)
TOPDIR		:= $(SRCTREE)
LNDIR		:= $(OBJTREE)
export	TOPDIR SRCTREE OBJTREE

导出编译配置

MKCONFIG等于SRCTREE目录下的makeconfig   

对于MKCONFIG(MAKEFILE的101行)

(1)Makefile中定义的一个变量(在这里定义,在后面使用),它的值就是我们源码根目录下的mkconfig。这个mkconfig是一个脚本(配置脚本),这个脚本记丨uboot配置阶段的配置脚本。(之后会详细讨论)

MKCONFIG	:= $(SRCTREE)/mkconfig
export MKCONFIG

如果改变了链接目录,那么会输出REMOTE_BUILD这样一个flag位为1。

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

并且如果源码目录和输出目录不相等,则变量obj和src被赋予相应的值,否则,两变量都为空

前面的第29行就用到了这里的obj变量。  VERSION_FILE = $(obj)include/version_autogenerated.h

可以知道obj是个路径


# $(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))
obj := $(OBJTREE)/
src := $(SRCTREE)/
else
obj :=
src :=
endif
export obj src

# Make sure CDPATH settings don't interfere
unexport CDPATH

 

感谢:

https://blog.csdn.net/baidu_37973494/article/details/88242961

https://blog.csdn.net/aojie6698/article/details/101540551

https://www.cnblogs.com/AndyChen1/p/8341329.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值