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 这两个标志的含义如下:
- -r(或 --no-builtin-rules):
这个选项会禁止 make 使用内置的隐含规则。隐含规则是 make 用来构建文件但未在 Makefile 中明确定义的一组默认规则。例如,make 有一个隐含规则知道如何将 .c 文件编译成 .o 文件。禁用内置规则可以避免一些意外的构建行为,并且可以在某些情况下提高 make 的执行性能。 - -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 或构建脚本中设置特定的环境变量,使得这些操作更可预测,具有一致性,避免构建过程中由于不同的本地化设置引起的问题。
- LC_ALL 是一个强制性的环境变量,用于设置 C 库的本地化配置,它会覆盖所有其他本地化设置,包括 LC_COLLATE, LC_NUMERIC, 以及其他 LC_* 类型的变量。
- LC_COLLATE 定义了字符串比较和排序的规则。设置为 C 可确保文件名和字符串的比较是基于字节值进行的,而不受根据地区的字母顺序影响。
- 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
它提供了一种灵活的机制,用于控制命令执行时输出信息的格式。这种机制让构建系统(如内核)能够以不同的详细级别显示或隐藏命令的输出。
- 设置输出参数
- 命令行变量 V:允许你通过在 make 命令后添加 V=1 参数来开启详细模式(例如,make V=1)。
- 设置 KBUILD_VERBOSE:根据 V 变量的值设置 KBUILD_VERBOSE,用于决定输出模式是详细 (1) 还是简洁 (0)。
- 定义 quiet 和 Q:利用 KBUILD_VERBOSE 变量,这段设置定义了两个控制输出的变量 quiet 和 Q。当 KBUILD_VERBOSE 是 1(详细模式),Q 是空字符串,这意味着所有命令都会显示。如果是 0(简洁模式),Q 被设置为 @,这表示 Makefile 中以 $(Q) 开头的命令将不显示。
- 控制命令输出
- 命令输出前缀:使用 $(quiet) 作为前缀可以使得 make 在执行命令时不显示整个命令,而是显示一个简短的描述,例如“Compiling foo/bar.o”。
- 静默模式检测:根据 Make 的版本,脚本检查 MAKEFLAGS 是否包含静默模式标志 s。如果用户使用了 make -s,则所有命令执行将不输出任何信息,因为 quiet 变量将被设置为 silent_。
这个复杂的控制机制最终目的是为开发者提供一个在需要时能够详细打印每一个命令执行的构建过程(有助于调试),而在常规构建时则显示简化或没有输出。这使得构建输出更易于阅读,并能在需要解决问题时提供足够的信息。
都看到这里了,可以给个点赞或者评论吗?达瓦里希( ̄^ ̄)ゞ
相关文章:
Makefile学习笔记15|u-boot顶层Makefile01
Makefile学习笔记15|u-boot顶层Makefile01 希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢。 这里是目录 版本号信息 # SPDX-License-Identifier: GPL-2.0VERSION 2024 PATCHLEVEL 01 SUBLEVEL EXTRAVERSION -rc4 NAME 这里定义了u-bo…...
C++笔记之Unix时间戳、UTC、TSN、系统时间戳、时区转换、local时间笔记
C++笔记之Unix时间戳、UTC、TSN、系统时间戳、时区转换、local时间笔记 ——2024-05-26 夜 code review! 参考博文 C++笔记之获取当前本地时间以及utc时间...
leetcode338-Counting Bits
题目 给你一个整数 n ,对于 0 < i < n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n 1 的数组 ans 作为答案。 示例 1: 输入:n 2 输出:[0,1,1] 解释: 0 --> 0 1 --&…...
sql server怎么存储图片
sql server怎么存储图片 在SQL Server中,可以使用VARBINARY数据类型来存储图片。以下是一个简单的例子,展示了如何将图片存储到数据库中,并从数据库中检索出来。 首先,创建一个表来存储图片数据: CREATE TABLE Image…...
大模型提示词Prompt学习
引言 关于chatGPT的Prompt Engineer,大家肯定耳朵都听起茧了。但是它的来由?,怎么能用好?很多人可能并不觉得并不是一个问题,或者说认定是一个很快会过时的概念。但其实也不能说得非常清楚(因为觉得没必要深…...
蓝桥杯python组备赛指南
文章目录 前言刷题网站idle操作常用标准库mathdatetime 常见Q&A 前言 最近结束了比赛,我对比赛的过程进行了详细的复盘,并计划撰写一篇文章。这篇文章旨在为准备参加蓝桥杯的学弟学妹们提供帮助,我希望我的文章和笔记能对你们有所裨益。…...
架构师系列-定时任务解决方案
定时任务概述 在很多应用中我们都是需要执行一些定时任务的,比如定时发送短信,定时统计数据,在实际使用中我们使用什么定时任务框架来实现我们的业务,定时任务使用中会遇到哪些坑,如何最大化的提高定时任务的性能。 我…...
新计划,不断变更!做自己,接受不美好!猪肝移植——早读(逆天打工人爬取热门微信文章解读)
时间不等人 引言Python 代码第一篇 做自己,没有很好也没关系第二篇结尾 引言 新计划: 早上一次性发几个视频不现实 所以更改一下 待后面有比较稳定的框架再优化 每天早上更新 早到8点 晚到10点 你刚刚好上班或者上课 然后偷瞄的看两眼 学习一下 补充知…...
【数据结构】二叉树-堆(上)
个人主页~ 二叉树-堆 一、树的概念及结构1、概念2、相关概念3、树的表示4、树的实际应用 二、二叉树的概念和结构1、概念2、特殊二叉树3、二叉树的性质4、二叉树的存储结构(1)顺序存储(2)链式存储 三、二叉树的顺序结构以及实现1、…...
【Spring Boot】在项目中使用Spring AI
Spring AI是Spring框架中用于集成和使用人工智能和机器学习功能的组件。它提供了一种简化的方式来与AI模型进行交互。下面是一个简单的示例,展示了如何在Spring Boot项目中使用Spring AI。 步骤 1: 添加依赖 首先,在pom.xml文件中添加Spring AI的依赖&…...
【java程序设计期末复习】chapter3 运算符、表达式和语句
运算符、表达式和语句 Java提供了丰富的运算符,如算术运算符、关系运算符、逻辑运算符、位运算符等。 Java语言中的绝大多数运算符和C语言相同,基本语句,如条件分支语句、循环语句等也和C语言类似,因此,本章就主要知识…...
【建议收藏】30个较难Python脚本,纯干货分享
本篇较难,建议优先学习上篇 ;20个硬核Python脚本-CSDN博客 接上篇文章,对于Pyhon的学习,上篇学习的结束相信大家对于Pyhon有了一定的理解和经验,学习完上篇文章之后再研究研究剩下的30个脚本你将会有所成就&…...
01-05.Vue自定义过滤器
目录 前言过滤器的概念过滤器的基本使用给过滤器添加多个参数 前言 我们接着上一篇文章01-04.Vue的使用示例:列表功能 来讲。 下一篇文章 02-Vue实例的生命周期函数 过滤器的概念 概念:Vue.js 允许我们自定义过滤器,可被用作一些常见的文本…...
C++系列-static成员
🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 概念 声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量,用static修饰的成员函数,称之为静态成…...
Git | 创建和管理Pull Request总结
如是我闻: 在使用 GitHub 进行项目协作时,掌握如何创建、更新和合并(squash)pull request 是非常有帮助的。本文将详细介绍这些操作,帮助我们更好地管理项目代码,并解释每个操作的原因和解决的问题。 1. 什…...
电机控制系列模块解析(23)—— 同步机初始位置辨识
一、两个常见问题 为什么感应电机(异步机)不需要初始位置辨识?(因此感应电机转子磁场在定子侧进行励磁,其初始位置可以始终人为定义为0) 为什么同步磁阻电机需要初始位置辨识?(因为…...
【数据库基础-mysql详解之索引的魅力(N叉树)】
索引的魅力目录 🌈索引的概念🌈使用场景🌈索引的使用🌞🌞🌞查看MySQL中的默认索引🌞🌞🌞创建索引🌞🌞🌞删除索引 站在索引背后的那个男…...
力扣739. 每日温度
Problem: 739. 每日温度 文章目录 题目描述思路复杂度Code 题目描述 思路 若本题目使用暴力法则会超时,故而使用单调栈解决: 1.创建结果数组res,和单调栈stack; 2.循环遍历数组temperatures: 2.1.若当stack不为空同时…...
KDE6桌面于2024年2月发布
原文:KDE MegaRelease 6 - KDE 社区 1. **Plasma 6 桌面环境**:KDE Plasma 是一个现代化、功能丰富的 Linux 操作系统桌面环境,以其时尚设计、可定制界面和广泛的应用程序而闻名。Plasma 6 带来了两项重大技术升级:过渡到最新的应…...
「TypeScript系列」TypeScript 对象及对象的使用场景
文章目录 一、TypeScript 对象1. 对象字面量2. 类实例化3. 使用接口定义对象形状4. 使用类型别名定义对象类型5. 使用工厂函数创建对象 二、TypeScript 对象属性及方法1. 对象属性2. 对象方法3. 访问器和修改器(Getters 和 Setters) 三、TypeScript 对象…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
海云安高敏捷信创白盒SCAP入选《中国网络安全细分领域产品名录》
近日,嘶吼安全产业研究院发布《中国网络安全细分领域产品名录》,海云安高敏捷信创白盒(SCAP)成功入选软件供应链安全领域产品名录。 在数字化转型加速的今天,网络安全已成为企业生存与发展的核心基石,为了解…...
电脑桌面太单调,用Python写一个桌面小宠物应用。
下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡,可以响应鼠标点击,并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...
高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...
Python的__call__ 方法
在 Python 中,__call__ 是一个特殊的魔术方法(magic method),它允许一个类的实例像函数一样被调用。当你在一个对象后面加上 () 并执行时(例如 obj()),Python 会自动调用该对象的 __call__ 方法…...
使用VMware克隆功能快速搭建集群
自己搭建的虚拟机,后续不管是学习java还是大数据,都需要集群,java需要分布式的微服务,大数据Hadoop的计算集群,如果从头开始搭建虚拟机会比较费时费力,这里分享一下如何使用克隆功能快速搭建一个集群 先把…...
