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 + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

Spring Boot结成MyBatis-Plus最全配置指南

《SpringBoot结成MyBatis-Plus最全配置指南》本文主要介绍了SpringBoot结成MyBatis-Plus最全配置指南,包括依赖引入、配置数据源、Mapper扫描、基本CRUD操... 目录前言详细操作一.创建项目并引入相关依赖二.配置数据源信息三.编写相关代码查zsRArly询数据库数

一文详解如何从零构建Spring Boot Starter并实现整合

《一文详解如何从零构建SpringBootStarter并实现整合》SpringBoot是一个开源的Java基础框架,用于创建独立、生产级的基于Spring框架的应用程序,:本文主要介绍如何从... 目录一、Spring Boot Starter的核心价值二、Starter项目创建全流程2.1 项目初始化(

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

Spring Boot 集成 Quartz 使用Cron 表达式实现定时任务

《SpringBoot集成Quartz使用Cron表达式实现定时任务》本文介绍了如何在SpringBoot项目中集成Quartz并使用Cron表达式进行任务调度,通过添加Quartz依赖、创... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Spring、Spring Boot、Spring Cloud 的区别与联系分析

《Spring、SpringBoot、SpringCloud的区别与联系分析》Spring、SpringBoot和SpringCloud是Java开发中常用的框架,分别针对企业级应用开发、快速开... 目录1. Spring 框架2. Spring Boot3. Spring Cloud总结1. Sprin

Spring Boot拦截器Interceptor与过滤器Filter详细教程(示例详解)

《SpringBoot拦截器Interceptor与过滤器Filter详细教程(示例详解)》本文详细介绍了SpringBoot中的拦截器(Interceptor)和过滤器(Filter),包括它们的... 目录Spring Boot拦截器(Interceptor)与过滤器(Filter)详细教程1. 概述1