UE编译缓存命中异常:可能由于Unity Build导致Cache Key未更新

我最近在尝试使用 Unreal Build Tool 的 Artifact Cache 功能来加速本地编译,配置如下所示:

xml 复制编辑 <BuildConfiguration> ... <bArtifactRead>true</bArtifactRead><bArtifactWrite>true</bArtifactWrite><bLogArtifactCacheMisses>true</bLogArtifactCacheMisses><ArtifactDirectory>Saved/Artifacts</ArtifactDirectory> </BuildConfiguration>一开始编译缓存运行得很理想,所有模块都成功命中缓存。

但当我修改了某个项目中的 .cpp文件内容之后,我发现编译依然命中所有缓存,没有任何模块被重新编译。在进一步排查后,我怀疑问题出在 Unity Build(联合编译)机制 上。简单来说:

如果一个 .cpp文件被包含进 Unity Build 文件(自动生成的那类

,用于包含多个源码文件),而该 Unity 文件本身没有变化(比如文件内容或包含列表没变),那么它的 Hash 值不会更新,导致 Artifact Cache 依然命中原始缓存即使源文件内容已经改变。这就可能导致:

  • 修改代码却未触发重新编译,行为异常;
  • 缓存命中的是旧版本.obj文件,构建结果不准确;
  • 缓存 Key 失效机制依赖 Unity 文件本身的变化,而不是源.cpp的直接变化。

我的疑问是:

  • 这是否是 Artifact Cache 当前在 Unity Build 下的已知限制?
  • 是否有推荐的解决方案?例如在开发调试阶段为部分模块禁用 Unity Build(如设置 bUseUnityBuild)?
  • 是否可以更细粒度地控制缓存失效机制,以便更准确反映代码变化?

如果有相关经验或建议,欢迎分享。谢谢!

重现步骤

我在使用 Unreal Build Tool 的 Artifact 缓存功能来加速项目编译,配置如下:

xml 复制编辑 <BuildConfiguration> ... <bArtifactRead>true</bArtifactRead><bArtifactWrite>true</bArtifactWrite><bLogArtifactCacheMisses>true</bLogArtifactCacheMisses><ArtifactDirectory>Saved/Artifacts</ArtifactDirectory> </BuildConfiguration>编译 LyraStarterGame 项目后,所有模块成功生成并写入缓存;紧接着再次编译,所有编译项也都正确命中缓存,表现正常。[Image Removed]接下来,我测试缓存失效机制:

  1. 找到类似Module.LyraGame.2.cpp 的文件(这是 UE 默认启用联合编译生成的 Unity 文件)。
  2. 修改该 Unity 文件中 include的某个源cpp文件,确保更改内容足够复杂,理论上应触发重新编译。
  3. 重新执行编译,结果发现:缓存仍然全部命中,没有触发重新编译

这与预期不符。按理说,Module.LyraGame.2.cpp的缓存应该因为其包含的 .cpp

文件发生了变化而失效。

初步分析

我怀疑问题出在 Unity Build 机制 上:

UBT 在计算 Unity 文件(如 Module.LyraGame.2.cpp)的缓存 Key 时,仅考虑了该文件本身的哈希,而未递归检查它所包含的原始.cpp文件内容是否发生了变化。补充测试

关闭联合编译

添加 bUseUnity = false

后再做相同修改,缓存失效行为恢复正常,修改能正确触发编译。但首次编译时间显著增加,编译粒度变小,整体构建速度变慢。

我的疑问:

  • 当前版本的 Artifact Cache 是否确实不支持 Unity Build 场景下的缓存精细变更检测?
  • 是否存在可以兼顾编译速度与缓存准确性的方案?例如部分模块关闭 Unity Build,或引入增量缓存 Key 的机制?
  • 有没有推荐的构建配置或实践来避免这一问题?

您好,unitybuild在收集源码的时候,会将修改过的文件移除出 unitybuild,加入adaptive列表,

编译的时候会出现 [Adaptive Build] Excluded from XXXModule unity file: XXX.cpp 的字样

如果您那边修改后并没有移出unitybuild,是否没有用Perforce或者git的代码管理工具?

是的 没有用版本管理工具 只是测试了一下

那应该就是这个问题了,如果有用git或Perforce管理就不会有这个问题