Makefile学习笔记16|u-boot顶层Makefile02

2024-05-24 16:12

本文主要是介绍Makefile学习笔记16|u-boot顶层Makefile02,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Makefile学习笔记16|u-boot顶层Makefile02

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

  这里是目录

设置输出文件路径

# 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)
ifeq ($(KBUILD_SRC),)# OK, Make called in directory where kernel src resides
# Do we want to locate output files in a separate directory?
ifeq ("$(origin O)", "command line")KBUILD_OUTPUT := $(O)
endif

  这段代码解释了 KBUILD 系统如何支持在与源代码树分离的目录中保存输出文件。基本上,这种功能允许你在构建内核时保持源码目录的干净,所有编译生成的文件(对象文件、配置文件和最终的内核镜像等)都将被放置在一个单独的目录。这被称为"out-of-tree"构建。这段代码涉及的两个主要概念:

  1. O= 指令。在命令行中使用 O= 选项与 make 命令一起,指定输出文件的存储目录。例如:
make O=dir/to/store/output/files/

这会告诉 make 将所有的输出文件(如 .o 对象文件和编译后的内核映像)放在指定的目录中。

  1. KBUILD_OUTPUT 环境变量。设置 KBUILD_OUTPUT 环境变量也可以达到同样的目的,但是不需要每次都在 make 命令中指定:
export KBUILD_OUTPUT=dir/to/store/output/files/

设置 KBUILD_OUTPUT 后,所有后续的 make 调用都将自动使用这个环境变量中指定的目录来存储输出文件。

  以上就是支持 out-of-tree 构建的 kbuild 系统一部分的逻辑,这让内核编译变得更加灵活和整洁。通过使用这个功能,多个构建可以共存而不会互相干扰,并且清理构建产物也变得更加容易。

设置默认Target

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

  在这段特定代码中,没有指定 _all 目标实际应该执行的命令或依赖的其他目标。通常,在完整的 Makefile 中,_all 目标会作为一个入口点,依赖实际的构建目标。

  在定义 .PHONY 的时候,通常会把所有不会生成同名输出文件的目标都定义为 .PHONY,这样可以防止 Make 错误地跳过这些目标,因为 Make 的默认行为是只构建那些比它们的依赖文件更新的目标。设置 .PHONY 可以确保无论环境如何改变,指定的目标总是被执行。

取消隐式规则

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

  在 Makefile 中,这行代码用于取消指定文件(在这种情况下是 Makefile 文件本身)的隐式规则。

  $(CURDIR)/Makefile Makefile: ; 和 MAKEFLAGS += -rR 是用来影响 make 行为的两种不同的方法,并且它们有着不同的目的。虽然两者都与禁用某些隐含行为有关,但它们的作用并不完全重复。

  这条规则是专门针对 Makefile(或任何其他特定文件)的,它定义了一个空规则,避免 make 根据任何内置的隐含规则尝试去重新生成 Makefile 文件。这在确保 Makefile 不被自动更新时很有用,如避免在存在预处理步骤(例如模式规则或自动生成 Makefile)的情况下意外地重建它。

  通常,你可以根据需要选择合适的方法或者两者结合使用。如果你只是想防止某个或某些特定文件被隐含规则所更新(如 Makefile),那么使用空规则是合适的。如果你想全面地提高构建的确定性和性能,并且防止任何潜在的隐含规则或变量干扰你的构建过程,那么 MAKEFLAGS += -rR 更适合。两者一起使用可以确保 Makefile 的稳定性,并为整个构建过程提供可靠和一致的输出,特别是在复杂或具有高度自定义性的构建系统中,这种严格控制可能是必要的。

创建输出文件目录

  我们以make TQM823L_defconfig为例,由于我们没有指定输出文件目录,以下代码将不会执行!!!

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)"))

  整个逻辑确保了在再次调用 make 之前,输出目录已存在且可以使用。如果创建目录失败,构建过程将不会继续,用户会收到明确的错误信息。通过在 Makefile 中进行目录检查和创建,这段代码简化了外部构建流程,并为用户提供了一致和可靠的行为。

构建 sub-make 依赖

  我们以make TQM823L_defconfig为例,由于我们没有指定输出文件目录,以下代码将不会执行!!!

MAKEFLAGS += --include-dir=$(CURDIR)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))# Leave processing to above invocation of make
skip-makefile := 1
endif # ifneq ($(KBUILD_OUTPUT),)
endif # ifeq ($(KBUILD_SRC),)

  .PHONY 目标定义了 sub-make 规则,它强制每次都执行,即使是 up-to-date 的情况下(由于依赖了 .PHONY 的 FORCE 目标)。

  这里定义了一个函数,其作用是当执行命令行目标时,先过滤掉 _all 和 sub-make,如果目标不是 $(CURDIR)/Makefile,则将它们作为依赖关系加入到 sub-make 目标。如果我像u-boot的readme中一样输入了make TQM823L_defconfig,则 TQM823L_defconfig 会成为sub-make的依赖。

  这段脚本设计为从内核源代码的根目录执行,并通过 sub-make 目标将实际构建工作移动到 KBUILD_OUTPUT 指定的外部目录中去。这种方法使内核源代码保持干净,避免了中间对象和二进制文件污染源代码树,同时也提供了灵活性,比如能够同时进行多个构建过程。

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

这篇关于Makefile学习笔记16|u-boot顶层Makefile02的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/998889

相关文章

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

Spring Boot配置和使用两个数据源的实现步骤

《SpringBoot配置和使用两个数据源的实现步骤》本文详解SpringBoot配置双数据源方法,包含配置文件设置、Bean创建、事务管理器配置及@Qualifier注解使用,强调主数据源标记、代... 目录Spring Boot配置和使用两个数据源技术背景实现步骤1. 配置数据源信息2. 创建数据源Be

Spring Boot 3.x 中 WebClient 示例详解析

《SpringBoot3.x中WebClient示例详解析》SpringBoot3.x中WebClient是响应式HTTP客户端,替代RestTemplate,支持异步非阻塞请求,涵盖GET... 目录Spring Boot 3.x 中 WebClient 全面详解及示例1. WebClient 简介2.

在IntelliJ IDEA中高效运行与调试Spring Boot项目的实战步骤

《在IntelliJIDEA中高效运行与调试SpringBoot项目的实战步骤》本章详解SpringBoot项目导入IntelliJIDEA的流程,教授运行与调试技巧,包括断点设置与变量查看,奠定... 目录引言:为良驹配上好鞍一、为何选择IntelliJ IDEA?二、实战:导入并运行你的第一个项目步骤1

Spring Boot从main方法到内嵌Tomcat的全过程(自动化流程)

《SpringBoot从main方法到内嵌Tomcat的全过程(自动化流程)》SpringBoot启动始于main方法,创建SpringApplication实例,初始化上下文,准备环境,刷新容器并... 目录1. 入口:main方法2. SpringApplication初始化2.1 构造阶段3. 运行阶

Spring Boot 与微服务入门实战详细总结

《SpringBoot与微服务入门实战详细总结》本文讲解SpringBoot框架的核心特性如快速构建、自动配置、零XML与微服务架构的定义、演进及优缺点,涵盖开发环境准备和HelloWorld实战... 目录一、Spring Boot 核心概述二、微服务架构详解1. 微服务的定义与演进2. 微服务的优缺点三