海思3559:uboot顶层Makefile分析

2023-11-16

顶层Makefile的内容主要结构为:

  1. 确定版本号及主机信息
  2. 实现静默编译功能
  3. 设置各种路径
  4. 设置编译工具链
  5. 设置规则
  6. 设置与cpu相关的伪目标
    需要注意的是,结构顺序并不代表代码执行顺序。

1.确定版本号及主机信息

VERSION = 2016
PATCHLEVEL = 11
SUBLEVEL =
EXTRAVERSION =
NAME =
version_h := include/generated/version_autogenerated.h
timestamp_h := include/generated/timestamp_autogenerated.h
UBOOTVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)

  最开始四个变量的含义依次为:主版本号、次版本号、再次版本号、附加的版本信息(值为空,可以给用户使用)
timestamp_autogenerated.h 这个文件是在make之后自动生成的,文件内容是一条宏,这条宏给将其他.c文件提供uboot的编译时间
  version_autogenerated.h这个文件是在make之后自动生成的,文件内容是一条宏,这条宏给将其他.c文件提供uboot的版本号
  UBOOTVERSION 为最终生成的uboot版本
  验证方法:自己修改主Makefile中几个Version有关的变量,然后重新编译uboot,然后烧录到SD卡中,从SD卡启动,然后去看启动时uboot打印出来的版本信息,看看变化是不是和自己的分析一致。

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

  HOSTARCH这个名字:HOST是主机;ARCH是architecture(架构)的缩写,表示CPU的架构。所以HOSTARCH就表示主机的CPU的架构
  makefile的函数调用与变量调用很类似,格式是$ ( function arguments),其实上面一大段的意思是变量HOSTARCH的值是一个函数的返回值shell是makefile中的一个函数,$ (shell XXX)会被解析成执行shell命令XXX;此处是执行了一条 uname -m |sed -e ……,符号 \是makefile的换行符其中,|是shell语法中的管道结构,例如:XXX | YYY ,表达式XXX 的输出将作为表达式YYY的输入,YYY的输出才是整句表达式的输出uname -m 指令将输出负责编译的主机cpu架构,比如ixx86;sed -e是替换命令,比如把ixx86替换为x86,由此可见这个HOSTARCH变量的值将得到负责编译的主机cpu架构。大部分情况下我们得到的都是x86


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

  这个HOSTOS变量和上一句HOSTARCH变量的原理类似,管道第一部分uname -s会得到负责编译的主机的OS,比如Linux
  管道第二部分是将大写转换成小写
  管道第三部分的意思是如果前面一个部分得到了cygwin系统,则格式要转换一下。不必深究,因为cygwin基本没人用……
  由此可见这个HOSTOS变量的值将得到负责编译的主机操作系统,大部分情况下我们得到的都是linux

CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
	  else if [ -x /bin/bash ]; then echo /bin/bash; \
	  else echo sh; fi ; fi)
export	HOSTARCH HOSTOS

  SHELL定义使用哪种sh解释器来解释脚本,BASH的值为/bin/sh也可能为,整个语句的意思是判断/bin/sh是否可执行
  如果可执行将/bin/sh 赋值给变量SHELL
  如果不可执行,进一步判断/bin/bash的可执行性
  如果/bin/sh和/bin/bash都不可执行,则直接将sh赋值给SHELL变量

  export HOSTARCH HOSTOS

  导出上面变量到全局,使其为环境变量,让其他的文件也可以使用架构和系统信息

2.实现静默编译功能

  平时默认编译时命令行会打印出来很多编译信息。但是有时候我们不希望看到这些编译信息,就后台编译即可。这就叫静默编译。

# If it is set to "quiet_", only the short version will be printed.
# If it is set to "silent_", nothing will be printed at all, since

  使用方法就是编译时make -s,-s会作为MAKEFLAGS传给Makefile,老版本uboot作用下XECHO变量就会被变成空(默认等于echo),于是实现了静默编译。

# If the user is running make -s (silent mode), suppress echoing of
# commands

ifneq ($(filter 4.%,$(MAKE_VERSION)),)	# make-4
ifneq ($(filter %s ,$(firstword x$(MAKEFLAGS))),)
  quiet=silent_
