Skip to content

Commit dd53530

Browse files
fix(toolchain): msvc@system is located for a build program, never installed
On a Windows machine whose default is msvc@system, a build program of a bare cross target resolved its host toolchain through the package index and looked for an msvc@system package. The spec now resolves the way a native build resolves it: the Visual Studio installation is located, and its absence is reported with the installation guidance. E2E 1017 builds openkal's 32-bit layout probe shape on Windows with msvc@system. Co-authored-by: speak-agent <248744407+speak-agent@users.noreply.github.com>
1 parent 30b900f commit dd53530

2 files changed

Lines changed: 84 additions & 0 deletions

File tree

‎src/build/prepare/xlings.cpp‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import mcpp.manifest;
1818
import mcpp.source_kind;
1919
import mcpp.toolchain.hostflags; // the compile-token producer the package std module reuses
2020
import mcpp.toolchain.detect;
21+
import mcpplibs.os.platform;
22+
import mcpp.toolchain.msvc;
2123
import mcpp.toolchain.dialect;
2224
import mcpp.toolchain.fingerprint;
2325
import mcpp.toolchain.registry;
@@ -235,6 +237,27 @@ step3_define_host_tc_closures_and_refresh_index(PrepareState& state) {
235237
return std::unexpected(std::format(
236238
"toolchain spec '{}' is invalid for the build.mcpp host resolve", hostSpecText));
237239
}
240+
// `<family>@system` NAMES THIS MACHINE'S INSTALLATION, AND IS LOCATED,
241+
// NEVER INSTALLED (2026.11.7.1). A Windows machine whose default is
242+
// `msvc@system`, building for a bare cross target, handed that spec to
243+
// the package resolver below, which looked for `msvc@system` in the
244+
// index (design 2026-11-07 §4.1.3). The build program is located the
245+
// way a native build locates the same spec.
246+
if (mcpp::toolchain::origin_of(*spec) == mcpp::toolchain::Origin::SystemMsvc) {
247+
if constexpr (!mcpplibs::os::is_windows) {
248+
return std::unexpected(std::format(
249+
"host toolchain for build.mcpp ('{}') is only available on Windows hosts", hostSpecText));
250+
}
251+
auto inst = mcpp::toolchain::msvc::detect_installation();
252+
if (!inst) return std::unexpected(mcpp::toolchain::msvc::install_guidance());
253+
auto htc = mcpp::toolchain::detect(
254+
inst->clPath, state.runtimePayload, state.runtimeBindingSnapshot.contractHash);
255+
if (!htc) return std::unexpected(htc.error().message);
256+
mcpp::ui::info("Resolved", std::format(
257+
"host toolchain for build.mcpp: {} → {}", hostSpecText, htc->label()));
258+
state.hostTcCache = std::pair{inst->clPath, *htc};
259+
return std::pair{state.hostTcCache->first, as_host(state.hostTcCache->second)};
260+
}
238261
// Deliberately NO target injection: the spec resolves for the host.
239262
auto pkg = mcpp::toolchain::to_xim_package(*spec);
240263
auto cfgH = state.get_cfg(true);
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
# requires: windows msvc llvm
3+
# `msvc@system` IS LOCATED FOR A BUILD PROGRAM, NEVER INSTALLED (2026.11.7.1).
4+
# On a Windows machine whose default toolchain is `msvc@system`, a project with
5+
# a build program built for a bare cross target resolved the build program's
6+
# host toolchain through the package index and looked for an `msvc@system`
7+
# package there (openkal's 32-bit layout probe, design 2026-11-07 §4.1.3). The
8+
# build program is now compiled by the located Visual Studio, as a native build
9+
# of the same machine is, and its directive reaches the cross build.
10+
set -e
11+
12+
CONF="${MCPP_HOME:-$HOME/.mcpp}/config.toml"
13+
ORIG_DEFAULT=""
14+
if [[ -f "$CONF" ]]; then
15+
ORIG_DEFAULT=$(sed -n '/^\[toolchain\]/,/^\[/p' "$CONF" \
16+
| grep -E '^default[[:space:]]*=' | head -1 | cut -d'"' -f2 || true)
17+
fi
18+
TMP=$(mktemp -d)
19+
restore() {
20+
if [[ -n "$ORIG_DEFAULT" ]]; then
21+
"$MCPP" toolchain default "$ORIG_DEFAULT" >/dev/null 2>&1 || true
22+
fi
23+
rm -rf "$TMP"
24+
}
25+
trap restore EXIT
26+
27+
"$MCPP" toolchain default msvc >/dev/null 2>&1 \
28+
|| { echo "FAIL: msvc@system not selectable"; exit 1; }
29+
30+
mkdir -p "$TMP/probe/src" "$TMP/probe/inc"
31+
cd "$TMP/probe"
32+
cat > mcpp.toml <<'EOF2'
33+
[package]
34+
name = "layout"
35+
version = "0.1.0"
36+
EOF2
37+
cat > build.mcpp <<'EOF2'
38+
#include <cstdio>
39+
int main() {
40+
std::puts("mcpp:include-dir=inc");
41+
std::puts("mcpp:rerun-if-changed=build.mcpp");
42+
return 0;
43+
}
44+
EOF2
45+
cat > inc/layout.h <<'EOF2'
46+
struct pair_layout { unsigned size; unsigned long long stamp; };
47+
EOF2
48+
cat > src/main.cpp <<'EOF2'
49+
#include "layout.h"
50+
static_assert(__builtin_offsetof(pair_layout, stamp) == 8);
51+
extern "C" void _start() { for (;;) {} }
52+
EOF2
53+
54+
out=$("$MCPP" build --target riscv64-none-elf 2>&1) \
55+
|| { echo "FAIL: the cross build with a build program failed:"; echo "$out"; exit 1; }
56+
grep -q "host toolchain for build.mcpp: msvc@system" <<< "$out" \
57+
|| { echo "FAIL: the build program was not compiled by the located msvc@system:"; echo "$out"; exit 1; }
58+
if grep -qi "xim:msvc@system\|msvc@system.*not found in the" <<< "$out"; then
59+
echo "FAIL: msvc@system was looked up as a package:"; echo "$out"; exit 1
60+
fi
61+
echo "OK: msvc@system compiled the build program of a riscv64-none-elf build"

0 commit comments

Comments
 (0)