Skip to content

feat(toolchain): toolchain × target 命名统一 — 二轴身份模型 (0.0.93)#217

Merged
Sunrisepeak merged 10 commits into
mainfrom
feat/toolchain-target-naming-unification
Jul 15, 2026
Merged

feat(toolchain): toolchain × target 命名统一 — 二轴身份模型 (0.0.93)#217
Sunrisepeak merged 10 commits into
mainfrom
feat/toolchain-target-naming-unification

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

一句话

toolchain = family@version(gcc | llvm | msvc)× target = 三段 triple arch-os[-env]:变体(gnu/musl/msvc)进 triple env 段,musl / mingw / cross 不再是工具链名字——mingw-cross 16.1.0 的本体是 gcc@16.1.0 → x86_64-windows-gnu。全部旧拼写永久兼容(compat 层归一 + 单行 note)。

设计文档(含 rustup/Zig/Go/xmake/CMake 行业对照与 9 项决策记录):.agents/docs/2026-07-15-toolchain-target-naming-unification-design.md

核心变更

  • triple.cppm(新):单一 triple 解析器 + 封闭 target 词汇表(tier/pin/defaultStatic 数据列)+ did-you-mean + 版本 pin 集中。cfgpred / abi / model 谓词 / registry 四处平行解析全部收敛;abi 的 os 维 darwinmacos(词汇分叉消灭)。
  • compat.cppm(新):唯一知道旧拼写的文件(musl-gcc / gcc@V-musl / -gcc / mingw / mingw-cross / clang)。xim 分发包名(mingw-cross-gcc 等)不动——"cross" 在分发层合法(musl.cc -cross 后缀 / Debian 包名先例)。
  • ToolchainSpec v2 + payload 数据表:五处 if 特例链(to_xim_package/display_label/matches_default_toolchain/frontend_candidates/available host 分流)收敛为一张 (family, target, host)→xim 映射 + 反向 identify;display_label/matches_default_toolchain 删除。
  • canonical triple(D1):x86_64-windows-gnu 为正典;x86_64-w64-mingw32、4 段 Rust 拼写为永久别名,归一进同一 target/<canonical>/ 目录(同一缓存,实测 alias 二跑 0.07s 全命中)。
  • --target 封闭词汇表校验:typo 硬错 + did-you-mean,根治「打错字静默编成宿主产物」;[target.X] 显式节为自定义 triple 逃生舱;planned 档报 not-yet-supported。两条硬编码约定改词汇表数据行。
  • CLI 单名词 + --target 选项(D4):toolchain install [gcc 16] --target <triple>(family 可省→约定 pin)/ default gcc@16 --target <triple>(默认变 pair,持久化 default+default_target)/ remove … --target;主路径 mcpp build --target <triple> 自动装链零仪式。
  • [build] target 新键(≙ cargo build.target):优先级 --target flag > [build] target > 全局 default_target > host。
  • toolchain list 两轴重排:Toolchains + Targets(installed/available/planned)两块;修版本字典序 bug(9.4.0 不再排最前);README 平台表从词汇表重画(修正 MSVC 仍标 planned 的错误信息)。

验证

  • 单测 35/35(新增 triple/compat 套件;registry/dialect/msvc 迁移 v2)
  • e2e 本机全量:102 过 / 3 环境性失败(22/54/62,与既有基线一致)/ 5 skip(macos/msvc/windows 能力);新增 103(typo/planned/逃生舱/[build] target/别名同目录),102 加双拼写断言(canonical + x86_64-w64-mingw32 同目录)
  • 本机真跑:双拼写交叉构建同 Resolved 行同缓存;PE32+ wine 真跑;musl 静态链解析 x86_64-linux-musl-g++;typo did-you-mean;install --target 省 family;default pair 持久化与 * 标记
  • 兼容:存量 config default = "mingw-cross@16.1.0" 直接被识别为 (gcc@16.1.0, x86_64-windows-gnu) 并正确打星;cross-build-test 的 toolchain install mingw-cross 16.1.0 原样保留作为 CI 内的别名回归覆盖

兼容性

无 breaking:全部旧拼写(CLI/manifest/config)永久解析;target/ 目录对 mingw 从 x86_64-w64-mingw32 改名 x86_64-windows-gnu、macOS 从 dumpmachine 串改 aarch64-macos(均为构建缓存,自动重建)。

… 1/8)

Canonical arch-os[-env] triple language (Zig-style, no vendor) + lenient
parse of GNU/LLVM/Apple alias spellings + closed known-target vocabulary
with tier/pin/defaultStatic columns + did-you-mean + centralized version
pins. Pure addition; no consumers yet.

