test runner, cross-target runners, lib/exe split

- subprocess-isolated test runner (replaces V1 dlopen-RunTest);
  Pass/Fail/Crash/Timeout/Skipped outcomes via :Test partition
- TestRunner abstraction with command templates: Local, Ssh,
  SshWin (cmd.exe-shell), QemuUser, FromEnv; probe-based skip
  when runner unreachable
- transitive PCM-path propagation in Build(); resolveImport
  walks deps recursively; depResults cache keyed by PcmDir()
  so per-target builds don't collide
- cfg.sysroot threaded through BuildStdPcm + base compile/link
  command (enables aarch64 cross via Arch Linux ARM rootfs)
- lib + exe split: project.cpp defines crafterBuildLib
  (LibraryStatic) + crafterBuildExe (Executable depending on
  it); build.sh produces lib/libcrafter-build.a alongside
  bin/crafter-build for downstream static-link consumers
- Windows DLL+launcher: CRAFTER_API macro, /EXPORT flag for
  project.dll's CrafterBuildProject; Crafter::Run as the real
  entry point with main.cpp as a thin wrapper
- 18 tests: HelloWorld/WithModule/Defines/CrossProjectModule/
  Diamond × (Linux + sshwin:winvm), plus Incremental,
  BuildError, Libraries, RunnerClassification, QemuUser,
  SshRunner, WindowsViaSsh, CrossArchAarch64
- single ./bin/crafter-build test runs everything; Windows
  variants skip gracefully if winvm SSH alias unreachable

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-04-27 22:32:19 +02:00
commit cdfdb976c8
60 changed files with 2029 additions and 104 deletions

6
tests/fixtures/diamond/B/B.cppm vendored Normal file
View file

@ -0,0 +1,6 @@
export module B;
import X;
export int BValue() {
return XValue() * 2;
}

6
tests/fixtures/diamond/C/C.cppm vendored Normal file
View file

@ -0,0 +1,6 @@
export module C;
import X;
export int CValue() {
return XValue() * 3;
}

5
tests/fixtures/diamond/X/X.cppm vendored Normal file
View file

@ -0,0 +1,5 @@
export module X;
export int XValue() {
return 7;
}

9
tests/fixtures/diamond/main.cpp vendored Normal file
View file

@ -0,0 +1,9 @@
import std;
import B;
import C;
int main() {
if (BValue() != 14) return 1; // X(7) * 2
if (CValue() != 21) return 1; // X(7) * 3
return 0;
}