endif
else					# make-3.8x
ifneq ($(filter s% -s%,$(MAKEFLAGS)),)
  quiet=silent_
endif
endif

export quiet Q KBUILD_VERBOSE

  此外,相关设置也需要kbuild值来决定是否开启,我理解只有等于1时才会生效,相关注释是这样说的

# Normally, we echo the whole command before executing it. By making
# that echo $($(quiet)$(cmd)), we now have the possibility to set
# $(quiet) to choose other forms of output instead, e.g.
#
#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
#
# If $(quiet) is empty, the whole command will be printed.
# If it is set to "quiet_", only the short version will be printed.
# If it is set to "silent_", nothing will be printed at all, since
# the variable $(silent_cmd_cc_o_c) doesn't exist.
#
# A simple variant is to prefix commands with $(Q) - that's useful
# for commands that shall be hidden in non-verbose mode.
#
#	$(Q)ln $@ :<
#
# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
# If KBUILD_VERBOSE equals 1 then the above command is displayed.
#
# To put more focus on warnings, be less verbose as default
# Use 'make V=1' to see the full commands

3.设置各种路径

两种编译方法

  (1)编译复杂项目,Makefile提供2种编译管理方法。默认情况下是当前文件夹中的.c文件,编译出来的.o文件会放在同一文件夹下。这种方式叫原地编译。原地编译的好处就是处理起来简单。
  (2)原地编译有一些坏处:第一,污染了源文件目录。第二的缺陷就是一套源代码只能按照一种配置和编译方法进行处理,无法同时维护2个或2个以上的配置编译方式。
  (假如这套源代码有2种配置,那么编译其中一种配置后,要想编译另一种配置需要先make distclean清除第一种的编译生成文件才可以进行。)
  (3)为了解决以上2种缺陷,uboot支持单独输出文件夹方式的编译(linux kernel也支持,而且uboot的这种技术就是从linux kernel偷师而来)。基本思路就是在编译时另外指定一个输出目录,将来所有的编译生成的.o文件或生成的其他文件全部丢到那个输出目录下去。源代码目录不做任何污染,这样输出目录就只是承载了本次配置编译的所有结果。
  (4)具体用法:默认的就是原地编译。如果需要指定具体的输出目录编译则有2种方式来指定输出目录。(具体参考Makefile注释内容)

# kbuild supports saving output files in a separate directory.
# To locate output files in a separate directory two syntaxes are supported.
# In both cases the working directory must be the root of the kernel src.
# 1) O=
# Use "make O=dir/to/store/output/files/"
#
# 2) Set KBUILD_OUTPUT
# Set the environment variable KBUILD_OUTPUT to point to the directory
# where the output files shall be placed.
# export KBUILD_OUTPUT=dir/to/store/output/files/
# make
#
# The O= assignment takes precedence over the KBUILD_OUTPUT environment
# variable.

# KBUILD_SRC is set on invocation of make in OBJ directory
# KBUILD_SRC is not intended to be used by the regular user (for now)

  第一种:make O=输出目录
  第二种:export BUILD_DIR=输出目录 然后再make
  如果两个都指定了(既有BUILD_DIR环境变量存在,又有O=xx),则O=xx具有更高优先级,会覆盖方法二。
  而且方法一必须每次输入make时都要输入参数(不论是make clean还是make config 的时候),格式如make O=/tmp/build disclean

# That's our default target when none is given on the command line
PHONY := _all
_all:

# Cancel implicit rules on top Makefile
$(CURDIR)/Makefile Makefile: ;

ifneq ($(KBUILD_OUTPUT),)
# Invoke a second make in the output directory, passing relevant variables
# check that the output directory actually exists
saved-output := $(KBUILD_OUTPUT)
KBUILD_OUTPUT := $(shell mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) \
								&& /bin/pwd)
$(if $(KBUILD_OUTPUT),, \
     $(error failed to create output directory "$(saved-output)"))

PHONY += $(MAKECMDGOALS) sub-make

$(filter-out _all sub-make $(CURDIR)/Makefile, $(MAKECMDGOALS)) _all: sub-make
	@:

sub-make: FORCE
	$(Q)$(MAKE) -C $(KBUILD_OUTPUT) KBUILD_SRC=$(CURDIR) \
	-f $(CURDIR)/Makefile $(filter-out _all sub-make,$(MAKECMDGOALS))

  这句是shell语法中简写的if表达式,其作用是当输出文件夹路径不存在时就创建它
  其中包含两个表达式,表达式1||表达式2,当表达式1为真时,表达式2不会被解释器执行,因为总结果一定为真,(尽管总的结果没有意义)。唯有表达式1为假时,解释器才会去执行表达式2,这样就能用逻辑表达式来实现if语句的功能了
  表达式1中,方括号是固定用法,是为了突出里面表达式的作用是判断语句。-p是shell中判断路径是否存在的符号,如果路径存在则为表达式1为真;如果路径不存在,表达式1为假,解释器会执行表达式2,即创建输出文件夹路径。
  这整个一段功能是确保输出文件夹路径创建成功,&&的功能是连续执行两句语句,当cd $(BUILD_DIR)执行完后,执行/bin/pwd,即打印当前路径;
$(if xxx,yyy,zzz)是makefile的判断函数,如果xxx为真,则执行yyy并返回值,否则执行zzz并返回值,由此可知如果未成功创建BUILD_DIR,就会输出错误打印信息;

objtree		:= .
src		:= $(srctree)
obj		:= $(objtree)

  (1)OBJTREE:编译出的.o文件存放的目录的根目录。在默认编译下,OBJTREE等于当前目录;在O=xx编译下,OBJTREE就等于我们设置的那个输出目录。
  (2)SRCTREE: 源码目录,其实就是源代码的根目录,也就是当前目录。
  总结:在默认编译下,OBJTREE和SRCTREE相等;在O=xx这种编译下OBJTREE和SRCTREE不相等。Makefile中定义这两个变量,其实就是为了记录编译后的.o文件往哪里放,就是为了实现O=xx的这种编译方式的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海思3559:uboot顶层Makefile分析 的相关文章

  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 尝试安装 LESS 时出现“请尝试以 root/管理员身份再次运行此命令”错误

    我正在尝试在我的计算机上安装 LESS 并且已经安装了节点 但是 当我输入 node install g less 时 出现以下错误 并且不知道该怎么办 FPaulMAC bin paul npm install g less npm ER
  • 无法使用 wget 在 CentOS 机器上安装 oracle jdk

    我想在CentOS上安装oracle java jdk 8 我无法安装 java jdk 因为当我尝试使用命令安装 java jdk 时 root ADARSH PROD1 wget no cookies no check certific
  • NPTL 和 POSIX 线程有什么区别?

    NPTL 和 POSIX 线程之间的基本区别是什么 这两者是如何演变的 POSIX 线程 pthread 不是一个实现 它是几个函数的 API 规范 纸上的标准 英文 其名称以pthread 以及定义在
  • Linux 中什么处理 ping?

    我想覆盖 更改 linux 处理 ping icmp echo 请求数据包的方式 这意味着我想运行自己的服务器来回复传入的 icmp 回显请求或其他 数据包 但为了使其正常工作 我想我需要禁用 Linux 的默认 ping icmp 数据包
  • 如何通过保持目录结构完整来同步路径中匹配模式的文件?

    我想将所有文件从服务器 A 复制到服务器 B 这些文件在不同级别的文件系统层次结构中具有相同的父目录名称 例如 var lib data sub1 sub2 commonname filetobecopied foo var lib dat
  • SSE:跨页边界的未对齐加载和存储

    我在页面边界旁边执行未对齐加载或存储之前读过某处 例如使用 mm loadu si128 mm storeu si128内在函数 代码应首先检查整个向量 在本例中为 16 个字节 是否属于同一页 如果不属于同一页 则切换到非向量指令 我知道
  • Linux 上有关 getBounds() 和 setBounds() 的 bug_id=4806603 的解决方法?

    在 Linux 平台上 Frame getBounds 和 Frame setBounds 的工作方式不一致 这在 2003 年就已经有报道了 请参见此处 http bugs java com bugdatabase view bug do
  • 如何使用 GOPATH 的 Samba 服务器位置?

    我正在尝试将 GOPATH 设置为共享网络文件夹 当我进入 export GOPATH smb path to shared folder I get go GOPATH entry is relative must be absolute
  • CoAP数据包的大小是多少?

    我是这项技术的新手 有人可以帮助我了解一些疑问吗 Q 1 CoAP数据包的大小是多少 我知道有 4 字节固定标头 但是包括标头 选项和负载在内的最大大小限制是多少 Q 2 有像MQTT那样的Keep Alive的概念吗 它在UDP上工作 它
  • 如何在 Bash 中给定超时后终止子进程?

    我有一个 bash 脚本 它启动一个子进程 该进程时不时地崩溃 实际上是挂起 而且没有明显的原因 闭源 所以我对此无能为力 因此 我希望能够在给定的时间内启动此进程 如果在给定的时间内没有成功返回 则将其终止 有没有simple and r
  • 是否可以创建一个脚本来保存和恢复权限?

    我正在使用 Linux 系统 需要对一组嵌套文件和目录进行一些权限实验 我想知道是否没有某种方法可以保存文件和目录的权限 而不保存文件本身 换句话说 我想保存权限 编辑一些文件 调整一些权限 然后将权限恢复到目录结构中 将更改的文件保留在适
  • Linux 上的用户空间能否实现本机代码的抢占式多任务处理?

    我想知道是否可以在 Linux 用户空间的单个进程中实现本机代码的抢占式多任务处理 也就是说 从外部暂停一些正在运行的本机代码 保存上下文 交换到不同的上下文 然后恢复执行 所有这些都由用户空间精心安排 但使用可能进入内核的调用 我认为这可
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • 当 grep "\\" XXFile 我得到“尾随反斜杠”

    现在我想查找是否有包含 字符的行 我试过grep XXFile但它暗示 尾随反斜杠 但当我尝试时grep XXFile没关系 谁能解释一下为什么第一个案例无法运行 谢谢 区别在于 shell 处理反斜杠的方式 当你写的时候 在双引号中 sh
  • MySQL 中的创建/写入权限

    我的设备遇到一些权限问题SELECT INTO OUTFILE陈述 当我登录数据库并执行简单的导出命令时 例如 mysql gt select from XYZ into outfile home mropa Photos Desktop
  • Linux:如何设置进程的时区?

    我需要设置在 Linux 机器上启动的各个进程的时区 我尝试设置TZ变量 在本地上下文中 但它不起作用 有没有一种方法可以使用与系统日期不同的系统日期从命令行运行应用程序 这可能听起来很愚蠢 但我需要一种sandbox系统日期将被更改的地方
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • 快速像素绘图库

    我的应用程序以每像素的方式生成 动画 因此我需要有效地绘制它们 我尝试过不同的策略 库 但结果并不令人满意 尤其是在更高分辨率的情况下 这是我尝试过的 SDL 好的 但是慢 OpenGL 像素操作效率低下 xlib 更好 但仍然太慢 svg
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost

