Skip to content

Commit c84ee05

Browse files
committed
fix(run): the cached fast path dropped the subos environment
`mcpp run` has two paths and only one of them had been taught about subos declarations. The full path resolves the toolchain and applies them; the fast path skips prepare_build entirely and built its own child environment. So a program got its environment on the run right after a build and lost it on every run after that -- for a GL application, "it worked once and now the window is black", with nothing in between to attribute it to. WHICH subos is a build property and is now recorded in the build cache. WHAT it declares is the subos's own and is re-read on every run, so installing a graphics stack between two runs takes effect without a rebuild. That split is also why MCPP_SUBOS_DIR moved out of the derivation: an override means "for this invocation", and caching one would let a single `MCPP_SUBOS_DIR=… mcpp run` silently redirect every later run. Found by an assertion that the test did not originally have. The first version ran `mcpp run` once, passed, and proved nothing about the path it was written for. The fast-path check now runs first and fails loudly if the second run did NOT take the fast path -- without it the assertion below it is vacuous and would keep passing after the coverage silently went away. It caught a second defect immediately: the new cache line was written before `profile=` and parsed after `cacheMode=`, so every entry read back as stale and the fast path was disabled for everyone. Two dead capability tokens, and a guard so there is no third. `# requires: linux` and `# requires: llvm` are not capabilities run_all.sh ever sets, so 65_toolchain_runtime_dirs_for_run.sh had never executed in CI -- and it passes. The skip line for a token that cannot exist reads exactly like the skip line for one that legitimately does not, which is what let it sit. The runner now refuses to start when a test declares a token outside the known universe. The xlings pin goes back to 2026.8.6.3. It was moved to 2026.8.7.1 for tidiness rather than need -- subos_info degrades quietly on an older xlings by design -- and CI's fresh-sandbox jobs failed with the toolchain's own g++ exiting 127, the signature of an interpreter that is not where the binary says it is. Whether that is a real incompatibility is worth knowing, but not on the back of a change that does not need it.
1 parent 37a4be7 commit c84ee05

12 files changed

Lines changed: 168 additions & 38 deletions

File tree

.github/actions/bootstrap-mcpp/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ inputs:
2525
# `package.name`, so one of the two was simply unreachable — and which one
2626
# depended on the machine, which is why CI failed on `compat:lua` on
2727
# Windows and `mcpplibs.capi:lua` on Linux. Never pin below that.
28-
default: '2026.8.7.1'
28+
default: '2026.8.6.3'
2929
cache-target:
3030
description: also restore/save target/ (build artifacts + BMIs)
3131
required: false

.github/actions/setup-macos-llvm/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ inputs:
1515
# Floor imposed by the index, not a routine bump — see
1616
# .github/actions/bootstrap-mcpp/action.yml for why 0.4.69 is required
1717
# (two packages named `lua` in one repo need openxlings/xlings#381).
18-
default: '2026.8.7.1'
18+
default: '2026.8.6.3'
1919

2020
runs:
2121
using: composite

.github/workflows/bootstrap-macos.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
# Dormant (workflow_dispatch only), but kept in step with the rest —
1818
# check_version_pins.sh holds it there. Floor: 0.4.69, below which the
1919
# index cannot resolve two packages that share a short name.
20-
XLINGS_VERSION: '2026.8.7.1'
20+
XLINGS_VERSION: '2026.8.6.3'
2121
steps:
2222
- uses: actions/checkout@v4
2323

.github/workflows/ci-fresh-install.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ jobs:
152152
env:
153153
XLINGS_NON_INTERACTIVE: '1'
154154
run: |
155-
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.7.1
155+
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.6.3
156156
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
157157
158158
- name: Install mcpp and config mirror
@@ -292,7 +292,7 @@ jobs:
292292

