feat: project.cpp declares its own dependencies with #pragma crafter dependency
A project.cpp could only import std and Crafter.Build, so anything shared
between build descriptions had to be a header every consumer copies. Now
#pragma crafter dependency "<source>" [branch "<b>" | commit "<sha>"] [project "<file>"]
names a sibling crafter-build project that project.cpp itself imports a
module from. LoadProject scans for the directive, resolves it through
GitProject (a URL) or LocalProject (a path relative to the project file),
forces the result into host-tooling mode (the host triple LoadProject's
own cache is keyed on, native march, no debug, -fPIC so the archive links
into a shared object), builds it, and puts its BMIs and archive on the
project.so command line. The dependency's own project.cpp goes through
the same loader, so its directives resolve recursively; a cycle between
project files is an error instead of unbounded recursion.
The dependency is built on every load, fresh or not: clang crashes rather
than erroring when it imports a BMI whose own imported PCM was rebuilt
underneath it, and the module depfile — which Module::Check already reads —
is what notices the host PCM cache was regenerated. Its artifact mtime is
an input to project.so's staleness check, so editing the dependency
recompiles project.cpp without touching it. The Linux link gains
-fuse-ld=lld because release archives hold ThinLTO bitcode.
ProjectDependency(name) hands the same Configuration* back from inside
CrafterBuildProject, by configuration name or exported module name, so a
test that links the module needn't spell the source twice. It reads a
thread_local frame stack that an RAII guard keeps for the whole of
LoadProject, which also provides the cycle check.
ExpectedOutput() is the link gate's artifact-path lambda hoisted into the
:Clang partition, so the staleness check and the -r runner share the one
rule. Windows branches are wired identically but unverified.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
802caac1c2
commit
b94139b67c
15 changed files with 618 additions and 45 deletions
|
|
@ -546,6 +546,13 @@ export namespace Crafter {
|
|||
// features, and suffixed with the wasm variant flags for the same reason.
|
||||
CRAFTER_API fs::path StdPcmDir(const Configuration& config);
|
||||
|
||||
// Where Build leaves this Configuration's linked artifact: the executable
|
||||
// (with the target's suffix), `lib<name>.a` / `<name>.lib`, or the shared
|
||||
// library / DLL. The one rule every "is the consumer older than its
|
||||
// dependency" check reads, so a staleness test and the link step can't
|
||||
// disagree about the file name.
|
||||
CRAFTER_API fs::path ExpectedOutput(const Configuration& config);
|
||||
|
||||
// The clang invocation every C++ translation unit in this Configuration is
|
||||
// compiled with, before anything that depends on work having happened
|
||||
// (dependency public flags, external dependency flags — Build appends
|
||||
|
|
|
|||
|
|
@ -33,6 +33,14 @@ namespace Crafter {
|
|||
export CRAFTER_API CommandResult RunCommandWithTimeout(std::string_view command, std::chrono::seconds timeout);
|
||||
std::string GetBaseCommand(const Configuration& config);
|
||||
export CRAFTER_API Configuration LoadProject(const fs::path& projectFile, std::span<const std::string_view> args);
|
||||
// A dependency the project file currently running its CrafterBuildProject
|
||||
// declared with `#pragma crafter dependency`, so it can also be wired
|
||||
// into the build graph (a test that links the same module, say) without
|
||||
// spelling the source twice. `name` is the dependency's Configuration
|
||||
// name or any module it exports — whatever the project file `import`s.
|
||||
// Throws when no such dependency was declared, or when called from
|
||||
// anywhere other than inside LoadProject.
|
||||
export CRAFTER_API Configuration* ProjectDependency(std::string_view name);
|
||||
// Resolves the directory holding distributed runtime assets (Crafter.Build
|
||||
// module sources, wasi-runtime/, etc). Honors CRAFTER_BUILD_HOME; otherwise
|
||||
// derives <prefix>/share/crafter-build from the running executable's path.
|
||||
|
|
|
|||
Loading…
Reference in a new issue