随机推荐

  • OpenHarmony鸿蒙系统源码编译

    学习资源 鸿蒙官网 https device harmonyos com cn home 开源代码仓库地址 https openharmony gitee com 源码获取 参考 https device harmonyos com cn
  • Unate function & Positive unate & Negtive unate

    Unate function Unateness gt Positive unate and negtive unate
  • python变量的引用赋值及深浅拷贝

    python变量的引用赋值及深浅拷贝 1 python的变量 1 1 可变数据类型 1 2 不可变数据类型 2 深浅拷贝 2 1 内存地址以及实际存储数据之间的关系 2 2 若拷贝对象是可变数据类型 2 3 若拷贝对象是不可变数据类型 1
  • MyBatis3入门

    这里对mybatis的入门介绍以官方最新MyBatis3 4 1为准 具体文档及jar包请访问 https github com mybatis mybatis 3 releases 以前经常都在使用mybatis 但通常都是和Spring
  • MFC 启用和禁用控件

    启用和禁用控件可以调用CWnd EnableWindow 函数 BOOL EnableWindow BOOL bEnable TRUE 判断控件是否可用可以调用 CWnd IsWindowEnable函数 BOOL IsWindowEnab
  • Oracle VM VirtualBOX下克隆虚拟机镜像

    Oracle VM VirtualBOX下克隆虚拟机镜像 Windows环境下在Oracle VM VirtualBOX下克隆虚拟机镜像 1 通过命令操作 VBoxManage exe clonevdi F mysqlvm mysqledi
  • 二叉树的深度优先遍历和广度优先遍历js代码实现

    a 树的深度优先搜索和广度优先搜索 其实没了解过的时候 看见树就头晕 之后去搜了下 发现也不是什么困难的事情 其实树的深度优先搜索指的是不按照层级的规律去便利 像前序便利 中序后序便利都是属于深度便利的方式 树的广度便利就是按照层级关系 一
  • js 解构赋值

    取对象里的code以及value值 对象结构 var data code 1 message Hello World 常规取值做法 var code data code var message data message 用解构就方便简洁许多
  • sqlserver 联表查询、子查询、窗口函数、聚合函数等概念与例子

    with cte as的用法 查询的一个有用工具 允许创建临时命名结果集 可在查询中多次引用相同的子查询结果 可以提高查询的可读性和维护性 WITH cte name column1 column2 AS 这里是子查询 SELECT col
  • 静态白盒测试-code review

    一 静态白盒测试概述 首先区分软件测试的几个术语 白盒测试 黑盒测试 静态测试 动态测试 白盒测试 也称为透明测试 clear box testing 白盒测试针对逻辑结构进行检查 它允许我们看到程序的内部结构 黑盒测试 black box
  • 图片重叠,转换

  • Unity射线检测失效原因(逐步完善)

    完整用法 1 确保被检测物体拥有 层的设置 public LayerMask m layerMask 别忘记给敌人设置层和在脚本中选择层 2 确保被检测物体拥有 collider且其厚度不为0
  • Unity缺少System.IO.Ports

    问题 我需要使用串口相关的类库 但是引用不到 怎么解决的 PlayerSetting 界面把 Api Compatibility Level 切换为 NET 4 x 然后就好了
  • python并发编程之多线程

    多线程 多线程的作用 也是用于提高程序的效率 多进程 1 核心是多道技术 把内存分成 几块 2 通过 本质上就是切换 加 保存状态 3 当程序 IO 操作较多 可以提高程序效率 多线程什么是多线程 程序的执行线路 相当于与一条流水线 其包含
  • 计算机物联网论文范文大全,精选物联网的毕业论文范文.doc

    精选物联网的毕业论文范文 基于单片机的嵌入式以太网控制终端设计摘要 基于单片机技术的以太网终端广泛应用在各个领域 本文基于建荣AX20XX PHY的解决方案 实现ARP请求 以及ping命令 同时 本文详细介绍以太网接口的硬件设计和通信电路
  • 数学建模之方差分析基础--单因素,双因素方差分析与matlab实现

    前言 由于方差分析的原理基本在所有概率论与数理统计的书中都可以找到 那么这里就直接以图片的形式呈现了 关于方差齐次性检验以后会补充 知识基础 假设检验 今天刚刚学了数据结构 发现自己以前写的数组的基础操作水平极低 真是惭愧 简介 方差分析
  • 贝叶斯网络结构学习方法简介

    题目 贝叶斯网络结构学习方法简介 贝叶斯网络 Bayesiannetwork BN 结构学习就是从给定的数据集中学出贝叶斯网络结构 即各节点之间的依赖关系 只有确定了结构才能继续学得网络参数 即表示各节点之间依赖强弱的条件概率 对于普通人来
  • 计算机致命命令,[注意]13 个致命的Linux 命令

    本文收集所有你不能在 Linux 下执行的命令 执行任何下列命令 之一 会让你丢失数据或造成数据损坏 冻结或挂起你运行中的 Linux 系统 千万不要在 Linux 文本界面运行下列命令 NEVER RUN THE FOLLOWING CO
  • 获取单选框值

    function getRadioVal nameVal var inputs document getElementsByName nameVal var checkVal for var i 0 len inputs length i
  • 海思3559:uboot顶层Makefile分析

    顶层Makefile的内容主要结构为 确定版本号及主机信息 实现静默编译功能 设置各种路径 设置编译工具链 设置规则 设置与cpu相关的伪目标 需要注意的是 结构顺序并不代表代码执行顺序 1 确定版本号及主机信息 VERSION 2016