293293
- name: Install xlings + mcpp
294294
run: |
295-
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.7.1
295+
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.6.3
296296
# Deliberately NOT writing to $GITHUB_PATH here. On container
297297
# images that declare no PATH in their config (opensuse/
298298
# tumbleweed), appending a single dir to GITHUB_PATH makes the
@@ -363,7 +363,7 @@ jobs:
363363
# (older ones carry minos=15 and refuse to start).
364364
# v0.4.51+: in-process sha256 — this image has no sha256sum
365365
# binary, so pinned fetches failed before it.
366-
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.7.1
366+
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.6.3
367367
echo "$HOME/.xlings/subos/current/bin" >> "$GITHUB_PATH"
368368
369369
- name: Install mcpp and config mirror

.github/workflows/ci-linux-e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ jobs:
123123
124124
- name: Bootstrap xlings + released mcpp
125125
run: |
126-
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.7.1
126+
curl -fsSL https://raw.githubusercontent.com/openxlings/xlings/main/tools/other/quick_install.sh | bash -s v2026.8.6.3
127127
export PATH="$HOME/.xlings/subos/current/bin:$PATH"
128128
xlings update
129129
xlings install mcpp -y -g

.github/workflows/cross-build-test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ jobs:
118118
# release assets were uploaded in a broken state (records present,
119119
# blobs missing → 404 on GET); re-uploaded clean. The stale-INDEX
120120
# half is handled by the marker-clear below.
121-
XLINGS_VERSION: '2026.8.7.1'
121+
XLINGS_VERSION: '2026.8.6.3'
122122
run: |
123123
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
124124
curl -fsSL -o "/tmp/${tarball}" \
@@ -255,7 +255,7 @@ jobs:
255255
- name: Bootstrap mcpp via xlings
256256
env:
257257
XLINGS_NON_INTERACTIVE: '1'
258-
XLINGS_VERSION: '2026.8.7.1'
258+
XLINGS_VERSION: '2026.8.6.3'
259259
run: |
260260
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
261261
curl -fsSL -o "/tmp/${tarball}" \

.github/workflows/release.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ jobs:
9696
# Pin xlings to a known-good version. The upstream install
9797
# script always grabs `latest` (no version override), so we
9898
# download + self-install manually to avoid broken releases.
99-
XLINGS_VERSION: '2026.8.7.1'
99+
XLINGS_VERSION: '2026.8.6.3'
100100
run: |
101101
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
102102
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
@@ -288,7 +288,7 @@ jobs:
288288
- name: Bootstrap mcpp via xlings
289289
env:
290290
XLINGS_NON_INTERACTIVE: '1'
291-
XLINGS_VERSION: '2026.8.7.1'
291+
XLINGS_VERSION: '2026.8.6.3'
292292
run: |
293293
tarball="xlings-${XLINGS_VERSION}-linux-x86_64.tar.gz"
294294
curl -fsSL -o "/tmp/${tarball}" \
@@ -358,11 +358,11 @@ jobs:
358358
# below are pinned to the same version as XLINGS_VERSION; they are
359359
# NOT interpolated from it, so check_version_pins.sh scans for them
360360
# explicitly (they were absent from the old lock-step comment).
361-
XLA="xlings-2026.8.7.1-linux-aarch64.tar.gz"
361+
XLA="xlings-2026.8.6.3-linux-aarch64.tar.gz"
362362
if curl -fsSL -o "/tmp/$XLA" \
363-
"https://github.com/openxlings/xlings/releases/download/v2026.8.7.1/$XLA"; then
363+
"https://github.com/openxlings/xlings/releases/download/v2026.8.6.3/$XLA"; then
364364
tar -xzf "/tmp/$XLA" -C /tmp
365-
XLBIN=$(find /tmp/xlings-2026.8.7.1-linux-aarch64 -path '*/bin/xlings' -type f | head -1)
365+
XLBIN=$(find /tmp/xlings-2026.8.6.3-linux-aarch64 -path '*/bin/xlings' -type f | head -1)
366366
if [ -n "$XLBIN" ]; then
367367
mkdir -p "$STAGING/$WRAPPER/registry/bin"
368368
cp "$XLBIN" "$STAGING/$WRAPPER/registry/bin/xlings"
@@ -440,7 +440,7 @@ jobs:
440440
- name: Bootstrap mcpp via xlings
441441
env:
442442
XLINGS_NON_INTERACTIVE: '1'
443-
XLINGS_VERSION: '2026.8.7.1'
443+
XLINGS_VERSION: '2026.8.6.3'
444444
run: |
445445
if [ ! -x "$HOME/.xlings/subos/default/bin/xlings" ]; then
446446
WORK=$(mktemp -d)
@@ -622,7 +622,7 @@ jobs:
622622
shell: bash
623623
env:
624624
XLINGS_NON_INTERACTIVE: '1'
625-
XLINGS_VERSION: '2026.8.7.1'
625+
XLINGS_VERSION: '2026.8.6.3'
626626
run: |
627627
# Captured before the `cd` below, in POSIX form: this step never
628628
# returns to the workspace, and GITHUB_WORKSPACE is a backslash

src/build/execute.cppm

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ struct BuildCacheEntry {
6262
// plan.runtimeLibraryDirs is empty.
6363
std::string runEnvKey;
6464
std::string runEnvValue;
65+
// The subos this build's toolchain belongs to (mcpp#352). The DIRECTORY,
66+
// never the resolved variables: the environment is the subos's property
67+
// and must be re-read on every run, while WHICH subos is the build's
68+
// property and would otherwise be unknowable on the fast path -- which
69+
// has no toolchain to derive it from.
70+
std::string subosDir;
6571
// The resolved profile this entry was built for. Entries used to be keyed
6672
// by target triple alone, and the fast paths only refuse to run when an
6773
// EXPLICIT --profile/--dev/--release is passed — so a bare `mcpp build`
@@ -141,6 +147,16 @@ std::vector<BuildCacheEntry> read_build_cache(const std::filesystem::path& proje
141147
std::getline(f, e.runEnvValue);
142148
haveNextLine = static_cast<bool>(std::getline(f, line));
143149
}
150+
// Optional subos line. Same back-compat contract: absent ⇒ empty ⇒
151+
// the run fast path treats the entry as a miss, exactly as it already
152+
// does for a cache written before runtimeEnvKey existed. Running with
153+
// a DIFFERENT environment than the full path would be worse than not
154+
// using the cache at all -- the program would work once and then
155+
// silently stop finding its runtime data.
156+
if (haveNextLine && line.starts_with("subos=")) {
157+
e.subosDir = line.substr(6);
158+
haveNextLine = static_cast<bool>(std::getline(f, line));
159+
}
144160
// Optional profile line. Same back-compat contract as the two blocks
145161
// above: absent ⇒ e.profile stays empty ⇒ every fast path treats the
146162
// entry as a miss and falls through to prepare_build.
@@ -169,7 +185,8 @@ void write_build_cache(const std::filesystem::path& projectRoot,
169185
const std::string& runEnvKey = "",
170186
const std::string& runEnvValue = "",
171187
const std::string& profile = "",
172-
const std::string& cacheMode = "") {
188+
const std::string& cacheMode = "",
189+
const std::string& subosDir = "") {
173190
auto path = projectRoot / kBuildCacheFile;
174191
auto entries = read_build_cache(projectRoot);
175192

@@ -184,7 +201,7 @@ void write_build_cache(const std::filesystem::path& projectRoot,
184201
// Insert at front (MRU).
185202
BuildCacheEntry newEntry{targetTriple, outputDir.string(), ninjaProgram, fingerprintHex,
186203
runtimeEnvKey, runtimeEnvValue, std::move(runTargets),
187-
runEnvKey, runEnvValue, profile, cacheMode};
204+
runEnvKey, runEnvValue, subosDir, profile, cacheMode};
188205
entries.insert(entries.begin(), std::move(newEntry));
189206

190207
// Trim to LRU capacity.
@@ -212,6 +229,7 @@ void write_build_cache(const std::filesystem::path& projectRoot,
212229
for (auto& [name, exe] : e.runTargets) f << name << '\t' << exe << '\n';
213230
f << "runEnv=" << e.runEnvKey << '\n';
214231
f << e.runEnvValue << '\n';
232+
f << "subos=" << e.subosDir << '\n';
215233
f << "profile=" << e.profile << '\n';
216234
f << "cacheMode=" << e.cacheMode << '\n';
217235
}
@@ -307,19 +325,35 @@ compute_run_env(const mcpp::build::BuildPlan& plan) {
307325
// mcpp does not know what any of these variables MEAN, and that is the design:
308326
// when the ecosystem gains a Vulkan loader or a new driver bridge, the
309327
// declaration changes and this code does not.
328+
// The subos a RUN should use: an explicit override if the caller set one,
329+
// otherwise the subos this build belongs to.
330+
//
331+
// The override lives HERE and not in the derivation, because the derivation's
332+
// answer is cached and this one must not be: MCPP_SUBOS_DIR says "for this
333+
// invocation". It exists so tests can exercise this path without touching a
334+
// developer's real subos — an earlier e2e wrote through a symlink and
335+
// permanently broke a real toolchain — and so a user can point one run at
336+
// another subos without switching the active one.
337+
std::filesystem::path subos_dir_for_run(const std::filesystem::path& buildSubos) {
338+
if (const char* e = std::getenv("MCPP_SUBOS_DIR"); e && *e)
339+
return std::filesystem::path(e);
340+
return buildSubos;
341+
}
342+
310343
std::vector<std::pair<std::string, std::string>>
311344
compute_subos_env(const mcpp::build::BuildPlan& plan) {
312-
auto dir = mcpp::xlings::paths::subos_dir_for(plan.toolchain.binaryPath);
313-
if (!dir) return {};
314-
auto info = mcpp::xlings::subos::read(*dir);
345+
auto built = mcpp::xlings::paths::subos_dir_of(plan.toolchain.binaryPath);
346+
auto dir = subos_dir_for_run(built ? *built : std::filesystem::path{});
347+
if (dir.empty()) return {};
348+
auto info = mcpp::xlings::subos::read(dir);
315349
// The note is a `verbose` line rather than a warning: a subos with no
316350
// self-description is the normal state of every machine whose subos
317351
// predates the block, and a warning on every run would train people to
318352
// ignore it. It becomes loud only where it explains a failure — the GL
319353
// diagnostic path in doctor.
320354
if (!info.note.empty())
321355
mcpp::log::verbose("subos", info.note);
322-
return mcpp::xlings::subos::resolve_env(info, *dir);
356+
return mcpp::xlings::subos::resolve_env(info, dir);
323357
}
324358

325359
// Compile a prepared BuildContext. Shared between `mcpp build` and `mcpp run`
@@ -433,12 +467,14 @@ export int run_build_plan(BuildContext& ctx, bool verbose, bool no_cache,
433467
auto fpHex = ctx.outputDir.filename().string();
434468
auto runTargets = compute_run_targets(ctx.plan);
435469
auto [runEnvKey, runEnvValue] = compute_run_env(ctx.plan);
470+
auto subosDir = mcpp::xlings::paths::subos_dir_of(ctx.plan.toolchain.binaryPath);
436471
write_build_cache(ctx.projectRoot, ctx.outputDir, r->ninjaProgram,
437472
std::string(targetOverride), fpHex,
438473
r->runtimeEnvKey.empty() ? "-" : r->runtimeEnvKey,
439474
r->runtimeEnvValue,
440475
std::move(runTargets), runEnvKey, runEnvValue,
441-
ctx.profile, std::string(cache_mode_name(ctx.cacheMode)));
476+
ctx.profile, std::string(cache_mode_name(ctx.cacheMode)),
477+
subosDir ? subosDir->string() : std::string{});
442478
}
443479

444480
// The one place the --strict policy is settled. Degradations reported by
@@ -789,6 +825,25 @@ std::optional<int> try_fast_run(const std::filesystem::path& projectRoot,
789825
std::vector<std::pair<std::string, std::string>> childEnv;
790826
if (!match->runEnvKey.empty() && !match->runEnvValue.empty())
791827
childEnv.emplace_back(match->runEnvKey, match->runEnvValue);
828+
// ...and the subos's declared environment, re-READ here rather than taken
829+
// from the cache. Which subos is a build property (cached above); what it
830+
// declares is the subos's own, and a user who installs a graphics stack
831+
// between two runs must get it without rebuilding.
832+
//
833+
// This is the half that a fast path is most likely to lose, and losing it
834+
// would be invisible in the worst way: the first `mcpp run` after a build
835+
// takes the full path and works, every later one takes this path and does
836+
// not. A GL program would run once and then stop finding its driver.
837+
{
838+
// Same rule as the full path, through the same helper: an override
839+
// for this invocation, else the subos this build was recorded against.
840+
auto subosDir = subos_dir_for_run(std::filesystem::path(match->subosDir));
841+
if (!subosDir.empty()) {
842+
auto info = mcpp::xlings::subos::read(subosDir);
843+
for (auto& kv : mcpp::xlings::subos::resolve_env(info, subosDir))
844+
childEnv.push_back(std::move(kv));
845+
}
846+
}
792847

793848
return mcpp::platform::process::run_exec(argv, childEnv) == 0 ? 0 : 1;
794849
}

src/xlings.cppm

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ namespace pinned {
4444
// in lock-step by hand; that list was already missing both composite
4545
// actions, which is how CI's sandbox sat on 0.4.30 unnoticed while
4646
// everything else had moved on. Don't reintroduce a hand-maintained list.
47-
inline constexpr std::string_view kXlingsVersion = "2026.8.7.1";
47+
inline constexpr std::string_view kXlingsVersion = "2026.8.6.3";
4848
inline constexpr std::string_view kNasmVersion = "3.02";
4949
}
5050

@@ -74,25 +74,25 @@ namespace paths {
7474
std::optional<std::filesystem::path>
7575
xpkgs_from_compiler(const std::filesystem::path& compilerBin);
7676

77-
// The subos whose declared ENVIRONMENT a program built with this toolchain
78-
// should run under (mcpp#352).
77+
// The subos a TOOLCHAIN belongs to (mcpp#352).
7978
//
8079
// Derived from the compiler rather than from a global: a build already
8180
// knows which home its toolchain came from, and asking a second source
8281
// would let the two disagree — the "one question, several answerers" shape
8382
// that the same investigation found four times over on the xlings side.
8483
//
85-
// MCPP_SUBOS_DIR overrides it outright. That exists so tests can exercise
86-
// this path without touching the developer's real environment (a lesson
87-
// with a scar: an earlier e2e wrote through a symlink and permanently
88-
// broke a real toolchain), and so a user can point one run at another
89-
// subos without switching the active one.
84+
// A PURE derivation, with no environment override in it. That is not an
85+
// omission: this value gets written into the build cache, and an override
86+
// means "for this invocation", not "for this build from now on". Caching
87+
// one would make a single `MCPP_SUBOS_DIR=… mcpp run` silently change
88+
// where every later run looked. Which subos a RUN should use is a
89+
// different question, answered in execute.cppm.
9090
//
9191
// Empty when the toolchain is not sandbox-resident — a system compiler is
9292
// the user's explicit choice of the host world, and there is no subos
9393
// speaking for it.
9494
std::optional<std::filesystem::path>
95-
subos_dir_for(const std::filesystem::path& compilerBin);
95+
subos_dir_of(const std::filesystem::path& compilerBin);
9696

9797
// Find a sibling xim tool relative to a compiler binary.
9898
// e.g. find_sibling_tool(gcc_bin, "binutils") returns highest version
@@ -694,9 +694,7 @@ xpkgs_from_compiler(const std::filesystem::path& compilerBin) {
694694
}
695695

696696
std::optional<std::filesystem::path>
697-
subos_dir_for(const std::filesystem::path& compilerBin) {
698-
if (const char* e = std::getenv("MCPP_SUBOS_DIR"); e && *e)
699-
return std::filesystem::path(e);
697+
subos_dir_of(const std::filesystem::path& compilerBin) {
700698
auto xpkgs = xpkgs_from_compiler(compilerBin);
701699
if (!xpkgs) return std::nullopt;
702700
// <home>/data/xpkgs → <home>/subos/default. Spelled from the xpkgs dir

tests/e2e/195_subos_env_reaches_program.sh renamed to tests/e2e/200_subos_env_reaches_program.sh

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
2-
# requires: linux
3-
# 195_subos_env_reaches_program.sh — a subos's declared environment must reach
2+
# requires: elf
3+
# 200_subos_env_reaches_program.sh — a subos's declared environment must reach
44
# the program mcpp launches (mcpp#352).
55
#
66
# A program needs three things: it links (bootstrap), it finds its libraries
@@ -55,6 +55,49 @@ echo "$out" | grep -q "PROBE=$subos/usr/lib/dri" || {
5555
exit 1
5656
}
5757

58+
# 1b. THE SECOND RUN, which takes the cached fast path.
59+
#
60+
# This is the assertion that matters most, and the one a single-run test
61+
# cannot make. The fast path builds its own child environment and skips
62+
# prepare_build entirely; when it was first written it did not know about
63+
# subos declarations at all, so a program worked on the run right after a
64+
# build and silently stopped finding its runtime data on every run after
65+
# that. For a GL application that is "it worked once and now the window is
66+
# black", with nothing in between to attribute it to.
67+
out_cached=$(MCPP_SUBOS_DIR="$subos" "$MCPP" run 2>&1) || {
68+
echo "cached mcpp run failed:"; echo "$out_cached"; exit 1; }
69+
# Self-check FIRST: prove this run actually took the fast path, otherwise the
70+
# assertion below is vacuous and would keep passing after the coverage it
71+
# exists for has silently gone away. The full path resolves the toolchain and
72+
# says so; the fast path skips prepare_build entirely and never prints it.
73+
echo "$out_cached" | grep -q 'Resolving toolchain' && {
74+
echo "the second run did NOT take the cached fast path, so this test is"
75+
echo " not covering it. Fix the test before trusting the assertion below:"
76+
echo "$out_cached"
77+
exit 1
78+
}
79+
echo "$out_cached" | grep -q "PROBE=$subos/usr/lib/dri" || {
80+
echo "the cached fast path dropped the subos environment — the program"
81+
echo " gets a different environment on its second run than its first:"
82+
echo "$out_cached"
83+
exit 1
84+
}
85+
86+
# 1c. ...and the environment is re-READ, not cached with the build. A user
87+
# who installs a graphics stack between two runs must get it without
88+
# rebuilding, so changing the declaration must change the next run.
89+
sed -i 's#/usr/lib/dri#/usr/lib/dri2#' "$subos/.xlings.json"
90+
out_changed=$(MCPP_SUBOS_DIR="$subos" "$MCPP" run 2>&1) || {
91+
echo "run after changing the declaration failed:"; echo "$out_changed"; exit 1; }
92+
echo "$out_changed" | grep -q "PROBE=$subos/usr/lib/dri2" || {
93+
echo "the subos declaration changed but the program still sees the old"
94+
echo " value — the environment was cached with the build instead of"
95+
echo " being read from the subos:"
96+
echo "$out_changed"
97+
exit 1
98+
}
99+
sed -i 's#/usr/lib/dri2#/usr/lib/dri#' "$subos/.xlings.json"
100+
58101
# 2. Without a subos saying anything, nothing is invented.
59102
out2=$("$MCPP" run 2>&1) || { echo "plain mcpp run failed:"; echo "$out2"; exit 1; }
60103
echo "$out2" | grep -q 'PROBE=(unset)' || {

0 commit comments

Comments
 (0)