Makefile学习笔记15|u-boot顶层Makefile01

Makefile学习笔记15|u-boot顶层Makefile01

  希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢。

  这里是目录

版本号信息

# SPDX-License-Identifier: GPL-2.0+VERSION = 2024
PATCHLEVEL = 01
SUBLEVEL =
EXTRAVERSION = -rc4
NAME =

  这里定义了u-boot的版本信息。

make行为控制

# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
# More info can be located in ./README
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.# Do not use make's built-in rules and variables
# (this increases performance and avoids hard-to-debug behaviour)
MAKEFLAGS += -rR

  前面的注释中说:该文件中的注释仅针对开发人员,不要指望通过阅读该文件来学习如何构建内核。那我们学一下Makefile不过分吧。

  在 Makefile 中设置 MAKEFLAGS += -rR 是控制 make 工具行为的一种方式。具体来说,-r 和 -R 这两个标志的含义如下:

  1. -r(或 --no-builtin-rules):
    这个选项会禁止 make 使用内置的隐含规则。隐含规则是 make 用来构建文件但未在 Makefile 中明确定义的一组默认规则。例如,make 有一个隐含规则知道如何将 .c 文件编译成 .o 文件。禁用内置规则可以避免一些意外的构建行为,并且可以在某些情况下提高 make 的执行性能。
  2. -R(或 --no-builtin-variables):
    这个选项禁止 make 使用内置的变量集合,这些变量可能会影响那些依赖隐含规则的命令。例如,CFLAGS 是 make 中一个影响 C 编译器行为的内置变量。在 Makefile 中禁用内置变量是为了确保构建环境的清晰和可控性,并避免 Makefile 行为的不确定性。

  将这两个选项合在一起使用可以确保 Makefile 中的构建规则和变量不受 make 内置规则和变量的任何潜在干扰。这在大型、复杂的构建系统中可能很有用,其中你希望对构建过程有完全的控制,同时减少构建过程的不必要干预和潜在的性能影响。

  确切的说,MAKEFLAGS 是一个环境变量,它允许你为 make 设置多个启动选项。在Makefile文件中通过 MAKEFLAGS 变量追加 -rR 选项,可以使这些选项在调用 make 时自动应用于当前构建。

  在你自己的项目中使用时,请确保你完全理解了禁止这些内置规则和变量的含义,以及它们对你的构建系统可能产生的影响。如果你依赖了默认的规则或变量,禁用它们可能会导致构建失败,因此在某些项目中可能需要保留这些内置规则和变量。

确定目标架构

# Determine target architecture for the sandbox
include include/host_arch.h
ifeq ("", "$(CROSS_COMPILE)")MK_ARCH="${shell uname -m}"
elseMK_ARCH="${shell echo $(CROSS_COMPILE) | sed -n 's/^[[:space:]]*\([^\/]*\/\)*\([^-]*\)-[^[:space:]]*/\2/p'}"
endif
unexport HOST_ARCH
ifeq ("x86_64", $(MK_ARCH))export HOST_ARCH=$(HOST_ARCH_X86_64)
else ifneq (,$(findstring $(MK_ARCH), "i386" "i486" "i586" "i686"))export HOST_ARCH=$(HOST_ARCH_X86)
else ifneq (,$(findstring $(MK_ARCH), "aarch64" "armv8l"))export HOST_ARCH=$(HOST_ARCH_AARCH64)
else ifneq (,$(findstring $(MK_ARCH), "arm" "armv7" "armv7a" "armv7l"))export HOST_ARCH=$(HOST_ARCH_ARM)
else ifeq ("riscv32", $(MK_ARCH))export HOST_ARCH=$(HOST_ARCH_RISCV32)
else ifeq ("riscv64", $(MK_ARCH))export HOST_ARCH=$(HOST_ARCH_RISCV64)
endif
undefine MK_ARCH

  在交叉编译环境中,CROSS_COMPILE 是一个常用的变量,它指定了编译器的前缀,使得我们能够为不同于编译宿主机的目标架构构建软件。这在嵌入式系统开发中很常见,因为编译的代码需要在如 ARM、MIPS 或 AVR 这样的架构上运行,而开发者通常在 x86 或 x86-64 架构的机器上进行开发。

  例如,如果你的开发系统是基于 x86 架构的,而你的目标系统是基于 ARM 架构的,那么你需要使用 ARM 架构的交叉编译器来编译你的代码。这样生成的可执行文件才能在 ARM 目标机上运行。

  CROSS_COMPILE 变量通常用于 Makefile 中。它是编译器命令的前缀,所有必要的工具(如编译器 gcc、链接器 ld、汇编器 as 和其他工具)都使用这个前缀。

  例如,如果 ARM 交叉编译器的命令是 arm-none-eabi-gcc,那么 CROSS_COMPILE 应该设置为 arm-none-eabi-,以此类推。下面是 CROSS_COMPILE 在Makefile中的常见用法:

