|
| 1 | +#!/usr/bin/env bash |
| 2 | +# requires: |
| 3 | +# 940 -- an indirect import is found whatever module map its importer has. |
| 4 | +# |
| 5 | +# A unit of the root package is given a module map only when it reaches a |
| 6 | +# module of another package (pack drive and selection design 2026-10-01, B1); |
| 7 | +# a unit that imports only the root's modules is compiled with the compiler's |
| 8 | +# own mapper. GCC records in a BMI the path of each module that BMI imports, as |
| 9 | +# its compile's mapper spelt it, and an importer finds an INDIRECT import at |
| 10 | +# that recorded path below its own repository. Until 2026.10.26.2 a map named |
| 11 | +# no repository, so a unit with a map that imported a root module compiled |
| 12 | +# without one looked for that module's import beside the build directory: |
| 13 | +# |
| 14 | +# mcppide.platform.os: error: failed to read compiled module: No such file |
| 15 | +# note: compiled module file is 'mcppide.platform.os.gcm' |
| 16 | +# |
| 17 | +# Criteria: |
| 18 | +# A. `app.os` (imports nothing), `app.process` (imports app.os; no map), |
| 19 | +# `app.jobs` (imports app.process and a path dependency's module; a map): |
| 20 | +# the build succeeds and the program runs. |
| 21 | +# B. The reverse: `app.view` (no map) imports `app.jobs` (a map), whose BMI |
| 22 | +# records its own imports; the build succeeds. |
| 23 | +set -e |
| 24 | + |
| 25 | +TMP=$(mktemp -d) |
| 26 | +trap 'rm -rf "$TMP"' EXIT |
| 27 | +fail() { echo "FAIL: $1"; shift; for f in "$@"; do echo "--- $f ---"; cat "$f" 2>/dev/null; done; exit 1; } |
| 28 | + |
| 29 | +cd "$TMP" |
| 30 | +mkdir -p dep/src app/src |
| 31 | +cat > dep/mcpp.toml <<'TOML' |
| 32 | +[package] |
| 33 | +name = "dep" |
| 34 | +version = "0.1.0" |
| 35 | +
|
| 36 | +[targets.dep] |
| 37 | +kind = "lib" |
| 38 | +TOML |
| 39 | +printf 'export module dep.lib;\nexport int dep_value() { return 2; }\n' > dep/src/lib.cppm |
| 40 | + |
| 41 | +cat > app/mcpp.toml <<'TOML' |
| 42 | +[package] |
| 43 | +name = "app" |
| 44 | +version = "0.1.0" |
| 45 | +
|
| 46 | +[dependencies] |
| 47 | +dep = { path = "../dep" } |
| 48 | +TOML |
| 49 | +printf 'export module app.os;\nexport inline constexpr int os_value = 1;\n' > app/src/os.cppm |
| 50 | +printf 'export module app.process;\nimport app.os;\nexport int process_value() { return os_value; }\n' > app/src/process.cppm |
| 51 | +printf 'export module app.jobs;\nimport app.process;\nimport dep.lib;\nexport int jobs_value() { return process_value() + dep_value(); }\n' > app/src/jobs.cppm |
| 52 | +printf 'export module app.view;\nimport app.jobs;\nexport int view_value() { return jobs_value() * 10; }\n' > app/src/view.cppm |
| 53 | +printf '#include <cstdio>\nimport app.view;\nint main() { std::printf("%%d\\n", view_value()); }\n' > app/src/main.cpp |
| 54 | + |
| 55 | +cd app |
| 56 | +"$MCPP" build > build.log 2>&1 || fail "a unit with a map could not read a root BMI's import" build.log |
| 57 | +echo "ok: A, B the build succeeds" |
| 58 | +out=$("$MCPP" run 2>run.log | tr -d '\r' | tail -1) |
| 59 | +[ "$out" = "30" ] || fail "the program printed '$out', expected 30" run.log |
| 60 | +echo "ok: the program runs" |
| 61 | + |
| 62 | +echo "PASS: 940 an indirect import is found whatever map its importer has" |
0 commit comments