Commit a557310
committed
feat(windows): give the SDK and the runtime the axes the compiler already had
Implements §1 / §2 / §3 of
.agents/docs/2026-08-16-windows-toolchain-three-axes-design.md.
Three questions were entangled because only one of them had ever been
modelled. The compiler got a version axis in the last round; the headers it
compiles against and the runtime the artifact loads did not.
§2 THE SDK IS BOUND, NOT SEARCHED.
`find_windows_sdk()` scanned — WindowsSdkDir, then the sibling store, then
the conventional roots — for BOTH origins. So a pinned `msvc@<toolset>` was a
pin the environment could overwrite, and two machines could build one
manifest against two SDKs with nothing in the log naming either. It is now
resolved by origin: a managed toolset takes the SDK payload from its own
store and ignores WindowsSdkDir/WindowsSdkVersion *out loud*; `msvc@system`
keeps today's chain, because a machine's things can only be found by looking.
A managed toolset with no SDK payload beside it still falls back to the
machine's — working beats failing — and says so, because that build is no
longer reproducible and only that line records it.
§2.3 `ucrt@<version>` FILLS A SLOT THAT HAS BEEN RESERVED SINCE THE FIELD
EXISTED. `RuntimeBinding::runtimeId`'s comment has documented it from the
start and nothing ever wrote one, so the SDK version never reached
`runtimeContractHash` and two SDKs shared one build cache.
It is NOT isomorphic to `glibc@`, and the comment says so where it will be
read: glibc@ binds a payload (headers + .so, patchelf makes the artifact run
on that copy), ucrt@ declares a floor (ucrtbase.dll is an OS component from
Win10 on; mcpp's windows-sdk payload deliberately carries only half of ucrt
and no redistributable). It is therefore not projected into `libc`. The
`glibc@`-prefix gates become `runtime_provider()` dispatch, so another
provider reads as "no rules here" rather than "no identity".
§3.3 `toolchain-coupled` NOW MEANS SOMETHING ON PE. The refusal said the MSVC
runtime "ships with the OS/redistributable, not with the toolchain" — true of
ucrtbase.dll, false of vcruntime140.dll/msvcp140.dll, which sit in
VC\Redist\MSVC\ inside every toolset. That is the relationship gcc has to
libstdc++.so, so it takes the same contract; PE has no rpath, so the
mechanism is a copy beside the artifact rather than a search path. /MT stays
a degradation, and a genuine one: a static CRT leaves no DLL to couple to.
The DLL set comes from `vc_redist_dir()` — the single criterion that excludes
`debug_nonredist\`, which may not be redistributed. A second, name-shaped
rule here could disagree with it, and disagreeing about that is a licensing
defect rather than a bug.
§1 THE ORIGIN AXIS IS CONTAINED, NOT GENERALISED.
- `gcc@system` / `llvm@system` are refused where they are read, naming both
things the user might have meant. They used to parse and then fail
elsewhere as `xim:gcc@system` → "no such package", sending the reader after
a version that was never going to exist. `msvc@system` is a concession to
one platform, not a capability the other families lack; the family-less
`system` escape hatch is untouched.
- `resolve_managed_msvc()` replaces two hand-written copies of "where does a
managed toolset live, and why is the fetcher's `root` wrong for it" — the
reason existed in only one of them.
- `needs_linux_sysroot_payloads()` replaces two spellings of one rule whose
comment claimed they mirrored each other. They did not: the PE term was
missing from one. Unreachable today, which is how it survived.
- The toolchain resolution order was documented twice, as "3 steps" and "4
steps", naming five of the nine inputs and disagreeing about two. One table
now, keyed to `TcOrigin` enumerators so it cannot quietly stop matching.
`dist::Format` is derived from the target triple before falling back to the
host, which only ADDS answers — and makes a Windows contract assertable on
the Linux runner that reviews most of this.
Tests: 22 new. The SDK-override criterion is the design doc's §6 acceptance
test as a unit test (point WindowsSdkDir elsewhere; the payload SDK must
still win, and the note must say the variable was ignored); the deploy tests
assert reachability twice over, since a copy edge nothing asks for never runs
under explicit ninja goals.1 parent d44bb53 commit a557310
17 files changed
Lines changed: 1204 additions & 107 deletions
File tree
- src
- build
- platform
- toolchain
- tests/unit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
268 | 268 | | |
269 | 269 | | |
270 | 270 | | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
271 | 281 | | |
272 | 282 | | |
273 | 283 | | |
| |||
426 | 436 | | |
427 | 437 | | |
428 | 438 | | |
429 | | - | |
430 | | - | |
431 | | - | |
432 | | - | |
433 | | - | |
434 | | - | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
435 | 476 | | |
436 | 477 | | |
437 | 478 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
80 | 102 | | |
81 | 103 | | |
82 | 104 | | |
| |||
762 | 784 | | |
763 | 785 | | |
764 | 786 | | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
765 | 803 | | |
766 | 804 | | |
767 | 805 | | |
| |||
896 | 934 | | |
897 | 935 | | |
898 | 936 | | |
| 937 | + | |
| 938 | + | |
899 | 939 | | |
900 | 940 | | |
901 | 941 | | |
| |||
910 | 950 | | |
911 | 951 | | |
912 | 952 | | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
913 | 960 | | |
914 | 961 | | |
915 | 962 | | |
916 | 963 | | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
| 982 | + | |
| 983 | + | |
| 984 | + | |
| 985 | + | |
| 986 | + | |
| 987 | + | |
| 988 | + | |
| 989 | + | |
| 990 | + | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
| 997 | + | |
| 998 | + | |
| 999 | + | |
| 1000 | + | |
| 1001 | + | |
| 1002 | + | |
| 1003 | + | |
| 1004 | + | |
| 1005 | + | |
| 1006 | + | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
917 | 1012 | | |
918 | 1013 | | |
919 | 1014 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
449 | 449 | | |
450 | 450 | | |
451 | 451 | | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
452 | 464 | | |
453 | 465 | | |
454 | 466 | | |
| |||
1770 | 1782 | | |
1771 | 1783 | | |
1772 | 1784 | | |
1773 | | - | |
| 1785 | + | |
1774 | 1786 | | |
1775 | 1787 | | |
1776 | 1788 | | |
| |||
1826 | 1838 | | |
1827 | 1839 | | |
1828 | 1840 | | |
1829 | | - | |
1830 | | - | |
| 1841 | + | |
| 1842 | + | |
1831 | 1843 | | |
1832 | 1844 | | |
1833 | 1845 | | |
1834 | 1846 | | |
1835 | | - | |
| 1847 | + | |
1836 | 1848 | | |
1837 | 1849 | | |
1838 | 1850 | | |
| |||
1899 | 1911 | | |
1900 | 1912 | | |
1901 | 1913 | | |
1902 | | - | |
| 1914 | + | |
1903 | 1915 | | |
1904 | 1916 | | |
1905 | 1917 | | |
| |||
0 commit comments