fix(incremental): key build outputs on the compiler
A project built with one clang kept its outputs when crafter-build started using another. The output directory is named by VariantId(), which hashed every input that changes what is compiled except the compiler itself, and staleness is decided by mtimes, which a compiler update leaves alone. A PCM can only be read by the clang release that wrote it, so after the bundled LLVM moved from 22 to 23 the first build found nothing stale, and the first edit failed with "module file Greeter.pcm uses an older format that is no longer supported" until the project was cleaned by hand. A project with a `#pragma crafter dependency` did not get that far: its project file imports the dependency's PCM, so it failed to load, and for a git dependency that PCM lives in the cache, where `crafter-build clean` does not reach. The same happens natively when the distro updates clang. The toolchain's key now goes into the hash, as the host PCM cache was already keyed on it. An update starts an empty variant directory and rebuilds into it; the previous one stays until `clean`, as after any other change of variant, and two crafter-build versions can work in one checkout without disturbing each other. VariantId() gains an overload taking the toolchain so the dependence can be tested in-process, the way ResolveToolchain and SysrootStdModule take theirs. External cmake builds are not covered: their directory is fixed per clone and keyed on the compiler's path, not its release. Objects of two clang releases link together on the host, so nothing fails there, but they are not rebuilt either. Verified by replaying the update: three projects built with the 2.0.0 Flatpak, then built, edited and run with this one without cleaning, then built with 2.0.0 again. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
6e9eedfd21
commit
b5a366d060
1 changed files with 18 additions and 4 deletions
|
|
@ -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<void(LintContext&)> 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<std::int32_t>(type));
|
||||
compileKey += '|';
|
||||
|
|
@ -521,6 +533,8 @@ export namespace Crafter {
|
|||
compileKey += "|A:";
|
||||
compileKey += a;
|
||||
}
|
||||
compileKey += "|T:";
|
||||
compileKey += toolchain.Key();
|
||||
std::size_t configHash = std::hash<std::string>{}(compileKey);
|
||||
return std::format("{}-{}-{}-{}-{:08x}", name, target, march, mtune, configHash);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue