Skip to content

Commit f842b54

Browse files
committed
fix(toolchain): 'default msvc' clears the target axis; e2e 99 asserts the resolved family
A stale [toolchain].default_target (left by a previous mingw/musl default) survived 'toolchain default msvc' — the msvc branch persisted only the toolchain axis. The leftover x86_64-windows-gnu then hijacked the next build: the target's convention pin overrode msvc@system and cl.exe builds silently ran gcc instead (caught by ci-windows: e2e 99 found .o instead of .obj after a 9s 'msvc' build). msvc default now writes default_target='' like every other default; e2e 99 additionally asserts the resolved family and uses the boundary-safe default-key grep (as 95/97 already do).
1 parent a8b5b0b commit f842b54

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

src/toolchain/lifecycle.cppm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,15 @@ export int toolchain_set_default(const mcpp::config::GlobalConfig& cfg,
647647
mcpp::ui::error(wr.error().message);
648648
return 1;
649649
}
650+
// Clear the target axis too: a stale default_target (e.g.
651+
// x86_64-windows-gnu left by a previous mingw default) would
652+
// otherwise hijack the next build — the target's convention pin
653+
// overrides the toolchain, silently building with gcc instead
654+
// of the just-selected cl.exe. Caught by ci-windows e2e 99.
655+
if (auto wt = mcpp::config::write_default_target(cfg, ""); !wt) {
656+
mcpp::ui::error(wt.error().message);
657+
return 1;
658+
}
650659
mcpp::ui::status("Default", std::format(
651660
"set to msvc@system (was: {})",
652661
cfg.defaultToolchain.empty() ? "<none>" : cfg.defaultToolchain));

tests/e2e/99_msvc_native_build.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ set -e
99
CONF="${MCPP_HOME:-$HOME/.mcpp}/config.toml"
1010
ORIG_DEFAULT=""
1111
if [[ -f "$CONF" ]]; then
12+
# NB: match `default =` exactly — `default_target =` also starts with
13+
# "default" (the persisted pair since the naming unification).
1214
ORIG_DEFAULT=$(sed -n '/^\[toolchain\]/,/^\[/p' "$CONF" \
13-
| grep '^default' | head -1 | cut -d'"' -f2 || true)
15+
| grep -E '^default[[:space:]]*=' | head -1 | cut -d'"' -f2 || true)
1416
fi
1517
TMP=$(mktemp -d)
1618
restore() {
@@ -42,6 +44,10 @@ int main() { std::println("{}", hello::greet()); return 0; }
4244
EOF
4345

4446
out=$("$MCPP" build 2>&1) || { echo "FAIL: msvc build: $out"; exit 1; }
47+
# the build must actually resolve msvc — a stale default_target could
48+
# otherwise silently reroute to another toolchain (that exact bug shipped
49+
# once: mingw's leftover default_target hijacked `toolchain default msvc`)
50+
grep -q "msvc" <<<"$out" || { echo "FAIL: build did not resolve msvc: $out"; exit 1; }
4551
run_out=$("$MCPP" run 2>&1) || { echo "FAIL: msvc run: $run_out"; exit 1; }
4652
[[ "$run_out" == *"cl-ok"* ]] || { echo "FAIL: run output: $run_out"; exit 1; }
4753

0 commit comments

Comments
 (0)