资讯动态

Matter 仓库 CI 中 ccache 的故障排查与缓存控制完整指南

发布时间:2026/9/17 23:55:46 来源:尧图企业网站定制
Matter 仓库 CI 中 ccache 的故障排查与缓存控制完整指南【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip本篇技术指南聚焦于 connectedhomeipMatter仓库在 GitHub Actions CI 中如何使用 ccache 加速 C/C 构建覆盖缓存存储与轮换机制、按运行禁用缓存、强制缓存轮换、master 分支构建失败时的自动重试以及命中率调试等实操问题。读完本文你将掌握[no-ccache]、disable_ccache、cache_suffix等控制手段的原理与用法并理解CCACHE_COMPILERCHECK、CCACHE_SLOPPINESS等关键环境变量对构建正确性的影响可直接对照本仓库的 workflow 与 action 配置进行排障。适用范围本文描述的内容仅适用于 GitHub Actions CI不涉及本地开发环境的 ccache 配置。原文档见 docs/tips_and_troubleshooting/ci-ccache.md。ccache 在 CI 中的角色与存储机制Matter 仓库体量庞大C/C 编译对象数以万计每次 CI 全量编译代价极高。因此 CI 引入 ccache 作为编译缓存层对 C/C 构建进行加速。缓存存储介质缓存通过 GitHub Actions Cacheactions/cache持久化落地目录为工作区下的.ccache即CCACHE_DIR${GITHUB_WORKSPACE}/.ccache并在每次运行时由 setup-ccache action 执行恢复与保存。缓存轮换外部缓存键cache key按周轮换保证缓存不会无限膨胀、始终相对新鲜。正确性保证即使命中了外部缓存ccache 仍会对每一个对象object做逐项校验编译器、预处理结果、环境等确保复用的对象与当前构建输入一致不会因为缓存键相同而盲目复用脏数据。常用控制手段如何按需关闭或强制轮换 ccache场景一为一次运行禁用 ccache当怀疑缓存命中导致构建行为异常、或需要验证无缓存下的干净构建时可以二选一在提交信息中加入[no-ccache]标记。workflow 在计算环境变量时会检查github.event.head_commit.message是否包含该字符串DISABLE_CCACHE: ${{ (github.event_name workflow_dispatch inputs.disable_ccache true) true || (contains(github.event.head_commit.message, [no-ccache]) true) || false }}来源.github/workflows/tests.yaml。手动触发workflow_dispatchTests工作流将输入参数disable_ccache设为true。该参数在 workflow 顶部定义disable_ccache: description: Disable ccache restore and builds (sets CCACHE_DISABLE1)见 .github/workflows/tests.yaml当上述任一条件成立时DISABLE_CCACHE环境变量被置为true。随后在 setup-ccache action 中会执行echo CCACHE_DISABLE1 $GITHUB_ENV设置CCACHE_DISABLE1意味着 ccache 被完全旁路——既不做缓存恢复restore 步骤被if: ${{ inputs.disable ! true }}跳过构建命令经过 ccache 包装后也会直接透传给真实编译器等同一次干净构建。场景二强制缓存轮换当怀疑缓存数据损坏、或希望为某次运行生成全新的缓存档案时手动触发Tests工作流并设置cache_suffix为任意字符串例如一个短哈希cache_suffix: description: Optional suffix appended to ccache key to rotate (e.g. short hash)见 .github/workflows/tests.yaml该后缀会追加到缓存键之后从而生成一个全新的缓存键、创建全新的缓存档案CACHE_SUFFIX${{ inputs.cache-suffix }} if [ -n $CACHE_SUFFIX ]; then CCACHE_KEYccache-${{ runner.os }}-${{ inputs.build-variant }}-${CACHE_SUFFIX} else CCACHE_KEYccache-${{ runner.os }}-${{ inputs.build-variant }} fi来源.github/actions/setup-ccache/action.yml。同时缓存恢复restore使用的是带前缀的模糊匹配键CCACHE_RESTORE_KEYccache-${{ runner.os }}-${{ inputs.build-variant }}-见 .github/actions/setup-ccache/action.yml因此设置了cache_suffix的运行虽然写入一个带后缀的新键但仍可读回历史的无后缀缓存实现新档案可继承旧数据的平滑轮换。缓存键的组成从上面的逻辑可以看出ccache 缓存键由三部分构成组成取值示例作用固定前缀ccache-标识缓存类型运行环境${{ runner.os }}区分 Linux / macOS 等避免跨平台复用构建变体${{ inputs.build-variant }}区分不同构建目标如linux-x64-test、python等可选后缀cache_suffix输入用于强制轮换、创建新档案master 构建失败时的自动兜底重试在master分支上如果 Linux 作业的首次构建失败CI 会自动在禁用 ccache 的情况下重试一次。这一设计基于一个朴素但实用的判断ccache 命中一般不会导致失败但一旦出现缓存相关异常如损坏对象、竞态关闭缓存重跑往往能直接验证问题是否由缓存引起从而避免 master 上的红 build 长期阻塞。该机制只对master分支github.ref refs/heads/master生效且仅在未显式禁用 ccacheenv.DISABLE_CCACHE ! true时才触发相关条件分散在 .github/workflows/tests.yaml 的保存缓存步骤中如 第 549 行 的ccache --evict-older-than 1d。调试技巧命中率、编译器与时间宏查看命中率统计CI 已内置ccache -s统计步骤用于检查命中/未命中率。构建阶段结束后 workflow 会运行ccache -s见 .github/workflows/tests.yaml。排查时重点关注cache hit rate总命中率包含直接命中与预处理命中cache miss/cache hit (direct)区分未命中与直接命中判断缓存是否真正被利用cache size当前缓存体积受CCACHE_MAXSIZE5G上限约束。另外setup-ccache action 的 post 步骤也会执行ccache --show-stats在工作流结束时自动打印统计。编译器/版本变更由内容校验兜底CI 设置了CCACHE_COMPILERCHECKcontent见 .github/actions/setup-ccache/action.yml这意味着 ccache 通过比较编译器二进制的内容哈希而非默认的mtime或版本字符串来判断编译器是否变化。因此编译器升级、打补丁、更换工具链后即使版本号相同只要内容不同就会自动 miss不会复用旧缓存反之如果工具链二进制在两次构建间完全一致则缓存可安全复用。时间宏time_macros带来的缓存复用语义CI 同时设置了CCACHE_SLOPPINESStime_macros见 .github/actions/setup-ccache/action.ymltime_macros会让 ccache 忽略__DATE__/__TIME__/__TIMESTAMP__这类时间相关宏对缓存键的影响。如果你的构建产物中嵌入了这些宏例如固件构建号、编译时间戳那么需要注意这些对象可能跨多次运行被复用其中的时间宏值不会随构建时间更新。对于依赖编译时间戳的功能应避免依赖该特性或在必要时通过[no-ccache]/cache_suffix强制刷新。配套环境变量与预处理一致性除上述两个关键变量外setup-ccache action 还统一配置了以下环境变量它们共同保证缓存跨运行的可复用性与正确性环境变量值作用CCACHE_NOHASHDIR1目录名不参与哈希跨 checkout 路径复用CCACHE_BASEDIR${GITHUB_WORKSPACE}重写绝对路径消除工作区路径差异对缓存键的影响CCACHE_NODIRECT1关闭直接模式direct mode强制走预处理器模式CCACHE_PREFIX_CPPscripts/helpers/ccache-prefix-cpp.sh为预处理器命令加-P参数CCACHE_DIR${GITHUB_WORKSPACE}/.ccache指定缓存目录CCACHE_MAXSIZE5G缓存上限 5 GBCCACHE_COMPRESS1启用压缩节省传输与存储CCACHE_COMPRESSLEVEL6压缩级别 6CHIP_PW_COMMAND_LAUNCHERccache让 Pigweed 构建系统把命令交给 ccache 启动其中CCACHE_PREFIX_CPP指向仓库内的辅助脚本 scripts/helpers/ccache-prefix-cpp.sh#!/bin/sh # Add -P flag to get rid of #line directives which break caching exec $ -P该脚本为预处理器追加-P参数去掉#line指令。#line指令会因文件路径/行号差异导致预处理输出不一致从而破坏缓存键——去掉后显著提升缓存命中率。CCACHE_BASEDIR配合CCACHE_NOHASHDIR则确保在不同 checkout 路径CI 的工作区路径可能变化之间也能命中缓存。本地构建的脚本 scripts/setup/bootstrap.sh 也设置了CCACHE_BASEDIR、CCACHE_NOHASHDIR1、CCACHE_NODIRECT1与CCACHE_PREFIX_CPP与 CI 配置保持一致。构建系统侧如何接入 ccacheccache 通过命令启动器command launcher接入构建系统这是 Pigweed 构建系统的通用机制。在 .github/workflows/tests.yaml 中可以看到大量示例构建均以如下方式调用--pw-command-launcherccache build --copy-artifacts-to objdir-clone例如 .github/workflows/tests.yaml 起的一组chip-tool等目标构建对于 Python 侧构建则使用--enable-ccache开关并在未禁用时通过 shell 条件注入scripts/run_in_build_env.sh ./scripts/build_python.sh ... $([ ${DISABLE_CCACHE} ! true ] echo --enable-ccache)见 .github/workflows/tests.yaml脚本 scripts/build/build_examples.py 中对该参数有明确说明Set pigweed command launcher. E.g.: --pw-command-launcherccache for using ccache when building examples.缓存保存策略只在 master 落盘缓存写入并非每次运行都执行而是仅在 master 分支github.ref refs/heads/master且未禁用 ccache 时进行。保存前会依次执行见 .github/workflows/tests.yaml# 1. 只保留最近 1 天内有用的缓存对象 ccache --evict-older-than 1d || true # 2. 保存前删除同名旧缓存Delete existing ccache before save # 3. 重新保存本次的 .ccache 目录键为 CCACHE_KEY这样的设计带来两个好处避免缓存频繁全量上传PR 的每次构建如果都写入缓存会产生大量无效写操作只由 master 维护缓存内容更稳定、更可信缓存体积受控--evict-older-than 1d配合CCACHE_MAXSIZE5G防止缓存无限膨胀同时CCACHE_COMPRESS1/CCACHE_COMPRESSLEVEL6压缩上传体积降低 GitHub Actions Cache 配额压力。如果需要在团队侧手动清理某条缓存键仓库还提供了独立的 buildjet-cache-delete workflow可输入cache_key手动删除指定缓存。总结与决策速查需求操作原理单次运行禁用缓存提交信息含[no-ccache]或手动触发Tests并设disable_ccachetrue设置CCACHE_DISABLE1跳过 restore 并旁路构建强制轮换缓存手动触发Tests并设cache_suffix短哈希后缀追加到缓存键创建新档案restore 仍可回退旧键master 构建偶发失败无需干预Linux 作业首次构建失败后自动禁用 ccache 重试排查命中率查看ccache -s/ccache --show-stats输出区分直接命中、预处理命中与未命中编译器变更无需干预CCACHE_COMPILERCHECKcontent按内容校验自动 miss构建含__DATE__/__TIME__评估对象复用影响CCACHE_SLOPPINESStime_macros下这些宏不参与缓存键整体而言Matter 仓库的 ccache 体系遵循大胆缓存、小心校验的原则用宽松的缓存键周轮换 time_macros换取高命中率用逐对象校验CCACHE_COMPILERCHECKcontent与便捷的禁用/轮换控制手段保证构建正确性并以 master-only 的保存策略控制缓存成本——这套设计对大型嵌入式 C/C 仓库的 CI 提速具有很强的参考价值。相关实现细节可继续阅读 .github/workflows/tests.yaml、.github/actions/setup-ccache/action.yml 与 docs/tips_and_troubleshooting/ci-ccache.md。【免费下载链接】connectedhomeipMatter (formerly Project CHIP) creates more connections between more objects, simplifying development for manufacturers and increasing compatibility for consumers, guided by the Connectivity Standards Alliance.项目地址: https://gitcode.com/GitHub_Trending/co/connectedhomeip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价