fix: let a project file ask whether it is the top-level project
Crafter.LintRules declares a test that links crafter-build, fetched with GitProject. crafter-build's own project.cpp loads Crafter.LintRules as a `#pragma crafter dependency`, so the chain was: crafter-build loads LintRules, LintRules' test wiring loads crafter-build's project.cpp from the external cache, which loads LintRules again, and the cycle guard threw. Every command that loads project.cpp in this repository has failed since that test was added, including the last CI run on master. A project file had no way to tell whether it was the one the user pointed crafter-build at or a dependency being loaded for somebody else, so it could not skip wiring that only its own build needs. IsTopLevelProject() answers that from the loading-frame stack ProjectDependency() already reads: one frame is the top-level project file, a second is only ever pushed for a dependency. Outside any project file it is true as well, which is what a test harness constructing Configurations expects. The ProjectDependency test records the answer from both the app and the greeter project files and checks each. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
c3d97be59e
commit
be88a194f4
5 changed files with 24 additions and 0 deletions
|
|
@ -92,11 +92,14 @@ int main(int argc, char** argv) {
|
|||
const fs::path appSo = scratch / "app" / "build" / "project.so";
|
||||
std::array<std::string_view, 0> noArgs = {};
|
||||
|
||||
Check(IsTopLevelProject(), "outside any project file counts as top level");
|
||||
|
||||
// The dependency is fetched, built and linked before project.cpp runs,
|
||||
// and ProjectDependency() hands it back by either name.
|
||||
try {
|
||||
Configuration cfg = LoadProject(app, noArgs);
|
||||
Check(cfg.name == "hello from greeter", std::format("project.cpp imported and called the dependency's module (got '{}')", cfg.name));
|
||||
Check(std::ranges::contains(cfg.compileFlags, "-DTOP_LEVEL=1"), "the project LoadProject was pointed at sees itself as top level");
|
||||
Check(cfg.dependencies.size() == 2, "ProjectDependency resolved by module name and by configuration name");
|
||||
if (cfg.dependencies.size() == 2) {
|
||||
Check(cfg.dependencies[0] == cfg.dependencies[1], "both names resolve to the same dependency");
|
||||
|
|
@ -105,6 +108,7 @@ int main(int argc, char** argv) {
|
|||
Check(dep.target == HostTarget(), "the dependency was built for the host triple LoadProject uses");
|
||||
Check(dep.march == "native", "the environment's march was overridden for host tooling");
|
||||
Check(std::ranges::contains(dep.compileFlags, "-fPIC"), "the dependency archive was built position-independent");
|
||||
Check(std::ranges::contains(dep.compileFlags, "-DTOP_LEVEL=0"), "a dependency's project file does not see itself as top level");
|
||||
Check(fs::exists(ExpectedOutput(dep)), "the dependency archive exists");
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue