fix: keep host tooling out of the project cache the target uses

ForceHostTooling rewrites a `#pragma crafter dependency` and everything
it loads in place: host target, march native, release, -fPIC. Those are
entries of the project cache like any other, keyed by project file and
args alone. A project that loaded the same sibling as its tool, with
the same args, got the rewritten entry back. That happens whenever the
project gets no args, since host tooling gets none either: a consumer
built for x86-64-v2 then imported a sibling's BMI compiled with
-march=native, and clang refused it. Any arg on the command line split
the keys and hid it.

A thread-local count of pragma loads now marks the tool's load and
every load inside it, its project file's siblings included, and
GitProject and LocalProject put that mark in the key. The clone stays
shared; only the Configuration is separate, as for two arg lists. A
module-internal function rather than a spec field, because the
siblings of a tool are loaded by the tool's own project.cpp, which
cannot know it is host tooling.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-10-31 05:10:21 +01:00
commit e420c9f958
Signed by: jorijnvdgraaf
GPG key ID: 2937E59CDCC1BCFB
3 changed files with 52 additions and 19 deletions

View file

@ -360,11 +360,12 @@ Configuration* Crafter::GitProject(const GitProjectSpec& spec) {
// source revision (forwarded args don't change what gets cloned, just
// how the dep's project.cpp interprets them at runtime), while the
// in-memory Configuration is keyed by the full spec so each (args)
// permutation gets its own Configuration object.
// permutation gets its own Configuration object, and host tooling one
// apart from the target's even for the same args.
std::string srcKey = std::format("git|{}|{}|{}|{}", spec.source.url, spec.source.branch, spec.source.commit, spec.projectFile.string());
std::string srcHash = std::format("{:016x}", std::hash<std::string>{}(srcKey));
std::string fullKey = srcKey;
std::string fullKey = std::format("{}{}", LoadingHostTooling() ? "host|" : "", srcKey);
for (const std::string& a : spec.args) {
fullKey += '|';
fullKey += a;
@ -449,7 +450,7 @@ Configuration* Crafter::LocalProject(const LocalProjectSpec& spec) {
}
fs::path canonical = fs::canonical(projectPath);
std::string fullKey = std::format("local|{}", canonical.string());
std::string fullKey = std::format("{}local|{}", LoadingHostTooling() ? "host|" : "", canonical.string());
for (const std::string& a : spec.args) {
fullKey += '|';
fullKey += a;