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

相关文章

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和

Spring Boot 整合 Apache Flink 的详细过程

《SpringBoot整合ApacheFlink的详细过程》ApacheFlink是一个高性能的分布式流处理框架,而SpringBoot提供了快速构建企业级应用的能力,下面给大家介绍Spri... 目录Spring Boot 整合 Apache Flink 教程一、背景与目标二、环境准备三、创建项目 & 添

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获

Spring Boot中的YML配置列表及应用小结

《SpringBoot中的YML配置列表及应用小结》在SpringBoot中使用YAML进行列表的配置不仅简洁明了,还能提高代码的可读性和可维护性,:本文主要介绍SpringBoot中的YML配... 目录YAML列表的基础语法在Spring Boot中的应用从YAML读取列表列表中的复杂对象其他注意事项总

Spring Boot 整合 Redis 实现数据缓存案例详解

《SpringBoot整合Redis实现数据缓存案例详解》Springboot缓存,默认使用的是ConcurrentMap的方式来实现的,然而我们在项目中并不会这么使用,本文介绍SpringB... 目录1.添加 Maven 依赖2.配置Redis属性3.创建 redisCacheManager4.使用Sp

redis在spring boot中异常退出的问题解决方案

《redis在springboot中异常退出的问题解决方案》:本文主要介绍redis在springboot中异常退出的问题解决方案,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴... 目录问题:解决 问题根源️ 解决方案1. 异步处理 + 提前ACK(关键步骤)2. 调整Redis消费者组

Spring Boot 事务详解(事务传播行为、事务属性)

《SpringBoot事务详解(事务传播行为、事务属性)》SpringBoot提供了强大的事务管理功能,通过@Transactional注解可以方便地配置事务的传播行为和属性,本文将详细介绍Spr... 目录Spring Boot 事务详解引言声明式事务管理示例编程式事务管理示例事务传播行为1. REQUI

Spring Boot 集成 Solr 的详细示例

《SpringBoot集成Solr的详细示例》:本文主要介绍SpringBoot集成Solr的详细示例,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录环境准备添加依赖配置 Solr 连接定义实体类编写 Repository 接口创建 Service 与 Controller示例运行