# 设置交叉编译器前缀
CROSS_COMPILE=arm-linux-gnueabihf-# 之后使用变量时:
CC=$(CROSS_COMPILE)gcc
LD=$(CROSS_COMPILE)ld
AS=$(CROSS_COMPILE)as# 其他编译规则和目标...

字符集设置

# Avoid funny character set dependencies
unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC# Avoid interference with shell env settings
unexport GREP_OPTIONS

  这段脚本通常出现在 Unix-like 系统的 Makefile 中,它的目的是确保 Makefile 中的操作对于本地化设置及字符集是独立的。本地化设置可能会影响字符串的比较,排序和数字的表示方式。为了避免这些依赖,通常在 Makefile 或构建脚本中设置特定的环境变量,使得这些操作更可预测,具有一致性,避免构建过程中由于不同的本地化设置引起的问题。

  1. LC_ALL 是一个强制性的环境变量,用于设置 C 库的本地化配置,它会覆盖所有其他本地化设置,包括 LC_COLLATE, LC_NUMERIC, 以及其他 LC_* 类型的变量。
  2. LC_COLLATE 定义了字符串比较和排序的规则。设置为 C 可确保文件名和字符串的比较是基于字节值进行的,而不受根据地区的字母顺序影响。
  3. LC_NUMERIC 影响数字的格式化方式,比如数字分隔符。例如,在某些本地化设置中,小数点用逗号 ‘,’ 表示。设置为 C 可以确保小数点始终使用点 ‘.’,以符合大多数编程语言和脚本的期望。

  当我们确保 LC_COLLATE 和 LC_NUMERIC 是 C(或 POSIX,它们是等效的)时,您可以让构建过程在所有环境中提供一致的行为,避免由于不同的语言或地区设置而造成的问题。这可以提高 Makefile 的可移植性和健壮性。

  对于最后一行,当在脚本或者 Makefile 中使用 grep,不同用户的不同 GREP_OPTIONS 设置可能会结果不一致,尤其是当这个脚本依赖于 grep 输出特定格式时。为了确保 grep 的行为是预期并且一致的,开发者通常会选择清除 GREP_OPTIONS 环境变量。

美化输出

# Beautify output
# ---------------------------------------------------------------------------
#
# 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 commandsifeq ("$(origin V)", "command line")KBUILD_VERBOSE = $(V)
endif
ifndef KBUILD_VERBOSEKBUILD_VERBOSE = 0
endififeq ($(KBUILD_VERBOSE),1)quiet =Q =
elsequiet=quiet_Q = @
endif# If the user is running make -s (silent mode), suppress echoing of
# commandsifneq ($(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
endifexport quiet Q KBUILD_VERBOSE

  它提供了一种灵活的机制,用于控制命令执行时输出信息的格式。这种机制让构建系统(如内核)能够以不同的详细级别显示或隐藏命令的输出。

  • 设置输出参数
    1. 命令行变量 V:允许你通过在 make 命令后添加 V=1 参数来开启详细模式(例如,make V=1)。
    2. 设置 KBUILD_VERBOSE:根据 V 变量的值设置 KBUILD_VERBOSE,用于决定输出模式是详细 (1) 还是简洁 (0)。
    3. 定义 quiet 和 Q:利用 KBUILD_VERBOSE 变量,这段设置定义了两个控制输出的变量 quiet 和 Q。当 KBUILD_VERBOSE 是 1(详细模式),Q 是空字符串,这意味着所有命令都会显示。如果是 0(简洁模式),Q 被设置为 @,这表示 Makefile 中以 $(Q) 开头的命令将不显示。
  • 控制命令输出
    1. 命令输出前缀:使用 $(quiet) 作为前缀可以使得 make 在执行命令时不显示整个命令,而是显示一个简短的描述,例如“Compiling foo/bar.o”。
    2. 静默模式检测:根据 Make 的版本,脚本检查 MAKEFLAGS 是否包含静默模式标志 s。如果用户使用了 make -s,则所有命令执行将不输出任何信息,因为 quiet 变量将被设置为 silent_。

  这个复杂的控制机制最终目的是为开发者提供一个在需要时能够详细打印每一个命令执行的构建过程(有助于调试),而在常规构建时则显示简化或没有输出。这使得构建输出更易于阅读,并能在需要解决问题时提供足够的信息。

  都看到这里了,可以给个点赞或者评论吗?达瓦里希( ̄^ ̄)ゞ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841811.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spark基础笔记之启动命令顺序

