Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 28 additions & 26 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,9 @@ jobs:
# from one that does not; without the guard this is
# `namespace default {` and the generated file does not parse.
grep -q '^namespace default_ {' \
target/.build-mcpp/out/spirv/shader_app.shaders.cppm \
$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/shader_app.shaders.cppm \
|| { echo "FAIL: the keyword directory did not get its trailing underscore"
grep -n namespace target/.build-mcpp/out/spirv/shader_app.shaders.cppm
grep -n namespace $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/shader_app.shaders.cppm
exit 1; }
# The point of the surface: a consumer names no generated file.
if grep -rn 'scale_comp\.h\|\.inc"' src/; then
Expand All @@ -271,10 +271,10 @@ jobs:
# manifest directory's leaf -- which is what this rule did before mcpp
# 2026.9.7.1 gave build programs `mcpp::package_name()` -- would write
# `spirv_module_consumer.shaders.cppm` and this test would find no file.
iface=target/.build-mcpp/out/spirv/shader_app.shaders.cppm
iface=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/shader_app.shaders.cppm
test -f "$iface" || {
echo "FAIL: no module interface at $iface"
find target/.build-mcpp/out/spirv -name '*.cppm' -print
find $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv -name '*.cppm' -print
exit 1; }
grep -q '^export module shader_app.shaders;' "$iface"
# The interface must name no standard-library type: one that does
Expand All @@ -300,7 +300,7 @@ jobs:
tar -xzf shaderc.tar.gz
rm -rf target
MCPP_GLSLC="$PWD/shaderc-2026.3/bin/glslc" "$MCPP" build
test -f target/.build-mcpp/out/spirv/scale_comp.inc
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/scale_comp.inc
MCPP_GLSLC="$PWD/shaderc-2026.3/bin/glslc" "$MCPP" run | tee run-glslc.log
grep -q '^magic=07230203' run-glslc.log
rm -rf shaderc.tar.gz shaderc-2026.3
Expand Down Expand Up @@ -339,7 +339,7 @@ jobs:
# TWO declarations, and the directory is in the second one's name.
# A build that collapsed them would also produce a working binary, so
# the criterion is the generated names rather than the run.
d=target/.build-mcpp/out/spirv
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv
find "$d" -name '*.h' | sort | sed 's/^/ /'
grep -rq 'scale_comp_spv' "$d" || {
echo "FAIL: the top-level shader lost its declaration"; exit 1; }
Expand Down Expand Up @@ -385,7 +385,7 @@ jobs:
grep -q '^all ok' run.log
# Neither artefact is written by hand.
test ! -f include/island_interface.kernels.h
d=target/.build-mcpp/out/island
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
grep -q 'extern "C" {' "$d/island_interface.kernels.h"
# THE MODULE NAME AND THE NAMESPACE ARE ONE IDENTIFIER PATH, which is
# the rule docs/42 states for both lanes and the one this generator
Expand Down Expand Up @@ -515,14 +515,16 @@ jobs:
- name: the same boundary and the same names, from the half the build selected
working-directory: tests/island-interface
run: |
d=target/.build-mcpp/out/island
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
cp "$d/island_interface.kernels.cppm" /tmp/device-leg.cppm
rm -rf target
"$MCPP" build --no-accel > cpu.log 2>&1 || {
echo "FAIL: the CPU leg does not build"; tail -25 cpu.log; exit 1; }
"$MCPP" run --no-accel | tee cpurun.log
grep -q '^out\[0\]=6 out\[1\]=12 out\[2\]=18 out\[3\]=24' cpurun.log
grep -q '^all ok' cpurun.log
# The CPU leg is another configuration, with its own output directory.
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
diff /tmp/device-leg.cppm "$d/island_interface.kernels.cppm" || {
echo "FAIL: the qualified names differ between the two legs"; exit 1; }
echo "ok: the CPU leg reaches the same qualified names"
Expand All @@ -538,7 +540,7 @@ jobs:
- name: reorganising a root that does not supply the shape renames nothing
working-directory: tests/island-interface
run: |
d=target/.build-mcpp/out/island
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
cp "$d/island_interface.kernels.cppm" /tmp/before-move.cppm
mkdir -p src/cpu/deep && mv src/cpu/ops.c src/cpu/deep/ops.c
rm -rf target
Expand All @@ -562,8 +564,8 @@ jobs:
- name: a new island file reaches the boundary with nothing else touched
working-directory: tests/island-interface
run: |
d=target/.build-mcpp/out/island
rm -rf target && "$MCPP" build > base.log 2>&1
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
before=$(grep -c '^using ::' "$d/island_interface.kernels.cppm")
mkdir -p src/kernels/audio
printf 'MCPP_EXPORT_C\nint island_fft(float* out, unsigned n) { (void)out; (void)n; return 0; }\n' \
Expand Down Expand Up @@ -781,16 +783,16 @@ jobs:
grep -q '^all ok' run.log
# The bytes are a section, so the compiler never saw a C array: the
# payload is a bare `.spv` and an `.S` names it with `.incbin`.
test -f target/.build-mcpp/out/spirv/scale_comp.spv
test -f target/.build-mcpp/out/spirv/spirv_object_storage.shaders.payload.S
grep -q '\.incbin' target/.build-mcpp/out/spirv/spirv_object_storage.shaders.payload.S
if ls target/.build-mcpp/out/spirv/*.inc >/dev/null 2>&1; then
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/scale_comp.spv
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/spirv_object_storage.shaders.payload.S
grep -q '\.incbin' $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/spirv_object_storage.shaders.payload.S
if ls $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/*.inc >/dev/null 2>&1; then
echo "FAIL: object storage still produced a C initialiser list"
exit 1
fi
# `pCode` wants four-byte alignment and a section directive alone does
# not promise it.
grep -q '\.balign 4' target/.build-mcpp/out/spirv/spirv_object_storage.shaders.payload.S
grep -q '\.balign 4' $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/spirv_object_storage.shaders.payload.S
echo "ok: the payload is a section, not generated source"

- name: rules-spirv with sidecar storage
Expand All @@ -800,7 +802,7 @@ jobs:
"$MCPP" run | tee run.log
grep -q '^magic=07230203' run.log
grep -q '^all ok' run.log
test -f target/.build-mcpp/out/spirv/scale_comp.spv
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/scale_comp.spv
# THE REVERSE LEG, AND IT IS THE POINT OF THIS STORAGE. The accessor
# opens a path relative to the working directory, so the program finds
# its shaders from the package root and must not from anywhere else.
Expand Down Expand Up @@ -1001,7 +1003,7 @@ jobs:
exit 1
fi
grep -q '^export module slang_consumer.shaders;' \
target/.build-mcpp/out/slang/slang_consumer.shaders.cppm
$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/slang/slang_consumer.shaders.cppm
echo "ok: a Slang shader reached through the same surface as a GLSL one"

# THE NEGATIVE LEG. A `per_file` key that names no shader must refuse the
Expand Down Expand Up @@ -1034,7 +1036,7 @@ jobs:
"$MCPP" run | tee run.log
grep -q '^magic=07230203' run.log
grep -q '^all ok' run.log
test -f target/.build-mcpp/out/slang/scale.spv
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/slang/scale.spv
if grep -q 'source-embed' target/*/*/build.ninja; then
echo "FAIL: sidecar storage still asked slangc to embed"; exit 1
fi
Expand Down Expand Up @@ -1115,7 +1117,7 @@ jobs:
# `key_kind::relative_path` and `element::word32` -- and `head -1`
# picked one by directory order, so the check was asserting about a
# file nothing chose.
mapfile -t headers < <(find target/.build-mcpp/out -name '*.h' | sort)
mapfile -t headers < <(find $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh") -name '*.h' | sort)
[ "${#headers[@]}" -gt 0 ] || { echo "FAIL: no generated header"; exit 1; }
echo "checking ${#headers[@]} generated header(s)"
for h in "${headers[@]}"; do
Expand Down Expand Up @@ -1424,7 +1426,7 @@ jobs:
working-directory: tests/hip-consumer
run: |
"$MCPP" build
test -f target/.build-mcpp/out/saxpy.hip.o
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/saxpy.hip.o
"$MCPP" build --no-accel
"$MCPP" run --no-accel | tee run.log
grep -q '^12 24 36 48' run.log
Expand All @@ -1437,8 +1439,8 @@ jobs:
working-directory: tests/sycl-consumer
run: |
"$MCPP" build
test -f target/.build-mcpp/out/saxpy.sycl.o
test -f target/.build-mcpp/out/sycl_device_link.o
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/saxpy.sycl.o
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/sycl_device_link.o
"$MCPP" build --no-accel
"$MCPP" run --no-accel | tee run.log
grep -q '^12 24 36 48' run.log
Expand Down Expand Up @@ -1536,9 +1538,9 @@ jobs:
working-directory: tests/multi-rule-consumer
run: |
"$MCPP" build
test -f target/.build-mcpp/out/saxpy.cu.o
test -f target/.build-mcpp/out/spirv/scale_comp.h
test ! -f target/.build-mcpp/out/scale.cu.o
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/saxpy.cu.o
test -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/spirv/scale_comp.h
test ! -f $(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/scale.cu.o
"$MCPP" run --no-accel | tee run.log
grep -q '^magic=(no shader in this build)' run.log
grep -q '^12 24 36 48' run.log
Expand Down Expand Up @@ -1980,7 +1982,7 @@ jobs:
"$MCPP" run | tee run.log
grep -q '^out\[0\]=6 out\[1\]=12 out\[2\]=18 out\[3\]=24' run.log
grep -q '^all ok' run.log
d=target/.build-mcpp/out/island
d=$(sh "$GITHUB_WORKSPACE/tests/out-dir.sh")/island
# The namespace is the path from the layout root to the file, so this
# is the assertion a separator mistake fails.
grep -q '^export namespace island_interface::kernels {' \
Expand Down
5 changes: 3 additions & 2 deletions tests/apk-consumer-libraries/check-apk-libraries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,9 @@ grep -q "android.permission.VIBRATE" libs-perm1.log || fail "the library's permi
grep -q "android.permission.WAKE_LOCK" libs-perm1.log || fail "the archive's permission was not merged" libs-perm1.log
grep -q "android.permission.CAMERA" libs-perm1.log && fail "the permission the application removed is in the package" libs-perm1.log
grep -q 'org.mcpp.apklibs.lib.FLAVOUR' libs-xml1.log || fail "the library's meta-data was not merged" libs-xml1.log
grep -q 'tools' target/.build-mcpp/out/dist-apk/AndroidManifest.xml \
&& fail "the merged manifest still carries a tools: attribute" target/.build-mcpp/out/dist-apk/AndroidManifest.xml
merged="$(sh "$(dirname "$0")/../out-dir.sh")/dist-apk/AndroidManifest.xml"
grep -q 'tools' "$merged" \
&& fail "the merged manifest still carries a tools: attribute" "$merged"
echo "ok: the manifest merges the library's and the archive's permissions and meta-data, drops the removed one, and keeps no tools: attribute"

"$JAR" tf "$apk" > libs-list1.log
Expand Down
2 changes: 1 addition & 1 deletion tests/apk-consumer/check-apk-features.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ rm -rf target
unset APK_CONSUMER_TEMPLATE APK_CONSUMER_LEVEL1 || true
"$MCPP" build --target "$TARGET" > build-a.log 2>&1 || fail "build failed" build-a.log
"$MCPP" pack --format apk --target "$TARGET" > pack-a.log 2>&1 || fail "pack failed" pack-a.log
MANIFEST=target/.build-mcpp/out/dist-apk/AndroidManifest.xml
MANIFEST="$(sh "$(dirname "$0")/../out-dir.sh")/dist-apk/AndroidManifest.xml"
cmp fixtures/expected-manifest-level0-0.8.0.xml "$MANIFEST" \
|| fail "level 0's manifest is not byte-identical to 0.8.0's" "$MANIFEST" fixtures/expected-manifest-level0-0.8.0.xml
echo "ok: level 0 with no template renders 0.8.0's manifest byte-for-byte"
Expand Down
2 changes: 1 addition & 1 deletion tests/metal-consumer/check-metal.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ reading metal-version "$(xcrun --sdk macosx metal --version 2>&1 | head -1)"
# ── 1. three libraries beside the program ─────────────────────────────────
echo "== 1. the shaders compile to Metal libraries the program finds =="
"$MCPP" build > metal-build.log 2>&1 || fail "mcpp build failed" metal-build.log
gen=target/.build-mcpp/out/metal
gen="$(sh "$(dirname "$0")/../out-dir.sh")/metal"
for name in scale tint tint_red; do
[ -f "$gen/$name.air" ] || fail "no $gen/$name.air" metal-build.log
[ -f "$gen/$name.metallib" ] || fail "no $gen/$name.metallib" metal-build.log
Expand Down
19 changes: 19 additions & 0 deletions tests/out-dir.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/sh
# Where `mcpp::out_dir()` pointed in the newest build of the package in the
# current directory. mcpp 2026.10.10.1 and later give each configuration its own
# output directory and record it as the root package's `outDir` in
# resolution.json; earlier engines use target/.build-mcpp/out.
r=$(ls -t target/*/*/resolution.json 2>/dev/null | head -1)
if [ -n "$r" ]; then
py=$(command -v python3 || command -v python)
d=$("$py" -c 'import json, sys
for p in json.load(open(sys.argv[1])).get("graph", {}).get("packages", []):
if p.get("root"):
print(p.get("outDir", ""))
break' "$r" 2>/dev/null)
if [ -n "$d" ]; then
echo "$d"
exit 0
fi
fi
echo "target/.build-mcpp/out"
Loading