这篇文章的灵感来自于上篇文章px4 make 固件的顺序和过程细节,写完发现中间有一些忽略的细节。补充一下
希望点赞和收藏❤️
上篇的文章中给出了编译的全流程,如下所示。本篇文章介绍A-D环节。
A[make命令] --> B[读取顶级Makefile]
B --> C[调用boards_dir扫描]
C --> D[定位板级目录]
D --> E[加载default.px4board]
E --> F[初始化CMake系统]
F --> G[加载平台级CMake]
G --> H[架构级配置]
H --> I[驱动层编译]
I --> J[应用层编译]
J --> K[生成固件]
在px4目录下我们输入命令 make holybro_kakuteh7_default就会在命令窗口开始编译过程。编译的顶级入口是根目录下的Makefile文件,和Cmakelists.txt文件。这两个文件分别是make和cmake的入口。
用户命令 make holybro_kakuteh7_default
首先由 Makefile处理,接下来我们仔细阅读这个文件。有些语法读不懂,直接deepseek和豆包了。我们逐行分析。
ifeq ($(wildcard .git),)
$(error YOU HAVE TO USE GIT TO DOWNLOAD THIS REPOSITORY. ABORTING.)
endif
强制要求使用Git仓库(检查.git目录是否存在)
所以如果你的代码不是通过git clone下载的,会编译失败,因为代码本身会以来其他git仓库的子模块。
all: px4_sitl_default
**`all`** 是一个伪目标(phony target),它是Makefile中的默认目标。 当你在命令行中直接运行`make`(不指定任何目标)时,Make工具会自动选择`all`目标来执行。 **`px4_sitl_default`** 是`all`目标的依赖项。这表示`all`目标的构建依赖于`px4_sitl_default`目标的完成。 这一行确保了默认的构建行为是构建`px4_sitl_default`配置。换句话说,运行`make`等价于运行`make px4_sitl_default`。 - `px4_sitl_default` 是PX4固件的一个特定配置,代表“Software In The Loop”(SITL)的默认仿真环境。它用于在主机上运行PX4的仿真版本,而不需要实际的硬件。- 这种设计是Makefile的常见模式,通过`all`目标提供一个默认的构建入口,方便用户直接使用`make`命令。
# define a space character to be able to explicitly find it in strings space := $(subst ,, )
如英文所示,定义了一个名为
space
的变量,其值为一个空格字符
解释:
$(subst FROM,TO,TEXT)
是 Makefile 的字符串替换函数。这里
FROM
和TO
都是空(,,
),TEXT
是一个空格()。
所以
$(subst ,, )
的结果就是一个空格字符。用途:
在 Makefile 中,空格有时需要显式处理,避免解析错误。这里可能是为了后续的字符串操作做准备。
define make_list $(shell [ -f .github/workflows/compile_${1}.yml ] && cat .github/workflows/compile_${1}.yml | sed -E 's|[[:space:]]+(.*),|check_\1|g' | grep check_${2}) endef
定义一个名为
make_list
的多行函数(Makefile 中的define
类似于其他语言中的函数定义)。
${1}
:第一个参数,通常是平台类型(如nuttx
、linux
)。
${2}
:第二个参数,可选过滤条件(如px4
、nxp
)。检查文件是否存在:
[ -f .github/workflows/compile_${1}.yml ]
:检查.github/workflows/compile_${1}.yml
文件是否存在。如果存在,则执行后续命令(
&&
表示逻辑与)。读取文件内容:
cat .github/workflows/compile_${1}.yml
:输出文件内容。正则替换:
sed -E 's|[[:space:]]+(.*),|check_\1|g'
:
[[:space:]]+
:匹配一个或多个空白字符(空格、制表符等)。
(.*),
:捕获逗号前的所有字符(\1
引用捕获的内容)。替换为
check_\1
,例如将px4_fmu-v2_default,
变成check_px4_fmu-v2_default
。过滤目标:
grep check_${2}
:如果${2}
有值,则只保留包含check_${2}
的行(否则输出所有行)。
define make_list
这是一个函数定义,不会被直接执行,后续代码会进行调用。这个函数用于从 .github/workflows
的 YAML 文件中提取构建目标列表,并添加 check_
前缀。 make holybro_kakuteh7_default不会执行这行代码,
make_list
函数是为 check_
开头的目标(如 check_px4
)服务的,通常用于测试或验证。这行代码在后面调用时再详细分析。
FIRST_ARG := $(firstword $(MAKECMDGOALS)) ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
这两行代码用于解析
make
命令的参数,将第一个目标(FIRST_ARG
)和剩余参数(ARGS
)分开存储,以便后续处理。1.
FIRST_ARG := $(firstword $(MAKECMDGOALS))
作用:提取
make
命令中的第一个目标。分解:
$(MAKECMDGOALS)
:Makefile 内置变量,表示用户输入的所有目标(如make target1 target2
中的target1 target2
)。
$(firstword ...)
:取参数列表的第一个单词。示例:
输入
make holybro_kakuteh7_default upload
FIRST_ARG
=holybro_kakuteh7_default
。
2.
ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS)
作用:提取
make
命令中除第一个目标外的剩余参数。分解:
$(words $(MAKECMDGOALS))
:计算总参数个数。
$(wordlist 2, ..., $(MAKECMDGOALS))
:从第 2 个参数开始提取到最后一个参数。示例:
输入
make holybro_kakuteh7_default upload -j4
ARGS
=upload -j4
。
-
FIRST_ARG
:获取用户输入的主构建目标(如硬件配置或仿真目标)。 -
ARGS
:获取后续参数(如upload
、test
或-j4
),用于控制构建行为
MAKE_PID := $(shell echo $$PPID) j := $(shell ps T | sed -n 's|.*$(MAKE_PID).*$(MAKE).* \(-j\|--jobs\) *\([0-9][0-9]*\).*|\2|p') # Default j for clang-tidy j_clang_tidy := $(or $(j),4)
这段代码用于提取
make
命令的并行编译参数-jN
(例如-j4
或--jobs=8
),并设置默认值,主要用于优化编译和静态分析工具(如clang-tidy
)的并行执行。
MAKE_PID
:获取父进程 ID,用于定位make
命令的进程信息。
j
:提取用户指定的并行编译线程数(如-j8
中的8
)。
j_clang_tidy
:为clang-tidy
设置并行度,优先使用用户指定的-jN
,否则默认 4。目的:统一管理并行任务数,优化编译和静态分析的性能。
Clang-Tidy 是一个基于 LLVM/Clang 的 C/C++ 静态代码分析工具,用于检测代码中的潜在问题、风格违规和可优化的代码模式。它可以自动修复部分问题,帮助开发者提高代码质量、减少错误,并遵循最佳实践。make clang-tidy 调用 PX4 预定义的检查规则
NINJA_BIN := ninja # 默认尝试使用 `ninja` 命令 ifndef NO_NINJA_BUILD # 如果没有明确禁用 Ninja # 检查 `ninja` 是否可用 # 静默运行 ninja --version,成功时返回版本号,失败返回空。 NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null) # 如果 `ninja` 不可用,尝试 `ninja-build` 命令 ifndef NINJA_BUILD NINJA_BIN := ninja-build NINJA_BUILD := $(shell $(NINJA_BIN) --version 2>/dev/null) endif endif
这段代码用于 检测并配置 Ninja 构建工具,它是 PX4 构建系统的重要组成部分。
为什么需要这段代码?
跨平台兼容性:
在 Linux 中,Ninja 通常通过
ninja
命令安装。某些系统(如旧版 Ubuntu)可能将其命名为
ninja-build
。
这段代码自动处理不同名称的兼容性问题。性能优化:
Ninja 比传统make
更快,尤其是在增量编译时。PX4 优先使用 Ninja 以加速构建。灵活控制:
通过NO_NINJA_BUILD=1
可强制禁用 Ninja,回退到 GNU Make(用于调试或兼容旧环境)。对 PX4 构建的影响
构建工具选择:
如果 Ninja 可用,PX4 会生成build.ninja
文件并调用ninja
编译;否则生成Makefile
并调用make
。变量传递:
在后续代码中,PX4_MAKE
会被赋值为$(NINJA_BIN)
或make
ifdef NINJA_BUILD PX4_CMAKE_GENERATOR := Ninja PX4_MAKE := $(NINJA_BIN) ifdef VERBOSE PX4_MAKE_ARGS := -v else PX4_MAKE_ARGS := endif # Only override ninja default if -j is set. ifneq ($(j),) PX4_MAKE_ARGS := $(PX4_MAKE_ARGS) -j$(j) endif else 如果未检测到 Ninja ifdef SYSTEMROOT # 检测 Windows 环境 # Windows PX4_CMAKE_GENERATOR := "MSYS\ Makefiles" # Windows 用 MSYS Makefiles else PX4_CMAKE_GENERATOR := "Unix\ Makefiles" # Linux/macOS 用 Unix Makefiles endif # For non-ninja builds we default to -j4 默认并行数 (-j4) j := $(or $(j),4) PX4_MAKE = $(MAKE) # 构建命令设为 make PX4_MAKE_ARGS = -j$(j) --no-print-directory # 强制多线程,禁止目录切换日志 endif
这段代码是 PX4 构建系统的核心配置逻辑,用于根据是否检测到 Ninja 构建工具,设置不同的构建参数和生成器(Generator)
如果检测到 Ninja (
ifdef NINJA_BUILD
)PX4_CMAKE_GENERATOR := Ninja # 告诉 CMake 使用 Ninja 作为生成器
PX4_MAKE := $(NINJA_BIN) # 实际构建命令设为 ninja 或 ninja-build
处理构建参数 (
PX4_MAKE_ARGS
)
VERBOSE
模式
VERBOSE
是一个 控制构建输出详细程度的开关变量。它的核心作用是:决定是否在编译过程中显示完整的底层命令(如编译器指令、链接参数等)ifdef VERBOSE PX4_MAKE_ARGS := -v # Ninja 的 -v 参数输出详细编译命令 else PX4_MAKE_ARGS := # 默认静默模式 endif并行编译 (
-jN
)ifneq ($(j),) # 如果用户通过 -jN 指定了并行数 PX4_MAKE_ARGS := $(PX4_MAKE_ARGS) -j$(j) # 传递给 Ninja endifNinja 默认会自动使用多核,
-jN
仅用于覆盖其默认行为。为什么需要这种设计?
性能优先:
Ninja 比 Make 更快,尤其在增量构建时。跨平台兼容:
Windows 需特殊处理生成器类型。用户体验:
自动选择最优工具,同时允许手动覆盖。
SRC_DIR := $(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))") # check if replay env variable is set & set build dir accordingly ifdef replay BUILD_DIR_SUFFIX := _replay else BUILD_DIR_SUFFIX := endif CMAKE_ARGS ?=
这段代码是 PX4 构建系统中用于 设置关键路径和构建参数 的逻辑
SRC_DIR
定义:获取当前 Makefile 所在的绝对路径作为项目根目录
分解:
$(MAKEFILE_LIST)
:当前加载的 Makefile 文件列表。
$(lastword ...)
:取列表中最后一个文件(主 Makefile)。
$(realpath ...)
:转换为绝对路径(解析软链接)。
$(dirname ...)
:提取目录部分。示例:
若 Makefile 路径为/home/user/PX4-Autopilot/Makefile
,则SRC_DIR = /home/user/PX4-Autopilot
。
BUILD_DIR_SUFFIX
设置
作用:根据是否启用
replay
模式,决定构建目录的后缀。
若定义了
replay
环境变量(如export replay=1
),则构建目录会添加_replay
后缀(例如build/px4_fmu-v5_default_replay
)。否则无后缀(例如
build/px4_fmu-v5_default
)。用途:
PX4 的 Replay 模式用于重放飞行日志,需要独立的构建目录以避免与正常构建冲突。
CMAKE_ARGS
初始化CMAKE_ARGS ?=作用:声明一个可被用户覆盖的 CMake 参数变量。
?=
表示仅当变量未定义时才赋空值。用户可通过命令行或环境变量传递自定义 CMake 参数
例如 make CMAKE_ARGS="-DDEBUG=ON" px4_fmu-v5_default,我怎么知道CMAKE_ARGS都有哪些参数呢,可以直接查看 CMake 脚本,浏览 CMakeLists.txt文件,比如,我在px4的根目录下输入
grep -r "option(" CMakeLists.txt src/
搜索到的内容,是 PX4 项目中所有通过 CMake 的
option()
命令定义的 可配置编译选项。这些选项允许开发者在构建时自定义功能模块、调试设置等。截取部分解释如下
PYTHON_COVERAGE
启用 Python 代码覆盖率统计(用于测试) OFF
CMAKE_TESTING
是否编译测试代码 OFF
其他类似。
外部模块路径配置 作用:如果用户定义了 EXTERNAL_MODULES_LOCATION 环境变量,将其作为 CMake 参数传递。 用途:指定外部模块(非 PX4 主代码库的模块)的存放路径。 ifdef EXTERNAL_MODULES_LOCATION override CMAKE_ARGS += -DEXTERNAL_MODULES_LOCATION:STRING=$(EXTERNAL_MODULES_LOCATION) endif
示例:
export EXTERNAL_MODULES_LOCATION=/path/to/external_modules make px4_sitl_default
px4的功能代码块都在px4文件夹下,如果你自己定义了额外的功能模块,并且没有放在src文件夹下,那么就需要执行以上命令。
2. 构建类型配置 (1) 直接指定构建类型 如果用户通过 PX4_CMAKE_BUILD_TYPE 显式定义了构建类型(如 Debug/Release),直接传递给 CMake。 在 PX4 的构建系统中,PX4_CMAKE_BUILD_TYPE 用于指定不同的构建类型,每种类型会启用特定的编译器选项和优化策略。 ifdef PX4_CMAKE_BUILD_TYPE override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=${PX4_CMAKE_BUILD_TYPE}
PX4_CMAKE_BUILD_TYPE都有哪些呢,我通过deepseek找到了一些
类型 含义 适用场景 Debug
启用调试符号,禁用优化,便于调试。 开发阶段(GDB 调试、崩溃分析)。 Release
最大优化(如 -O3
),禁用调试符号。正式发布(追求最高性能)。 RelWithDebInfo
优化级别 -O2
,但保留调试符号。需要平衡性能与调试的场景(如现场问题排查)。 MinSizeRel
优化以减少代码体积(如 -Os
)。资源受限的硬件(如 Flash 空间紧张的飞控)。 使用时,例如
# 1. 启用 Debug 构建 make px4_sitl_default PX4_CMAKE_BUILD_TYPE=Debug
(2) 自动化工具链配置(Sanitizers/Fuzzing) 如果未指定 PX4_CMAKE_BUILD_TYPE,则检查以下代码分析工具的环境变量,并自动设置对应的构建类型: else # Address Sanitizer ifdef PX4_ASAN override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=AddressSanitizer endif # Memory Sanitizer ifdef PX4_MSAN override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=MemorySanitizer endif # Thread Sanitizer ifdef PX4_TSAN override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=ThreadSanitizer endif # Undefined Behavior Sanitizer ifdef PX4_UBSAN override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=UndefinedBehaviorSanitizer endif # Fuzz Testing ifdef PX4_FUZZ override CMAKE_ARGS += -DCMAKE_BUILD_TYPE=FuzzTesting endif endif
环境变量 | 对应的 CMake 构建类型 | 作用 |
---|---|---|
PX4_ASAN | AddressSanitizer | 检测内存错误(如越界访问、释放后使用)。 |
PX4_MSAN | MemorySanitizer | 检测未初始化的内存读取。 |
PX4_TSAN | ThreadSanitizer | 检测多线程竞争条件。 |
PX4_UBSAN | UndefinedBehaviorSanitizer | 检测未定义行为(如整数溢出、空指针解引用)。 |
PX4_FUZZ | FuzzTesting | 启用模糊测试(Fuzzing)相关的编译选项。 |
实例:make px4_sitl_default PX4_ASAN=1 ,表示启用地址消毒器(ASan)。
关键点说明
override
关键字:确保强制覆盖CMAKE_ARGS
中可能已存在的参数。
+=
操作符:追加参数,而非覆盖整个变量。
:STRING
类型声明:显式指定 CMake 参数类型(可选,但提高可读性)。
ifdef PYTHON_EXECUTABLE override CMAKE_ARGS += -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} endif
允许用户自定义 Python 解释器的路径
作用:如果用户通过环境变量
PYTHON_EXECUTABLE
指定了 Python 解释器的路径,则将其作为 CMake 参数-DPYTHON_EXECUTABLE
传递给构建系统。关键点:
override
:确保强制覆盖 CMake 中可能已存在的同名参数。
+=
:追加参数,不影响其他已定义的CMAKE_ARGS
。使用方法
(1) 临时指定 Python 路径
# 明确使用 /usr/bin/python3 make px4_sitl_default PYTHON_EXECUTABLE=/usr/bin/python3
(2) 通过环境变量永久设置
# 在 shell 配置文件中设置(如 ~/.bashrc) export PYTHON_EXECUTABLE=~/.conda/envs/px4/bin/python
通过 grep "PYTHON_EXECUTABLE" build/px4_sitl_default/CMakeCache.txt输出应显示指定的 Python 路径,例如:PYTHON_EXECUTABLE:FILEPATH=/usr/bin/python3
define cmake-build $(eval override CMAKE_ARGS += -DCONFIG=$(1)) @$(eval BUILD_DIR = "$(SRC_DIR)/build/$(1)") @# check if the desired cmake configuration matches the cache then CMAKE_CACHE_CHECK stays empty @$(call cmake-cache-check) @# make sure to start from scratch when switching from GNU Make to Ninja @if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ -e $(BUILD_DIR)/Makefile ]; then rm -rf $(BUILD_DIR); fi @# make sure to start from scratch if ninja build file is missing @if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ ! -f $(BUILD_DIR)/build.ninja ]; then rm -rf $(BUILD_DIR); fi @# only excplicitly configure the first build, if cache file already exists the makefile will rerun cmake automatically if necessary @if [ ! -e $(BUILD_DIR)/CMakeCache.txt ] || [ $(CMAKE_CACHE_CHECK) ]; then \ mkdir -p $(BUILD_DIR) \ && cd $(BUILD_DIR) \ && cmake "$(SRC_DIR)" -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS) \ || (rm -rf $(BUILD_DIR)); \ fi @# run the build for the specified target @cmake --build $(BUILD_DIR) -- $(PX4_MAKE_ARGS) $(ARGS) endef
cmake-build
函数功能:负责执行完整的 CMake 构建流程,包括配置(configure)和编译(build)。
参数
$(1)
:构建目标的名称(如px4_fmu-v5_default
)。执行步骤
设置配置参数 $(eval override CMAKE_ARGS += -DCONFIG=$(1)),将
-DCONFIG=<目标名>
添加到CMAKE_ARGS
中。定义构建目录 @$(eval BUILD_DIR = "$(SRC_DIR)/build/$(1)"),构建路径为
PX4-Autopilot/build/<目标名>/。
检查配置缓存 @$(call cmake-cache-check),调用 cmake-cache-check 函数,检查当前 CMAKE_ARGS 是否与缓存一致。
清理旧构建(必要时)
@if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ -e $(BUILD_DIR)/Makefile ]; then rm -rf $(BUILD_DIR); fi
@if [ $(PX4_CMAKE_GENERATOR) = "Ninja" ] && [ ! -f $(BUILD_DIR)/build.ninja ]; then rm -rf $(BUILD_DIR); fi。如果从 Make 切换到 Ninja,或 Ninja 构建文件丢失,则清理目录运行 CMake 配置
@if [ ! -e $(BUILD_DIR)/CMakeCache.txt ] || [ $(CMAKE_CACHE_CHECK) ]; then \
mkdir -p $(BUILD_DIR) \
&& cd $(BUILD_DIR) \
&& cmake "$(SRC_DIR)" -G"$(PX4_CMAKE_GENERATOR)" $(CMAKE_ARGS) \
|| (rm -rf $(BUILD_DIR)); \
fi如果缓存不存在或配置不匹配,则重新运行 CMake。
执行构建 cmake --build $(BUILD_DIR) -- $(PX4_MAKE_ARGS) $(ARGS),调用
cmake --build
实际编译代码,传递PX4_MAKE_ARGS
(如-j8
)和用户参数$(ARGS)
(如upload)
define cmake-cache-check @# change to build folder which fails if it doesn't exist and CACHED_CMAKE_OPTIONS stays empty @# fetch all previously configured and cached options from the build folder and transform them into the OPTION=VALUE format without type (e.g. :BOOL) @$(eval CACHED_CMAKE_OPTIONS = $(shell cd $(BUILD_DIR) 2>/dev/null && cmake -L 2>/dev/null | sed -n 's|\([^[:blank:]]*\):[^[:blank:]]*\(=[^[:blank:]]*\)|\1\2|gp' )) @# transform the options in CMAKE_ARGS into the OPTION=VALUE format without -D @$(eval DESIRED_CMAKE_OPTIONS = $(shell echo $(CMAKE_ARGS) | sed -n 's|-D\([^[:blank:]]*=[^[:blank:]]*\)|\1|gp' )) @# find each currently desired option in the already cached ones making sure the complete configured string value is the same @$(eval VERIFIED_CMAKE_OPTIONS = $(foreach option,$(DESIRED_CMAKE_OPTIONS),$(strip $(findstring $(option)$(space),$(CACHED_CMAKE_OPTIONS))))) @# if the complete list of desired options is found in the list of verified options we don't need to reconfigure and CMAKE_CACHE_CHECK stays empty @$(eval CMAKE_CACHE_CHECK = $(if $(findstring $(DESIRED_CMAKE_OPTIONS),$(VERIFIED_CMAKE_OPTIONS)),,y)) endef
cmake-cache-check
函数功能
比较当前的
CMAKE_ARGS
与构建目录中缓存的 CMake 配置,判断是否需要重新配置。执行步骤
提取缓存的 CMake 选项 @$(eval CACHED_CMAKE_OPTIONS = $(shell cd $(BUILD_DIR) 2>/dev/null && cmake -L 2>/dev/null | sed -n 's|\([^[:blank:]]*\):[^[:blank:]]*\(=[^[:blank:]]*\)|\1\2|gp' ))
进入构建目录,运行
cmake -L
列出所有缓存变量。使用
sed
移除变量类型(如:BOOL
),格式化为VAR=VALUE
提取当前的 CMake 参数 @$(eval DESIRED_CMAKE_OPTIONS = $(shell echo $(CMAKE_ARGS) | sed -n 's|-D\([^[:blank:]]*=[^[:blank:]]*\)|\1|gp' ))
CMAKE_ARGS
中去掉-D
前缀,格式化为VAR=VALUE
验证参数一致性 @$(eval VERIFIED_CMAKE_OPTIONS = $(foreach option,$(DESIRED_CMAKE_OPTIONS),$(strip $(findstring $(option)$(space),$(CACHED_CMAKE_OPTIONS)))))检查每个当前参数是否与缓存完全匹配
设置重新配置标志 @$(eval CMAKE_CACHE_CHECK = $(if $(findstring $(DESIRED_CMAKE_OPTIONS),$(VERIFIED_CMAKE_OPTIONS)),,y))如果不匹配,设置
CMAKE_CACHE_CHECK=y
,触发重新配置。
关键设计思想
增量配置
仅当参数变化时重新运行 CMake,避免不必要的重复配置。
跨生成器兼容
处理 Ninja 和 Make 生成器的切换场景,确保构建目录干净。
用户参数透传
将
$(ARGS)
(如upload
)传递给底层的构建工具(Ninja/Make)。(1) 普通构建 make px4_fmu-v5_default
调用
cmake-build
函数,配置并编译px4_fmu-v5_default
。(2) 带参数构建 make px4_fmu-v5_default upload -j8
$(ARGS)
包含upload
,PX4_MAKE_ARGS
包含-j8
。(3) 强制重新配置 rm -rf build/px4_fmu-v5_default,make px4_fmu-v5_default 删除构建目录后,
cmake-cache-check
会触发重新配置。
COLOR_BLUE = \033[0;94m # 蓝色 ANSI 转义码 NO_COLOR = \033[m # 重置颜色的 ANSI 转义码 define colorecho +@echo -e '${COLOR_BLUE}${1} ${NO_COLOR}' endef
定义了一个 带颜色输出的 Shell 回显功能,用于在终端中显示彩色的文本(这里是蓝色)
\033
:ASCII 转义字符(Esc),表示开始控制序列。
[0;94m
:
0
表示正常样式(非粗体/斜体)。
94
是亮蓝色的颜色代码。
[m
:重置所有样式和颜色。📌 ANSI 颜色代码参考:
30-37
:标准色(黑、红、绿、黄等)
90-97
:亮色(灰、亮红、亮蓝等)
39
:默认前景色
49
:默认背景色
colorecho
函数
功能:输出蓝色文字,并在末尾重置颜色。
参数:
${1}
:要显示的文本内容。关键符号:
+@
:
+
表示始终执行该命令(即使 Make 运行在-n
只打印模式)。
@
抑制命令本身的回显(不显示echo
这一行)。
-e
:允许echo
解释转义字符(如\033
)。确保始终用
${NO_COLOR}
重置,否则后续所有文本可能保持蓝色!
这篇文章先分析这么多,makefile实在太多了,下次接着看。有些直接deepseek和元宝搜的,根据自己的理解进行了整理。下篇文章继续!