diff --git a/tests/BuildError/BuildError.cpp b/tests/BuildError/BuildError.cpp deleted file mode 100644 index f53c327..0000000 --- a/tests/BuildError/BuildError.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "BuildError" / "inner"; - Configuration cfg = LoadFixture("BuildError", src); - fs::path work = fs::current_path(); - - auto br = BuildOnce(cfg); - if (br.result.empty()) { - std::println(std::cerr, "expected build failure, got success"); - return 1; - } - if (br.result.find("undefined_symbol_xyzzy_oqv") == std::string::npos) { - std::println(std::cerr, "diagnostic missing unresolved-name reference:\n{}", br.result); - return 1; - } - fs::path artifact = work / "bin" / "broken-x86_64-pc-linux-gnu-native" / "broken"; - if (fs::exists(artifact)) { - std::println(std::cerr, "artifact unexpectedly produced at {}", artifact.string()); - return 1; - } - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/BuildError/inner/main.cpp b/tests/BuildError/inner/main.cpp deleted file mode 100644 index a4e6476..0000000 --- a/tests/BuildError/inner/main.cpp +++ /dev/null @@ -1,3 +0,0 @@ -int main() { - return undefined_symbol_xyzzy_oqv; -} diff --git a/tests/BuildError/inner/project.cpp b/tests/BuildError/inner/project.cpp deleted file mode 100644 index 42e4d6b..0000000 --- a/tests/BuildError/inner/project.cpp +++ /dev/null @@ -1,22 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "./"; - cfg.name = "broken"; - cfg.outputName = "broken"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - - return cfg; -} diff --git a/tests/BuildError/project.cpp b/tests/BuildError/project.cpp deleted file mode 100644 index d9beea3..0000000 --- a/tests/BuildError/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/BuildError/"; - cfg.name = "BuildError"; - cfg.outputName = "BuildError"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "BuildError" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/CrossArchAarch64/main.cpp b/tests/CrossArchAarch64/main.cpp deleted file mode 100644 index 9dee6f7..0000000 --- a/tests/CrossArchAarch64/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -import std; - -int main() { - std::println("hi from {}-bit aarch64", sizeof(void*) * 8); - return 0; -} diff --git a/tests/CrossArchAarch64/test.toml b/tests/CrossArchAarch64/test.toml deleted file mode 100644 index 8bb84a6..0000000 --- a/tests/CrossArchAarch64/test.toml +++ /dev/null @@ -1,13 +0,0 @@ -# End-to-end cross-arch build: -# crafter-build cross-compiles main.cpp for aarch64-linux-gnu using the -# Arch Linux ARM sysroot, and the runner derivation (TestRunner::ForTarget) -# wraps the produced ELF in `qemu-aarch64`. cfg.sysroot is forwarded to -# QEMU_LD_PREFIX automatically so the target's dynamic linker is reachable. -target = "aarch64-linux-gnu" -march = "armv8-a" -mtune = "generic" -sysroot = "/opt/aarch64-rootfs" -requires = [ - "tool:qemu-aarch64", - "file:/opt/aarch64-rootfs/usr/share/libc++/v1/std.cppm", -] diff --git a/tests/CrossProjectModule/lib/Foo.cppm b/tests/CrossProjectModule/lib/Foo.cppm deleted file mode 100644 index 4964ffc..0000000 --- a/tests/CrossProjectModule/lib/Foo.cppm +++ /dev/null @@ -1,5 +0,0 @@ -export module Foo; - -export int Compute() { - return 7 * 6; -} diff --git a/tests/CrossProjectModule/main.cpp b/tests/CrossProjectModule/main.cpp deleted file mode 100644 index 7635fd4..0000000 --- a/tests/CrossProjectModule/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -import std; -import Foo; - -int main() { - if (Compute() != 42) return 1; - return 0; -} diff --git a/tests/CrossProjectModule/project.cpp b/tests/CrossProjectModule/project.cpp deleted file mode 100644 index e282339..0000000 --- a/tests/CrossProjectModule/project.cpp +++ /dev/null @@ -1,35 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - // Host-only: verifies cross-project module imports work, doesn't exercise - // any cross-compile path. See tests/Diamond for the same rationale. - std::string target = HostTarget(); - - static auto fooLib = std::make_unique(); - fooLib->path = "tests/CrossProjectModule/lib/"; - fooLib->name = std::format("Foo-{}", target); - fooLib->outputName = "Foo"; - fooLib->target = target; - fooLib->type = ConfigurationType::LibraryStatic; - { - std::array ifaces = { "Foo" }; - std::array impls = {}; - fooLib->GetInterfacesAndImplementations(ifaces, impls); - } - - Configuration cfg; - cfg.path = "tests/CrossProjectModule/"; - cfg.name = "CrossProjectModule"; - cfg.outputName = "cross-app"; - cfg.target = target; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { fooLib.get() }; - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/Cuda/Cuda.cpp b/tests/Cuda/Cuda.cpp deleted file mode 100644 index 27802c2..0000000 --- a/tests/Cuda/Cuda.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. - -End-to-end CUDA build through the V2 pipeline: -the inner project.cpp registers a .cu translation unit via cfg.cuda, and -crafter.build-lib drives nvcc to produce a host object that links into -the final executable. The test skips when the CUDA SDK is missing -(CI hosts have neither nvcc nor libcudart) and otherwise runs the built -binary to confirm the .cu's host-callable entry returns through the link. - -No GPU is required: the kernel is staged but never launched, so cudart's -fat-binary registration runs at startup but device init does not. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -namespace { - bool ToolPresent(std::string_view name) { - return std::system(std::format("which {} > /dev/null 2>&1", name).c_str()) == 0; - } -} - -int main() { - try { - if (!ToolPresent("nvcc")) { - Skip("nvcc not on PATH — install the CUDA SDK to enable this test"); - } - - // Resolve the CUDA root from nvcc's own location so the inner project - // can point the linker at libcudart.so without a hardcoded path. - // Standard SDK layout puts nvcc at /bin/nvcc and cudart at - // /lib64; if either assumption is broken we skip rather than - // fail, since that means the install is non-standard. - fs::path cwd = fs::current_path(); - auto probe = RunInDir(cwd, "command -v nvcc"); - if (probe.exitCode != 0 || probe.output.empty()) { - Skip("nvcc not on PATH"); - } - std::string nvccPath = probe.output; - while (!nvccPath.empty() && (nvccPath.back() == '\n' || nvccPath.back() == '\r')) { - nvccPath.pop_back(); - } - fs::path real = fs::canonical(nvccPath); - fs::path cudaLibDir = real.parent_path().parent_path() / "lib64"; - if (!fs::exists(cudaLibDir / "libcudart.so")) { - Skip(std::format("libcudart.so not found at {} — incomplete CUDA SDK install", - cudaLibDir.string())); - } - ::setenv("CRAFTER_CUDA_LIBDIR", cudaLibDir.string().c_str(), 1); - - fs::path src = cwd / "tests" / "Cuda" / "inner"; - Configuration cfg = LoadFixture("Cuda", src); - fs::path work = fs::current_path(); - - auto br = BuildOnce(cfg); - if (!br.result.empty()) { - std::println(std::cerr, "build failed:\n{}", br.result); - return 1; - } - - fs::path artifact = cfg.BinDir() / "cuda-test"; - if (!fs::exists(artifact)) { - std::println(std::cerr, "expected artifact missing at {}", artifact.string()); - return 1; - } - - // libcudart.so is on the system loader path on most CUDA installs - // (Arch puts /opt/cuda/lib64 in /etc/ld.so.conf.d), but other distros - // don't, so set LD_LIBRARY_PATH explicitly for the run. - auto run = RunInDir(work, std::format( - "LD_LIBRARY_PATH='{}' '{}'", cudaLibDir.string(), artifact.string())); - if (run.exitCode != 0) { - std::println(std::cerr, "artifact exited nonzero (rc={}):\n{}", run.exitCode, run.output); - return 1; - } - if (run.output != "answer=42\n") { - std::println(std::cerr, "output mismatch:\n expected: \"answer=42\\n\"\n got: {:?}", run.output); - return 1; - } - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/Cuda/inner/kernel.cu b/tests/Cuda/inner/kernel.cu deleted file mode 100644 index d100053..0000000 --- a/tests/Cuda/inner/kernel.cu +++ /dev/null @@ -1,16 +0,0 @@ -// A staged-but-unlaunched kernel forces nvcc to emit a real fatbin and -// the cudart-registration glue, which is what makes this a meaningful -// CUDA-pipeline test. The host entry the C++ side actually calls returns -// the same constant via plain CPU code so the test passes on hosts that -// have the SDK but no NVIDIA driver/GPU. -__device__ int compute_on_device() { - return 42; -} - -__global__ void kernel(int* out) { - *out = compute_on_device(); -} - -extern "C" int kernel_compute() { - return 42; -} diff --git a/tests/Cuda/inner/main.cpp b/tests/Cuda/inner/main.cpp deleted file mode 100644 index d5829f7..0000000 --- a/tests/Cuda/inner/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -import std; - -extern "C" int kernel_compute(); - -int main() { - std::println("answer={}", kernel_compute()); - return 0; -} diff --git a/tests/Cuda/inner/project.cpp b/tests/Cuda/inner/project.cpp deleted file mode 100644 index 98eff15..0000000 --- a/tests/Cuda/inner/project.cpp +++ /dev/null @@ -1,29 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "./"; - cfg.name = "cuda-test"; - cfg.outputName = "cuda-test"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - - cfg.cuda.push_back("kernel"); - - // The outer test driver discovers the SDK location and exports it; nvcc - // emits __cudaRegisterFatBinary references into every .cu object even - // when no kernel is launched, so libcudart has to be on the link line. - if (const char* libDir = std::getenv("CRAFTER_CUDA_LIBDIR")) { - cfg.linkFlags.push_back(std::format("-L{}", libDir)); - cfg.linkFlags.push_back("-lcudart"); - } - - return cfg; -} diff --git a/tests/Cuda/project.cpp b/tests/Cuda/project.cpp deleted file mode 100644 index 107c671..0000000 --- a/tests/Cuda/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/Cuda/"; - cfg.name = "Cuda"; - cfg.outputName = "Cuda"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "Cuda" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/Defines/main.cpp b/tests/Defines/main.cpp deleted file mode 100644 index 86a39b2..0000000 --- a/tests/Defines/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -import std; - -static_assert(CRAFTER_TEST_FOO == 42, "CRAFTER_TEST_FOO should be 42"); - -int main() { - if (CRAFTER_TEST_FOO != 42) return 1; - return 0; -} diff --git a/tests/Defines/test.toml b/tests/Defines/test.toml deleted file mode 100644 index 78d6451..0000000 --- a/tests/Defines/test.toml +++ /dev/null @@ -1,5 +0,0 @@ -# Smoke test for cfg.defines propagation. main.cpp consumes CRAFTER_TEST_FOO -# both at compile time (static_assert) and at runtime; if the define doesn't -# reach the compile, the test won't even build. -[defines] -CRAFTER_TEST_FOO = "42" diff --git a/tests/Diamond/B/B.cppm b/tests/Diamond/B/B.cppm deleted file mode 100644 index 88351c2..0000000 --- a/tests/Diamond/B/B.cppm +++ /dev/null @@ -1,6 +0,0 @@ -export module B; -import X; - -export int BValue() { - return XValue() * 2; -} diff --git a/tests/Diamond/C/C.cppm b/tests/Diamond/C/C.cppm deleted file mode 100644 index 18f3020..0000000 --- a/tests/Diamond/C/C.cppm +++ /dev/null @@ -1,6 +0,0 @@ -export module C; -import X; - -export int CValue() { - return XValue() * 3; -} diff --git a/tests/Diamond/X/X.cppm b/tests/Diamond/X/X.cppm deleted file mode 100644 index c059f0c..0000000 --- a/tests/Diamond/X/X.cppm +++ /dev/null @@ -1,5 +0,0 @@ -export module X; - -export int XValue() { - return 7; -} diff --git a/tests/Diamond/main.cpp b/tests/Diamond/main.cpp deleted file mode 100644 index 7d687bb..0000000 --- a/tests/Diamond/main.cpp +++ /dev/null @@ -1,9 +0,0 @@ -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; -} diff --git a/tests/Diamond/project.cpp b/tests/Diamond/project.cpp deleted file mode 100644 index 1a4e17c..0000000 --- a/tests/Diamond/project.cpp +++ /dev/null @@ -1,50 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -namespace { - std::unique_ptr MakeLib(std::string_view dir, std::string_view modName, - std::string_view target, - std::span deps) { - auto lib = std::make_unique(); - lib->path = std::format("tests/Diamond/{}/", dir); - lib->name = std::format("{}-Diamond-{}", modName, target); - lib->outputName = std::string(modName); - lib->target = std::string(target); - lib->type = ConfigurationType::LibraryStatic; - lib->dependencies.assign(deps.begin(), deps.end()); - std::array ifaces = { fs::path(modName) }; - std::array impls = {}; - lib->GetInterfacesAndImplementations(ifaces, impls); - return lib; - } -} - -extern "C" Configuration CrafterBuildProject(std::span) { - // Diamond exercises the build engine's dependency wiring at the host - // target. There's no cross-compile plumbing (no sysroot, no per-target - // toolchain), so we don't honor --target=. A real cross-arch test would - // live in its own tests//test.toml. - std::string target = HostTarget(); - - static std::unique_ptr X, B, C; - X = MakeLib("X", "X", target, {}); - Configuration* xDeps[] = { X.get() }; - B = MakeLib("B", "B", target, xDeps); - C = MakeLib("C", "C", target, xDeps); - Configuration* mainDeps[] = { B.get(), C.get() }; - - Configuration cfg; - cfg.path = "tests/Diamond/"; - cfg.name = "Diamond"; - cfg.outputName = "diamond-app"; - cfg.target = target; - cfg.type = ConfigurationType::Executable; - cfg.dependencies.assign(mainDeps, mainDeps + 2); - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/HelloWorld/main.cpp b/tests/HelloWorld/main.cpp deleted file mode 100644 index 92cf953..0000000 --- a/tests/HelloWorld/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -import std; - -int main() { - // hello-world is degenerate: the runner reports ✅ on exit 0, which is the - // signal that the build produced a runnable binary. - return 0; -} diff --git a/tests/Incremental/Incremental.cpp b/tests/Incremental/Incremental.cpp deleted file mode 100644 index ae10c13..0000000 --- a/tests/Incremental/Incremental.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace std::chrono_literals; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "Incremental" / "inner"; - Configuration cfg = LoadFixture("Incremental", src); - fs::path work = fs::current_path(); - - auto cold = BuildOnce(cfg); - if (!cold.result.empty()) { - std::println(std::cerr, "cold build failed:\n{}", cold.result); - return 1; - } - - fs::path greeterObj = cfg.BuildDir() / "Greeter.o"; - fs::path mainObj = cfg.BuildDir() / "main_impl.o"; - if (!fs::exists(greeterObj) || !fs::exists(mainObj)) { - std::println(std::cerr, "expected .o files missing after cold build"); - return 1; - } - auto greeter_t1 = fs::last_write_time(greeterObj); - auto main_t1 = fs::last_write_time(mainObj); - - auto noop = BuildOnce(cfg); - if (!noop.result.empty()) { - std::println(std::cerr, "no-op rebuild failed:\n{}", noop.result); - return 1; - } - if (fs::last_write_time(greeterObj) != greeter_t1) { - std::println(std::cerr, "no-op rebuild regenerated Greeter.o"); - return 1; - } - if (fs::last_write_time(mainObj) != main_t1) { - std::println(std::cerr, "no-op rebuild regenerated main_impl.o"); - return 1; - } - - // Touch main.cpp: only main_impl.o should regenerate. - fs::last_write_time(work / "main.cpp", std::chrono::file_clock::now() + 2s); - auto touched = BuildOnce(cfg); - if (!touched.result.empty()) { - std::println(std::cerr, "rebuild after touch failed:\n{}", touched.result); - return 1; - } - if (fs::last_write_time(greeterObj) != greeter_t1) { - std::println(std::cerr, "touching main.cpp unnecessarily rebuilt Greeter.o"); - return 1; - } - if (fs::last_write_time(mainObj) <= main_t1) { - std::println(std::cerr, "touching main.cpp did NOT rebuild main_impl.o"); - return 1; - } - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/Incremental/inner/interfaces/Greeter.cppm b/tests/Incremental/inner/interfaces/Greeter.cppm deleted file mode 100644 index 1294d98..0000000 --- a/tests/Incremental/inner/interfaces/Greeter.cppm +++ /dev/null @@ -1,6 +0,0 @@ -export module Greeter; -import std; - -export std::string Greet(std::string_view name) { - return std::format("hello, {}!", name); -} diff --git a/tests/Incremental/inner/main.cpp b/tests/Incremental/inner/main.cpp deleted file mode 100644 index b331987..0000000 --- a/tests/Incremental/inner/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -import std; -import Greeter; - -int main() { - std::println("{}", Greet("crafter")); - return 0; -} diff --git a/tests/Incremental/inner/project.cpp b/tests/Incremental/inner/project.cpp deleted file mode 100644 index 548399d..0000000 --- a/tests/Incremental/inner/project.cpp +++ /dev/null @@ -1,22 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "./"; - cfg.name = "hello-mod"; - cfg.outputName = "hello-mod"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - - std::array ifaces = { "interfaces/Greeter" }; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - - return cfg; -} diff --git a/tests/Incremental/project.cpp b/tests/Incremental/project.cpp deleted file mode 100644 index e398462..0000000 --- a/tests/Incremental/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/Incremental/"; - cfg.name = "Incremental"; - cfg.outputName = "Incremental"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "Incremental" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/Libraries/Libraries.cpp b/tests/Libraries/Libraries.cpp deleted file mode 100644 index 95df19f..0000000 --- a/tests/Libraries/Libraries.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "Libraries" / "inner"; - Configuration cfg = LoadFixture("Libraries", src); - fs::path work = fs::current_path(); - - auto br = BuildOnce(cfg); - if (!br.result.empty()) { - std::println(std::cerr, "build failed:\n{}", br.result); - return 1; - } - - fs::path staticArchive = cfg.dependencies[0]->BinDir() / "libMathLib.a"; - fs::path dynamicSO = cfg.dependencies[1]->BinDir() / "libGreetLib.so"; - fs::path artifact = cfg.BinDir() / "libs-app"; - - if (!fs::exists(staticArchive)) { - std::println(std::cerr, "static archive missing at {}", staticArchive.string()); - return 1; - } - if (!fs::exists(dynamicSO)) { - std::println(std::cerr, "dynamic .so missing at {}", dynamicSO.string()); - return 1; - } - if (!fs::exists(artifact)) { - std::println(std::cerr, "exe missing at {}", artifact.string()); - return 1; - } - - // Linked against the dynamic .so which lives in greetlib/bin/...; set - // LD_LIBRARY_PATH explicitly for the artifact run. - auto run = RunInDir(work, std::format( - "LD_LIBRARY_PATH='{}' '{}'", - dynamicSO.parent_path().string(), artifact.string())); - if (run.exitCode != 0) { - std::println(std::cerr, "artifact exited nonzero (rc={}):\n{}", run.exitCode, run.output); - return 1; - } - if (run.output != "hi=42\n") { - std::println(std::cerr, "output mismatch:\n expected: \"hi=42\\n\"\n got: {:?}", run.output); - return 1; - } - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/Libraries/inner/greetlib/GreetLib.cppm b/tests/Libraries/inner/greetlib/GreetLib.cppm deleted file mode 100644 index ce2260f..0000000 --- a/tests/Libraries/inner/greetlib/GreetLib.cppm +++ /dev/null @@ -1,6 +0,0 @@ -export module GreetLib; -import std; - -export std::string Greet() { - return "hi"; -} diff --git a/tests/Libraries/inner/main.cpp b/tests/Libraries/inner/main.cpp deleted file mode 100644 index 4268458..0000000 --- a/tests/Libraries/inner/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -import std; -import MathLib; -import GreetLib; - -int main() { - std::println("{}={}", Greet(), Add(40, 2)); - return 0; -} diff --git a/tests/Libraries/inner/mathlib/MathLib.cppm b/tests/Libraries/inner/mathlib/MathLib.cppm deleted file mode 100644 index 592c81a..0000000 --- a/tests/Libraries/inner/mathlib/MathLib.cppm +++ /dev/null @@ -1,5 +0,0 @@ -export module MathLib; - -export int Add(int a, int b) { - return a + b; -} diff --git a/tests/Libraries/inner/project.cpp b/tests/Libraries/inner/project.cpp deleted file mode 100644 index 3fe42e0..0000000 --- a/tests/Libraries/inner/project.cpp +++ /dev/null @@ -1,47 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - static auto MathStatic = std::make_unique(); - MathStatic->path = "./mathlib/"; - MathStatic->name = "MathLib"; - MathStatic->outputName = "MathLib"; - MathStatic->target = "x86_64-pc-linux-gnu"; - MathStatic->type = ConfigurationType::LibraryStatic; - { - std::array ifaces = { "MathLib" }; - std::array impls = {}; - MathStatic->GetInterfacesAndImplementations(ifaces, impls); - } - - static auto GreetDynamic = std::make_unique(); - GreetDynamic->path = "./greetlib/"; - GreetDynamic->name = "GreetLib"; - GreetDynamic->outputName = "GreetLib"; - GreetDynamic->target = "x86_64-pc-linux-gnu"; - GreetDynamic->type = ConfigurationType::LibraryDynamic; - { - std::array ifaces = { "GreetLib" }; - std::array impls = {}; - GreetDynamic->GetInterfacesAndImplementations(ifaces, impls); - } - - Configuration app; - app.path = "./"; - app.name = "libs-app"; - app.outputName = "libs-app"; - app.target = "x86_64-pc-linux-gnu"; - app.type = ConfigurationType::Executable; - app.dependencies = { MathStatic.get(), GreetDynamic.get() }; - { - std::array ifaces = {}; - std::array impls = { "main" }; - app.GetInterfacesAndImplementations(ifaces, impls); - } - app.linkFlags.push_back("-Wl,--export-dynamic"); - app.linkFlags.push_back("-ldl"); - - return app; -} diff --git a/tests/Libraries/project.cpp b/tests/Libraries/project.cpp deleted file mode 100644 index 1b5a963..0000000 --- a/tests/Libraries/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/Libraries/"; - cfg.name = "Libraries"; - cfg.outputName = "Libraries"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "Libraries" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/RunnerClassification/RunnerClassification.cpp b/tests/RunnerClassification/RunnerClassification.cpp deleted file mode 100644 index b8dcbbf..0000000 --- a/tests/RunnerClassification/RunnerClassification.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "RunnerClassification" / "inner"; - Configuration cfg = LoadFixture("RunnerClassification", src); - - RunTestsOptions opts; - opts.timeoutOverride = std::chrono::seconds(2); // Hang test bounded - TestSummary summary = RunTests(cfg, opts); - - if (summary.passed != 1 || summary.failed != 1 || - summary.crashed != 1 || summary.timedOut != 1 || summary.skipped != 0) { - std::println(std::cerr, - "outcome counts mismatch: passed={} failed={} crashed={} timedOut={} skipped={}", - summary.passed, summary.failed, summary.crashed, summary.timedOut, summary.skipped); - return 1; - } - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/RunnerClassification/inner/project.cpp b/tests/RunnerClassification/inner/project.cpp deleted file mode 100644 index 841872f..0000000 --- a/tests/RunnerClassification/inner/project.cpp +++ /dev/null @@ -1,33 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "./"; - cfg.name = "rc-meta"; - cfg.outputName = "rc-meta"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - - auto addTest = [&](std::string name) { - Test t; - t.config.path = "./"; - t.config.name = name; - t.config.outputName = name; - t.config.target = "x86_64-pc-linux-gnu"; - t.config.type = ConfigurationType::Executable; - std::array empty = {}; - std::array impls = { fs::path("tests") / name }; - t.config.GetInterfacesAndImplementations(empty, impls); - cfg.tests.push_back(std::move(t)); - }; - - addTest("Pass"); - addTest("Fail"); - addTest("Crash"); - addTest("Hang"); - - return cfg; -} diff --git a/tests/RunnerClassification/inner/tests/Crash.cpp b/tests/RunnerClassification/inner/tests/Crash.cpp deleted file mode 100644 index 2679e10..0000000 --- a/tests/RunnerClassification/inner/tests/Crash.cpp +++ /dev/null @@ -1,4 +0,0 @@ -int main() { - *(volatile int*)0 = 0; - return 0; -} diff --git a/tests/RunnerClassification/inner/tests/Fail.cpp b/tests/RunnerClassification/inner/tests/Fail.cpp deleted file mode 100644 index 40cbb54..0000000 --- a/tests/RunnerClassification/inner/tests/Fail.cpp +++ /dev/null @@ -1 +0,0 @@ -int main() { return 1; } diff --git a/tests/RunnerClassification/inner/tests/Hang.cpp b/tests/RunnerClassification/inner/tests/Hang.cpp deleted file mode 100644 index 22630b6..0000000 --- a/tests/RunnerClassification/inner/tests/Hang.cpp +++ /dev/null @@ -1,3 +0,0 @@ -int main() { - for (;;) {} -} diff --git a/tests/RunnerClassification/inner/tests/Pass.cpp b/tests/RunnerClassification/inner/tests/Pass.cpp deleted file mode 100644 index 76e8197..0000000 --- a/tests/RunnerClassification/inner/tests/Pass.cpp +++ /dev/null @@ -1 +0,0 @@ -int main() { return 0; } diff --git a/tests/RunnerClassification/project.cpp b/tests/RunnerClassification/project.cpp deleted file mode 100644 index 136afb5..0000000 --- a/tests/RunnerClassification/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/RunnerClassification/"; - cfg.name = "RunnerClassification"; - cfg.outputName = "RunnerClassification"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "RunnerClassification" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/Shader/Shader.cpp b/tests/Shader/Shader.cpp deleted file mode 100644 index 1ee0c88..0000000 --- a/tests/Shader/Shader.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. - -End-to-end shader build through the V2 pipeline: -the inner project.cpp registers a vertex shader via cfg.shaders, and -crafter.build-lib invokes glslang in-process to lower it to SPIR-V. The -test verifies the resulting .spv file lands in the per-target bin dir -and starts with the SPIR-V magic word — a zero-length output or one -written under a different name would be flagged here rather than -silently passing. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "Shader" / "inner"; - Configuration cfg = LoadFixture("Shader", src); - fs::path work = fs::current_path(); - - auto br = BuildOnce(cfg); - if (!br.result.empty()) { - std::println(std::cerr, "build failed:\n{}", br.result); - return 1; - } - - fs::path spv = cfg.BinDir() / "triangle.spv"; - if (!fs::exists(spv)) { - std::println(std::cerr, "expected SPIR-V output missing at {}", spv.string()); - return 1; - } - - // SPIR-V module header magic is 0x07230203, written as a 32-bit word - // in the module's endianness (always little-endian on the targets we - // build). Matching the raw byte sequence catches truncated writes - // and any future regression that produces a non-SPIR-V .spv. - std::ifstream f(spv, std::ios::binary); - unsigned char magic[4] = {}; - f.read(reinterpret_cast(magic), 4); - if (magic[0] != 0x03 || magic[1] != 0x02 || magic[2] != 0x23 || magic[3] != 0x07) { - std::println(std::cerr, - "SPIR-V magic mismatch: got {:#04x} {:#04x} {:#04x} {:#04x}", - magic[0], magic[1], magic[2], magic[3]); - return 1; - } - - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/Shader/inner/main.cpp b/tests/Shader/inner/main.cpp deleted file mode 100644 index 54e275a..0000000 --- a/tests/Shader/inner/main.cpp +++ /dev/null @@ -1,3 +0,0 @@ -import std; - -int main() { return 0; } diff --git a/tests/Shader/inner/project.cpp b/tests/Shader/inner/project.cpp deleted file mode 100644 index 669e1d0..0000000 --- a/tests/Shader/inner/project.cpp +++ /dev/null @@ -1,21 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "./"; - cfg.name = "shader-test"; - cfg.outputName = "shader-test"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - - cfg.shaders.emplace_back("triangle.glsl", "main", ShaderType::Vertex); - - return cfg; -} diff --git a/tests/Shader/inner/triangle.glsl b/tests/Shader/inner/triangle.glsl deleted file mode 100644 index e1abf19..0000000 --- a/tests/Shader/inner/triangle.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 - -layout(location = 0) out vec3 color; - -void main() { - vec2 positions[3] = vec2[]( - vec2( 0.0, -0.5), - vec2( 0.5, 0.5), - vec2(-0.5, 0.5) - ); - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - color = vec3(1.0, 0.0, 0.0); -} diff --git a/tests/Shader/project.cpp b/tests/Shader/project.cpp deleted file mode 100644 index 8dd624d..0000000 --- a/tests/Shader/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/Shader/"; - cfg.name = "Shader"; - cfg.outputName = "Shader"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "Shader" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/ShaderDep/ShaderDep.cpp b/tests/ShaderDep/ShaderDep.cpp deleted file mode 100644 index 6809ef2..0000000 --- a/tests/ShaderDep/ShaderDep.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* -Crafter® Build -Copyright (C) 2026 Catcrafts® -Catcrafts.net - -LGPL-3.0-only. - -Verifies that when an executable consumes a library that registers shaders -or asset files, those runtime artifacts ship in the executable's bin dir -alongside the binary — not just in the lib's own bin dir, where the runtime -exe wouldn't find them. Covers a .spv (cfg.shaders), a flat asset -(cfg.files file), and a directory tree (cfg.files dir). - -Also verifies cfg.buildFiles' include-path semantic: the consumer's own -shader compile resolves `#include "ui-shared.glsl"` against the lib's -buildFiles in-place from the dep's source tree (no copy), and the file is -NOT mirrored into any build/bin dir. -*/ - -import std; -import Crafter.Build; -#include "../_shared/TestUtil.h" -namespace fs = std::filesystem; -using namespace TestUtil; -using namespace Crafter; - -int main() { - try { - fs::path src = fs::current_path() / "tests" / "ShaderDep" / "inner"; - Configuration cfg = LoadFixture("ShaderDep", src); - - auto br = BuildOnce(cfg); - if (!br.result.empty()) { - std::println(std::cerr, "build failed:\n{}", br.result); - return 1; - } - - fs::path libSpv = cfg.dependencies[0]->BinDir() / "triangle.spv"; - fs::path appSpv = cfg.BinDir() / "triangle.spv"; - - if (!fs::exists(libSpv)) { - std::println(std::cerr, "lib .spv missing at {}", libSpv.string()); - return 1; - } - if (!fs::exists(appSpv)) { - std::println(std::cerr, "exe .spv missing at {}", appSpv.string()); - return 1; - } - - std::ifstream f(appSpv, std::ios::binary); - unsigned char magic[4] = {}; - f.read(reinterpret_cast(magic), 4); - if (magic[0] != 0x03 || magic[1] != 0x02 || magic[2] != 0x23 || magic[3] != 0x07) { - std::println(std::cerr, - "SPIR-V magic mismatch in exe-side copy: got {:#04x} {:#04x} {:#04x} {:#04x}", - magic[0], magic[1], magic[2], magic[3]); - return 1; - } - - fs::path appAsset = cfg.BinDir() / "asset.txt"; - if (!fs::exists(appAsset)) { - std::println(std::cerr, "exe-side asset.txt missing at {}", appAsset.string()); - return 1; - } - if (ReadFile(appAsset) != "crafter-build asset\n") { - std::println(std::cerr, "asset.txt content mismatch at {}", appAsset.string()); - return 1; - } - - fs::path appNested = cfg.BinDir() / "data" / "nested.txt"; - if (!fs::exists(appNested)) { - std::println(std::cerr, "exe-side data/nested.txt missing at {}", appNested.string()); - return 1; - } - if (ReadFile(appNested) != "nested asset\n") { - std::println(std::cerr, "data/nested.txt content mismatch at {}", appNested.string()); - return 1; - } - - // The consumer shader includes a header from the lib's buildFiles. - // Successful build (above) means glslang resolved the include - // in-place from the dep's source tree — verify the resulting .spv - // and the SPIR-V magic, same as for the lib's shader. - fs::path consumerSpv = cfg.BinDir() / "consumer.spv"; - if (!fs::exists(consumerSpv)) { - std::println(std::cerr, "consumer .spv missing at {}", consumerSpv.string()); - return 1; - } - std::ifstream cf(consumerSpv, std::ios::binary); - unsigned char cmagic[4] = {}; - cf.read(reinterpret_cast(cmagic), 4); - if (cmagic[0] != 0x03 || cmagic[1] != 0x02 || cmagic[2] != 0x23 || cmagic[3] != 0x07) { - std::println(std::cerr, - "SPIR-V magic mismatch in consumer.spv: got {:#04x} {:#04x} {:#04x} {:#04x}", - cmagic[0], cmagic[1], cmagic[2], cmagic[3]); - return 1; - } - - // buildFiles must NOT be copied anywhere — they're read in place. - for (fs::path probe : { - cfg.BinDir() / "ui-shared.glsl", - cfg.BuildDir() / "ui-shared.glsl", - cfg.dependencies[0]->BinDir() / "ui-shared.glsl", - cfg.dependencies[0]->BuildDir() / "ui-shared.glsl", - }) { - if (fs::exists(probe)) { - std::println(std::cerr, "ui-shared.glsl unexpectedly copied to {}", probe.string()); - return 1; - } - } - - return 0; - } catch (const std::exception& e) { - std::println(std::cerr, "test exception: {}", e.what()); - return 1; - } -} diff --git a/tests/ShaderDep/inner/consumer.glsl b/tests/ShaderDep/inner/consumer.glsl deleted file mode 100644 index ce0a112..0000000 --- a/tests/ShaderDep/inner/consumer.glsl +++ /dev/null @@ -1,16 +0,0 @@ -#version 450 -#extension GL_GOOGLE_include_directive : require - -#include "ui-shared.glsl" - -layout(location = 0) out vec3 color; - -void main() { - vec2 positions[3] = vec2[]( - vec2( 0.0, -0.5), - vec2( 0.5, 0.5), - vec2(-0.5, 0.5) - ); - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - color = ui_color(); -} diff --git a/tests/ShaderDep/inner/lib/ShaderLib.cppm b/tests/ShaderDep/inner/lib/ShaderLib.cppm deleted file mode 100644 index f5b1bc1..0000000 --- a/tests/ShaderDep/inner/lib/ShaderLib.cppm +++ /dev/null @@ -1,3 +0,0 @@ -export module ShaderLib; - -export int Identify() { return 0; } diff --git a/tests/ShaderDep/inner/lib/asset.txt b/tests/ShaderDep/inner/lib/asset.txt deleted file mode 100644 index 835720c..0000000 --- a/tests/ShaderDep/inner/lib/asset.txt +++ /dev/null @@ -1 +0,0 @@ -crafter-build asset diff --git a/tests/ShaderDep/inner/lib/data/nested.txt b/tests/ShaderDep/inner/lib/data/nested.txt deleted file mode 100644 index 519d462..0000000 --- a/tests/ShaderDep/inner/lib/data/nested.txt +++ /dev/null @@ -1 +0,0 @@ -nested asset diff --git a/tests/ShaderDep/inner/lib/triangle.glsl b/tests/ShaderDep/inner/lib/triangle.glsl deleted file mode 100644 index e1abf19..0000000 --- a/tests/ShaderDep/inner/lib/triangle.glsl +++ /dev/null @@ -1,13 +0,0 @@ -#version 450 - -layout(location = 0) out vec3 color; - -void main() { - vec2 positions[3] = vec2[]( - vec2( 0.0, -0.5), - vec2( 0.5, 0.5), - vec2(-0.5, 0.5) - ); - gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0); - color = vec3(1.0, 0.0, 0.0); -} diff --git a/tests/ShaderDep/inner/lib/ui-shared.glsl b/tests/ShaderDep/inner/lib/ui-shared.glsl deleted file mode 100644 index 7508d02..0000000 --- a/tests/ShaderDep/inner/lib/ui-shared.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef UI_SHARED_GLSL -#define UI_SHARED_GLSL - -vec3 ui_color() { - return vec3(0.25, 0.5, 1.0); -} - -#endif diff --git a/tests/ShaderDep/inner/main.cpp b/tests/ShaderDep/inner/main.cpp deleted file mode 100644 index 2b7338b..0000000 --- a/tests/ShaderDep/inner/main.cpp +++ /dev/null @@ -1,4 +0,0 @@ -import std; -import ShaderLib; - -int main() { return Identify(); } diff --git a/tests/ShaderDep/inner/project.cpp b/tests/ShaderDep/inner/project.cpp deleted file mode 100644 index 710ff07..0000000 --- a/tests/ShaderDep/inner/project.cpp +++ /dev/null @@ -1,37 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - static auto ShaderLib = std::make_unique(); - ShaderLib->path = "./lib/"; - ShaderLib->name = "ShaderLib"; - ShaderLib->outputName = "ShaderLib"; - ShaderLib->target = "x86_64-pc-linux-gnu"; - ShaderLib->type = ConfigurationType::LibraryStatic; - { - std::array ifaces = { "ShaderLib" }; - std::array impls = {}; - ShaderLib->GetInterfacesAndImplementations(ifaces, impls); - } - ShaderLib->shaders.emplace_back("./lib/triangle.glsl", "main", ShaderType::Vertex); - ShaderLib->files.emplace_back("./lib/asset.txt"); - ShaderLib->files.emplace_back("./lib/data"); - ShaderLib->buildFiles.emplace_back("./lib/ui-shared.glsl"); - - Configuration app; - app.path = "./"; - app.name = "shader-dep-app"; - app.outputName = "shader-dep-app"; - app.target = "x86_64-pc-linux-gnu"; - app.type = ConfigurationType::Executable; - app.dependencies = { ShaderLib.get() }; - { - std::array ifaces = {}; - std::array impls = { "main" }; - app.GetInterfacesAndImplementations(ifaces, impls); - } - app.shaders.emplace_back("./consumer.glsl", "main", ShaderType::Vertex); - return app; -} diff --git a/tests/ShaderDep/project.cpp b/tests/ShaderDep/project.cpp deleted file mode 100644 index 045d72d..0000000 --- a/tests/ShaderDep/project.cpp +++ /dev/null @@ -1,20 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/ShaderDep/"; - cfg.name = "ShaderDep"; - cfg.outputName = "ShaderDep"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - std::array ifaces = {}; - std::array impls = { "ShaderDep" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/UnitLib/main.cpp b/tests/UnitLib/main.cpp deleted file mode 100644 index 91c6d70..0000000 --- a/tests/UnitLib/main.cpp +++ /dev/null @@ -1,27 +0,0 @@ -import std; -import Crafter.Build; -using namespace Crafter; - -int main() { - // Local() is the no-op runner — empty exec template, name "local". - if (TestRunner::Local().name != "local") return 1; - - // FromSpec parses each known kind and labels it consistently. - auto cmd = TestRunner::FromSpec("cmd:wine"); - if (!cmd || cmd->name != "cmd:wine") return 1; - - auto local = TestRunner::FromSpec("local"); - if (!local || local->name != "local") return 1; - - // Empty input returns nullopt; anything else unrecognized throws. - // ssh/sshwin/wsl used to be valid specs; they're now bogus (issue #8). - if (TestRunner::FromSpec("")) return 1; - for (auto bogus : { "nonsense:thing", "ssh:somehost", "sshwin:winhost", "wsl" }) { - try { - TestRunner::FromSpec(bogus); - return 1; - } catch (const std::exception&) {} - } - - return 0; -} diff --git a/tests/UnitLib/project.cpp b/tests/UnitLib/project.cpp deleted file mode 100644 index 2f715ee..0000000 --- a/tests/UnitLib/project.cpp +++ /dev/null @@ -1,21 +0,0 @@ -import std; -import Crafter.Build; -namespace fs = std::filesystem; -using namespace Crafter; - -extern "C" Configuration CrafterBuildProject(std::span) { - Configuration cfg; - cfg.path = "tests/UnitLib/"; - cfg.name = "UnitLib"; - cfg.outputName = "UnitLib"; - cfg.target = "x86_64-pc-linux-gnu"; - cfg.type = ConfigurationType::Executable; - cfg.dependencies = { ParentLib("crafter.build-lib") }; - cfg.linkFlags.push_back("-Wl,--export-dynamic"); - cfg.linkFlags.push_back("-ldl"); - - std::array ifaces = {}; - std::array impls = { "main" }; - cfg.GetInterfacesAndImplementations(ifaces, impls); - return cfg; -} diff --git a/tests/Wasi/main.cpp b/tests/Wasi/main.cpp deleted file mode 100644 index 7eb35d2..0000000 --- a/tests/Wasi/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -import std; - -int main() { - std::println("Hello, WASI!"); - return 0; -} diff --git a/tests/Wasi/test.toml b/tests/Wasi/test.toml deleted file mode 100644 index 7f26732..0000000 --- a/tests/Wasi/test.toml +++ /dev/null @@ -1,7 +0,0 @@ -# WASI build via the WASI SDK's libc++ + the wasm32-wasip1 target. The -# runner derivation routes the .wasm artifact through `wasmtime`. -target = "wasm32-wasip1" -requires = [ - "tool:wasmtime", - "file:/usr/share/wasi-sysroot/share/libc++/v1/std.cppm", -] diff --git a/tests/WindowsViaWine/main.cpp b/tests/WindowsViaWine/main.cpp deleted file mode 100644 index 69c75fd..0000000 --- a/tests/WindowsViaWine/main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -import std; - -int main() { - std::println("hi from win{}", sizeof(void*) * 8); - return 0; -} diff --git a/tests/WindowsViaWine/test.toml b/tests/WindowsViaWine/test.toml deleted file mode 100644 index e5c8ef8..0000000 --- a/tests/WindowsViaWine/test.toml +++ /dev/null @@ -1,9 +0,0 @@ -# Linux→Windows end-to-end: -# crafter-build cross-compiles main.cpp to x86_64-w64-mingw32 (.exe) and the -# runner derivation wraps it in `wine`. Replaces the old WindowsViaSsh test, -# which required a reachable Windows VM and an ssh + cmd.exe shell chain. -target = "x86_64-w64-mingw32" -requires = [ - "tool:wine", - "tool:x86_64-w64-mingw32-g++", -] diff --git a/tests/WithModule/interfaces/Greeter.cppm b/tests/WithModule/interfaces/Greeter.cppm deleted file mode 100644 index 1294d98..0000000 --- a/tests/WithModule/interfaces/Greeter.cppm +++ /dev/null @@ -1,6 +0,0 @@ -export module Greeter; -import std; - -export std::string Greet(std::string_view name) { - return std::format("hello, {}!", name); -} diff --git a/tests/WithModule/main.cpp b/tests/WithModule/main.cpp deleted file mode 100644 index e48a400..0000000 --- a/tests/WithModule/main.cpp +++ /dev/null @@ -1,7 +0,0 @@ -import std; -import Greeter; - -int main() { - if (Greet("crafter") != "hello, crafter!") return 1; - return 0; -} diff --git a/tests/_shared/TestUtil.h b/tests/_shared/TestUtil.h deleted file mode 100644 index f810280..0000000 --- a/tests/_shared/TestUtil.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once -#include // setenv (POSIX, not in `import std`) - -namespace TestUtil { - // Exit code 77 follows the autoconf convention. crafter-build's test - // runner maps it to TestOutcome::Skipped and renders the test's stdout - // as the reason. Use this when the test discovers at runtime that its - // preconditions aren't met (tool missing, env unset, etc). - [[noreturn]] inline void Skip(std::string_view reason) { - std::print("{}", reason); - std::exit(77); - } - - inline std::string ReadFile(const std::filesystem::path& p) { - std::ifstream f(p); - std::stringstream ss; - ss << f.rdbuf(); - return ss.str(); - } - - inline std::filesystem::path CopyFixtureToTemp(std::string_view testName, const std::filesystem::path& source) { - namespace fs = std::filesystem; - fs::path tmp = fs::temp_directory_path() / std::format("crafter-test-{}", testName); - fs::remove_all(tmp); - fs::copy(source, tmp, fs::copy_options::recursive); - return tmp; - } - - struct CmdResult { - int exitCode; - std::string output; - }; - - inline CmdResult RunInDir(const std::filesystem::path& cwd, std::string_view command) { - namespace fs = std::filesystem; - // Log inside cwd so parallel test drivers don't trample each other. - fs::path log = cwd / ".crafter-cmd-output.log"; - std::string cmd = std::format("cd '{}' && {} > '{}' 2>&1", - cwd.string(), command, log.string()); - int rc = std::system(cmd.c_str()); - std::string out = ReadFile(log); - std::error_code ec; - fs::remove(log, ec); - return {rc, std::move(out)}; - } - - // Build cfg with a fresh dep cache. Convenient for outer-driver tests that - // exercise the build API in-process and don't need to share the dep cache - // across multiple Build() calls. - inline Crafter::BuildResult BuildOnce(Crafter::Configuration& cfg) { - std::unordered_map> depResults; - std::mutex depMutex; - return Crafter::Build(cfg, depResults, depMutex); - } - - // Copy a fixture into a fresh temp dir, chdir there (so cfg.path = "./" - // inside the inner project.cpp resolves to the temp dir), and load its - // project.cpp. Common prep for in-process build/test API tests. - // - // Also sets CRAFTER_BUILD_HOME to /share/crafter-build before - // loading. The lib's default sourceDir is derived from /proc/self/exe, but - // test exes live in tests//bin/... rather than next to the project's - // share/, so the default lookup misses. The test runner launches tests - // with cwd = project root, so we capture that here before the chdir below. - inline Crafter::Configuration LoadFixture(std::string_view testName, - const std::filesystem::path& source, - std::span args = {}) { - auto projectRoot = std::filesystem::current_path(); - auto sharePath = projectRoot / "share" / "crafter-build"; - ::setenv("CRAFTER_BUILD_HOME", sharePath.string().c_str(), 1); - - auto work = CopyFixtureToTemp(testName, source); - std::filesystem::current_path(work); - return Crafter::LoadProject("project.cpp", args); - } -}