系统环境&#xff08;三台虚拟机&#xff09; node1 192.168.32.101&#xff08;主&#xff09; node2 192.168.32.102 node3 192.168.32.103 1、启动hdfs、yarn、historyserver&#xff08;hadoop用户启动&#xff09; # 启动dfs&#xff0c;启动后的服务名&#xff1a; Da…

【ai】pycharm安装langchain 相关module

pycharm module install 【Python学习 】一篇文章教你PyCharm如何快速安装module 【python】pycharm如何安装python的模块包版本 2024.1.2 RC2 找到当前的虚拟项目 找到解释器 我现在配置为专门为openai-start 准备的3.10 版本+ 号可以找到模块

Vue3拖拽修改左侧元素宽度组件开发

在开发过程中有时候会碰到需要拖拽修改页面元素宽度的需求&#xff0c;实际场景是页面上有并排两个或多个元素&#xff0c;需要拖拽修改其中一个元素的宽度&#xff0c;则只引入下方组件代替页面中需要被拖拽的元素及右侧相邻的元素。需要将需要拖拽的元素放进下面组件的左边的…

pdf拆分成多个文件 pdf拆分成一页一页

pdf拆分成多个文件的方法。在现代办公环境中&#xff0c;PDF文件因其跨平台、保持格式一致等特性&#xff0c;成为了广泛使用的文件格式。然而&#xff0c;有时我们需要对PDF文件进行拆分&#xff0c;以便更好地管理和使用其中的内容。本文将详细介绍PDF拆分的方法和步骤&#…

Flutter 中的 ClipOval 小部件:全面指南

Flutter 中的 ClipOval 小部件&#xff1a;全面指南 在Flutter的丰富布局库中&#xff0c;ClipOval是一个用于裁剪子组件的显示区域为椭圆形或圆形的小部件。这种裁剪效果可以用于创建头像、图标或其他图形元素的美观边框。本文将提供ClipOval的全面指南&#xff0c;帮助你了解…

一.架构设计

架构采用 ddd 架构&#xff0c;不同于传统简单的三层的架构&#xff0c;其分层的思想对于大家日后都是很有好处的&#xff0c;会给大家的思想层级&#xff0c;提高很多。 传统的项目 现有的架构 采取ddd架构&#xff0c;给大家在复杂基础上简化保留精髓&#xff0c;一步步进行…

LabVIEW直方图应用解析

概述 在LabVIEW中&#xff0c;直方图是一种重要的工具&#xff0c;用于分析和展示数据的分布情况。它通过将数据分成若干区间并绘制对应频数&#xff0c;可以帮助用户了解数据的集中趋势、离散程度和分布形态。本文将详细介绍LabVIEW中直方图的使用方法、适用场合、实际意义及…

19 QinQ技术(Vlan两层封装)

1 什么是QinQ&#xff1f; QinQ&#xff08;802.1Q-in-802.1Q&#xff09;&#xff0c;也叫做VLAN Stacking或Double VLAN&#xff0c;由IEEE 802.1ad标准定义&#xff0c;**是一项扩展VLAN空间的技术&#xff0c;**通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩…

工具使用-网络性能测试工具(iperf)-TCP 和 UDP 的吞吐量-包转发率参数的理解

时间戳&#xff1a;2024年5月26日15:18:39 iperf 和 netperf 都是最常用的网络性能测试工具&#xff0c;测试 TCP 和 UDP 的吞吐量。它们都以客户端和服务器通信的方式&#xff0c;测试一段时间内的平均吞吐量。 接下来&#xff0c;我们就以 iperf 为例&#xff0c;看一下 TC…

MyBatis进阶(<if><trim><where><set><foreach><include>标签的使用)

目录 < if >标签 < trim >标签 < where >标签 < set >标签 < foreach >标签 < include >标签 < if >标签 非必填字段 xml实现 <insert id"insertUserByCondition">INSERT INTO userinfo (username,passwor…

【力扣一轮】202.快乐数 1.两数之和

202.快乐数 力扣链接 代码随想录链接 思路 看到这一题没思路&#xff0c;直接看题解。 发现其中一个难点在于“无限循环”&#xff0c;这个字眼可以转换成退出条件。退出条件就有两种&#xff0c;一种是这个数字是快乐数&#xff0c;一种是这个数字不是快乐数。 如果是快…

【vue嵌套iframe】实现项目重构

vue嵌套iframe 创建 iframe 通用组件添加页面及路由进阶&#xff1a;vue 与 iframe 的双向通讯代码下载 适用于使用vue重构及vue访问其他服务页面 基于vue3示例页面添加嵌套iframe的页面 创建 iframe 通用组件 IframeTemplate.vue 页面布局 <template><div class…

9.2 Go语言入门(包和导入)

Go语言入门&#xff08;包和导入&#xff09; 目录一、包和导入1. 包&#xff08;Package&#xff09;1.1 包的定义1.2 包的作用1.3 main 包1.4 非 main 包 2. 导入&#xff08;Import&#xff09;2.1 导入标准库2.2 导入第三方包2.3 导入本地包2.4 导入别名2.5 导入并调用初始…

mysql授权用户

mysql授权用户只能看到某张表单表 要实现MySQL中的用户只能看到某张表&#xff0c;可以通过创建一个新的数据库用户&#xff0c;并且只授予该用户对特定表的权限。以下是实现这一功能的步骤和示例代码&#xff1a; 创建新用户并设置密码。 授予该用户对特定数据库的权限。 授…

国内最受欢迎的7大API供应平台对比和介绍||电商API数据采集接口简要说明

本文将介绍7款API供应平台&#xff1a;聚合数据、百度APIStore、Apix、数说聚合、通联数据、HaoService、datasift 。排名不分先后&#xff01; 免费实用的API接口 第一部分 1、聚合数据&#xff08;API数据接口_开发者数据定制&#xff09; 2、百度API Store(API集市_APIStore…

数据库系统原理实验报告6 | 视图

整理自博主本科《数据库系统原理》专业课自己完成的实验报告&#xff0c;以便各位学习数据库系统概论的小伙伴们参考、学习。 专业课本&#xff1a; ​ ———— 本次实验使用到的图形化工具&#xff1a;Heidisql ​ 目录 一、实验目的 二、实验内容 1&#xff0e;根据EDUC数…

妙解设计模式之适配器模式

适配器模式的概念 适配器模式是一种结构设计模式&#xff0c;它允许将接口不兼容的类通过一个适配器类进行适配&#xff0c;使得这些类可以一起工作。适配器模式通常用于以下情况&#xff1a; 当一个接口的实现类已经存在&#xff0c;但是另一个接口需要的是不兼容的时候。当…

揭秘C++ String容器:字符串操作的艺术

目录 ​编辑 引言 一、初识std::string&#xff1a;构造与初始化 二、字符串的操纵艺术&#xff1a;拼接、查找与替换 三、访问与遍历&#xff1a;字符的细腻触感 四、大小与容量&#xff1a;动态调整的智慧 五、进阶功能&#xff1a;探索更多可能 结语 引言 在C标准库…

ssms执行建表后如何自动刷新所有SQL SERVER表

在 SQL Server Management Studio (SSMS) 中&#xff0c;当你通过 T-SQL 脚本创建表后&#xff0c;通常需要手动刷新对象资源管理器以查看新表。SSMS 并没有提供自动刷新的选项&#xff0c;但你可以使用以下几种方法来解决这个问题&#xff1a; 手动刷新&#xff1a;在对象资源…

网络工程师基础知识:

网络工程师基础知识&#xff1a; 1.最基本的7层协议&#xff1a; 来源&#xff1a; 通过网络网线和报文的这些机制让全世界的数据通过二进制流来进行沟通 从下而上&#xff1a; 物理层 数据链路层 网络层 传输层 表示层 会话层 应用层 基本的一个数据报文&#xff1a; 数据链…