|
| 1 | +#!/usr/bin/env bash |
| 2 | +# requires: gcc |
| 3 | +# A BUILD PROGRAM IS TOLD WHICH PACKAGE IT IS BUILDING. |
| 4 | +# |
| 5 | +# Every name a rule package generates is derived from this one: the module a |
| 6 | +# consumer imports, the namespace the accessors sit in, the symbols in a |
| 7 | +# generated header. Until 2026.9.7.1 nothing answered it, and the closest thing |
| 8 | +# available was the leaf of `MCPP_MANIFEST_DIR` -- a DIRECTORY name. |
| 9 | +# |
| 10 | +# THE DIRECTORY AND THE PACKAGE ARE DELIBERATELY DIFFERENT HERE, and that is the |
| 11 | +# whole test. A fixture whose package name happens to equal its directory leaf |
| 12 | +# passes against both the old derivation and the new one, so it would assert |
| 13 | +# nothing. `mcpp.rules.spirv` shipped with exactly that defect: an example laid |
| 14 | +# out as `vulkan/app/` with `name = "vulkan-saxpy"` generated `app.shaders`, and |
| 15 | +# every `<something>/app/` in a workspace claimed the same module. |
| 16 | +# |
| 17 | +# The answer is written to a FILE rather than printed, because mcpp shows a |
| 18 | +# build program's stdout only when it exits non-zero -- a criterion reading the |
| 19 | +# build log would be measuring the failure path. |
| 20 | +set -e |
| 21 | + |
| 22 | +TMP=$(mktemp -d) |
| 23 | +trap "rm -rf $TMP" EXIT |
| 24 | +cd "$TMP" |
| 25 | + |
| 26 | +# The directory is `app`. The package is not. |
| 27 | +mkdir -p app/src |
| 28 | +cat > app/src/main.cpp <<'EOF' |
| 29 | +int main() { return 0; } |
| 30 | +EOF |
| 31 | + |
| 32 | +cat > app/build.mcpp <<'EOF' |
| 33 | +#include <cstdio> |
| 34 | +#include <string> |
| 35 | +import mcpp; |
| 36 | +int main() { |
| 37 | + std::string out = std::string(mcpp::manifest_dir()) + "/answered.txt"; |
| 38 | + std::FILE* f = std::fopen(out.c_str(), "w"); |
| 39 | + if (f == nullptr) return 3; |
| 40 | + std::fprintf(f, "name=%s\n", mcpp::package_name()); |
| 41 | + std::fprintf(f, "namespace=%s\n", mcpp::package_namespace()); |
| 42 | + std::fclose(f); |
| 43 | + return 0; |
| 44 | +} |
| 45 | +EOF |
| 46 | + |
| 47 | +cat > app/mcpp.toml <<'EOF' |
| 48 | +[package] |
| 49 | +name = "vulkan-saxpy" |
| 50 | +namespace = "example" |
| 51 | +version = "0.1.0" |
| 52 | +
|
| 53 | +[build] |
| 54 | +sources = ["src/*.cpp"] |
| 55 | +
|
| 56 | +[targets.vulkan-saxpy] |
| 57 | +kind = "bin" |
| 58 | +main = "src/main.cpp" |
| 59 | +EOF |
| 60 | + |
| 61 | +cd app |
| 62 | +"${MCPP:-mcpp}" build > build.log 2>&1 || { echo "FAIL: build"; cat build.log; exit 1; } |
| 63 | + |
| 64 | +[ -f answered.txt ] || { echo "FAIL: the build program wrote no answer"; exit 1; } |
| 65 | +cat answered.txt |
| 66 | + |
| 67 | +grep -qx 'name=vulkan-saxpy' answered.txt || { |
| 68 | + echo "FAIL: package_name() did not answer the [package] name" |
| 69 | + echo " (a directory-derived answer would read 'app')" |
| 70 | + exit 1; } |
| 71 | +grep -qx 'namespace=example' answered.txt || { |
| 72 | + echo "FAIL: package_namespace() did not answer the [package] namespace" |
| 73 | + exit 1; } |
| 74 | + |
| 75 | +# THE REVERSE LEG: the directory leaf is `app`, so an implementation that still |
| 76 | +# derived from the directory would have written `app` above. Assert the two are |
| 77 | +# actually different in this fixture, or the check above proves nothing. |
| 78 | +[ "$(basename "$PWD")" = "app" ] || { |
| 79 | + echo "FAIL: this fixture no longer distinguishes the two derivations" |
| 80 | + exit 1; } |
| 81 | + |
| 82 | +echo "PASS: a build program reads its package identity, not its directory name" |
0 commit comments