Design: .agents/docs/2026-07-15-toolchain-target-naming-unification-design.md §4.1/§4.2/§4.4/§4.6
…tep 2/8)

The only file that knows pre-0.0.93 spellings: musl-gcc@V / gcc@V-musl /
<triple>-gcc@V / mingw@V / mingw-cross@V / clang@V all normalize to the
two-axis (family, version, target) identity, with a once-per-process
canonical hint. Aliases are permanent — this is a pointer, not a
deprecation. Pure addition; wired into registry in step 3.

Design: §4.7/§6.2
… list (step 3/8)

Identity is now (family ∈ gcc|llvm|msvc, version, target Triple). The five
if-chains (to_xim_package / display_label / matches_default_toolchain /
frontend_candidates_for / available_toolchain_indexes host-split) collapse
into one payload mapping + identify_xim_payload reverse mapping;
display_label and matches_default_toolchain are deleted — display renders
from structure, default matching is spec equality. mingw/mingw-cross are
no longer families: gcc targeting x86_64-windows-gnu, host-split at the
distribution layer only (the mingw-on-Linux host gate is gone by design —
that spelling now installs the cross payload).

toolchain list becomes the two-block rustup shape (Toolchains axis +
Targets axis with tier/status incl. planned rows) and fixes the
lexicographic version sort (9.4.0 no longer sorts above 15.1.0). Default
is persisted as the pair [toolchain].default (family@version) +
[toolchain].default_target; legacy combined spellings in existing configs
keep parsing via compat (write path: boundary-safe key writer so
'default' never clobbers 'default_target').

Unit: 35/35 green (registry/dialect/msvc suites migrated to v2).
…switch + --target validation (steps 4-5/8)

All triple interpretation now goes through triple.cppm: cfgpred::context_for
(vocab = the canonical triple vocab; alias spellings evaluate identically),
abi_profile (os says 'macos' — the darwin/macos vocabulary fork is dead;
darwin/arm64 accepted as constraint aliases), model.cppm is_*_target
predicates (spelling-independent, substring fallback for escape-hatch
triples), plus spelling-independent [target.X] key lookup and bare-triple
cfg matching.

Canonical switch (D1): target/ output dirs are named by canonical triple —
the Windows PE cross now lands in target/x86_64-windows-gnu (both spellings,
one cache). --target is validated against the known-target vocabulary:
typos hard-error with did-you-mean instead of silently building for the
host; explicit [target.X] sections remain the custom-triple escape hatch;
planned-tier targets error until a toolchain ships. The two hardcoded
conventions (*-musl, x86_64-w64-mingw32) are now the vocabulary table's
pin/defaultStatic columns.

Verified locally: dual-spelling cross build → same Resolved line, same
canonical dir, alias run 100% cache hit; PE32+ runs under wine; musl static
resolves x86_64-linux-musl-g++; typo produces did-you-mean. e2e 102 now
asserts both spellings; ci-linux musl grep updated to canonical rendering.
…] target (step 6/8)

Single-noun CLI (design D4): no 'mcpp target' subcommand — the existing
toolchain verbs take an optional --target <triple>. install may omit the
family entirely (--target x86_64-windows-gnu → the target's convention
pin); default persists the PAIR as [toolchain].default + default_target;
remove targets a specific payload. New [build] target manifest key
(≙ cargo build.target) + global default_target complete the target-axis
default chain: --target flag > [build] target > default_target > host.
'mcpp run' positional help clarified to 'Binary name' (it never was a
triple).

e2e 103: typo did-you-mean, planned-tier hard error, [target.X] custom-
triple escape hatch, [build] target dir selection, 4-segment alias →
canonical dir. All verified green locally.
…ite + 0.0.93 (step 7/8)

README (en/zh): platform support redrawn as the two-axis model — hosts +
target vocabulary table (mirrors triple.cppm's kKnownTargets; fixes MSVC
still marked 'planned' though 0.0.90 shipped native cl.exe builds, and adds
the missing windows-gnu rows). docs/03 (en/zh): identity-model section,
--target install forms, default pair, two-block list example, MinGW
rewritten as a target (x86_64-windows-gnu — same command from Windows or
Linux), targets & cross section (validation/escape hatch/[build] target);
fixes the stale 'Linux defaults to gcc@15.1.0-musl' claim (arch-aware
gcc@16.1.0 glibc on x86_64 since the first-run default changed). docs/05:
[build] target key. docs/08: two-axis resolution + add-a-target SOP row.
CHANGELOG 0.0.93 + version bump.
…r Linux hosts)

On macOS/Windows a linux-musl target is cross by definition, so
to_xim_package resolves the triple-named package — caught by ci-macos.
… 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).
@Sunrisepeak Sunrisepeak merged commit 6d8083a into main Jul 15, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant