diff --git a/interfaces/Crafter.Build-Clang.cppm b/interfaces/Crafter.Build-Clang.cppm index 1149661..8a306be 100644 --- a/interfaces/Crafter.Build-Clang.cppm +++ b/interfaces/Crafter.Build-Clang.cppm @@ -7,6 +7,7 @@ import :Shader; import :Interface; import :Implementation; import :External; +import :Toolchain; namespace fs = std::filesystem; export namespace Crafter { @@ -488,10 +489,21 @@ export namespace Crafter { void AddAstLintRule(std::string name, std::function check); // Suffix that uniquely identifies this Configuration's compile state. // target+march+mtune are spelled out for readability; the rest - // (type, debug, sysroot, defines, compileFlags) collapse into a short - // hash so two Configurations sharing a path but with different - // compile state can't clobber each other's outputs. - std::string VariantId() const { + // (type, debug, sysroot, defines, compileFlags, the toolchain) + // collapse into a short hash so two Configurations sharing a path but + // with different compile state can't clobber each other's outputs. + std::string VariantId() const { return VariantId(GetToolchain()); } + // The variant under an explicit toolchain; VariantId() is this for + // the running one. The compiler is compile state like any flag: a + // PCM can only be read by the clang release that wrote it, and + // staleness is decided by mtimes, which a compiler update does not + // touch. Before the toolchain was hashed, a project built with clang + // 22 kept its PCMs when crafter-build moved to clang 23, and the + // first edit afterwards failed with "module file ... uses an older + // format that is no longer supported" until the project was cleaned. + // Keyed here, an update starts an empty directory and rebuilds; the + // old one stays until `crafter-build clean`. + std::string VariantId(const Toolchain& toolchain) const { std::string compileKey; compileKey += std::to_string(static_cast(type)); compileKey += '|'; @@ -521,6 +533,8 @@ export namespace Crafter { compileKey += "|A:"; compileKey += a; } + compileKey += "|T:"; + compileKey += toolchain.Key(); std::size_t configHash = std::hash{}(compileKey); return std::format("{}-{}-{}-{}-{:08x}", name, target, march, mtune, configHash); }