Skip to content

Commit c2fbe08

Browse files
committed
the host-surface table was written from one sweep, and three were missing
The table in docs/20 says it is "the whole of what does not" come from the graph or from xlings. It was derived from a single sweep -- every `fs::which` call -- and three other shapes reach the host without passing through one. Two of them are rows the table owes a reason for, and now has: * A command interpreter. `[hooks]` runs through `run_shell_deadline`, the xlings CLI through `run_streaming_bounded`, and the detached codegen command through the same `/bin/sh` (`cmd.exe` on Windows). A hook is a line the USER wrote in shell syntax; shipping a shell would change the language that line is read in, so what mcpp depends on here is not a tool it could package. * The MSVC toolset and the Windows SDK, reached when a user names `msvc@system` or when a managed toolset has no SDK payload beside it. Not redistributable, the same category as the Apple SDK -- and already handled the way the assembler now is: a managed toolset BINDS its SDK and ignores `WindowsSdkDir` even when set, because a pin the environment can overwrite is not a pin, and the fallback to the machine's SDK carries a note the caller must surface. The third points the other way and is recorded for that reason: `src/runtime/ elf` writes `/usr/lib` and `/usr/lib64` only to MODEL a loader's run-time search, and `mcpp.toolchain.registry` REFUSES a payload descriptor whose `frontend` names `/usr/bin/g++`. The four sweeps are now written into the page, with the exact count each yields, so the next reader checks the list rather than trusting it. The count of `fs::which` call sites is five, and each is a row.
1 parent 9fd2f8a commit c2fbe08

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

docs/20-toolchains.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,30 @@ reason it cannot.
662662
| **the iOS simulator runtime** | `simctl`, through `xim:apple-simulator-tools` | The same. |
663663
| **an assembler (`nasm`)** | the pinned `xim:nasm` first; the host's only when that route could not serve, and **named in the build report** when it is used | An offline machine that already has a usable assembler can still build. It used to be the other way round -- see below. |
664664
| **a C++ compiler on PATH (`$CXX`, else `g++`)** | `mcpp doctor` only | That command's job is to report on the host. The build path sets the compiler from a resolved payload at every branch that reaches the probe, and refuses when the payload cannot be resolved rather than falling through to PATH. |
665+
| **a command interpreter (`/bin/sh`, `cmd.exe` on Windows)** | `run_shell_deadline` for `[hooks]`, `run_streaming_bounded` for the xlings CLI, and the detached codegen command | A hook is a line the USER wrote in shell syntax. Shipping a shell would change the language that line is read in, so the thing mcpp depends on here is not a tool it could package -- it is the host's agreement about what that line means. |
666+
| **the MSVC toolset and the Windows SDK** | `msvc@system`, which a user names; or a managed toolset that has no SDK payload beside it | Not redistributable, the same category as the Apple SDK. A managed toolset BINDS its SDK and ignores `WindowsSdkDir` even when set, because a pin the environment can overwrite is not a pin; the fallback to the machine's SDK works, is not reproducible, and carries a note saying so (`SdkChoice::note`, which the caller must surface). |
667+
668+
That list is meant to be exhaustive, and it is derived rather than remembered.
669+
Four sweeps over `src/` and `modules/` reach it. Every `fs::which` call --
670+
there are exactly five, and each is a row above: `toolchain/probe` for `$CXX`,
671+
`config` and two in `fallback/xlings_binary` for xlings, and `xlings/xlings`
672+
for the assembler. Every string literal rooted at `/usr`, `/bin`, `/opt` or
673+
`/etc`. Every `cmd.exe` and `COMSPEC` use. And every `getenv` naming something
674+
a host toolchain sets -- `CXX`, `SDKROOT`, `WindowsSdkDir`,
675+
`WindowsSdkVersion`, `VSINSTALLDIR`, `MACOSX_DEPLOYMENT_TARGET` (the other
676+
`getenv` reads are mcpp's own `MCPP_*` knobs and `HOME`, which name no host
677+
tool). The first version of this table
678+
was written from the first sweep alone and was missing the last two rows; the
679+
sweeps are written down here so that the next reader checks the list rather
680+
than trusting it.
681+
682+
Two results of those sweeps are worth naming because they point the other way.
683+
`mcpp.toolchain.registry` REFUSES a payload descriptor whose `frontend` names
684+
`/usr/bin/g++` or climbs out with `../` -- and validates it as a string rather
685+
than through `std::filesystem::path`, because `path("/usr/bin/g++")
686+
.is_absolute()` is false on Windows, where the guard therefore did not look
687+
(measured 2026-09-11). And `src/runtime/elf` writes `/usr/lib` and `/usr/lib64`
688+
only to MODEL what a loader will search at run time; mcpp reads nothing there.
665689

666690
Everything else comes from the graph or from xlings, including the ones most
667691
often assumed to be the host's: the compiler and the linker (a payload), the

docs/zh/20-toolchains.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,25 @@ mcpp build --target aarch64-ios-sim # 解析 llvm@22.1.8 + 模拟器 SDK
597597
| **iOS 模拟器运行时** | `simctl`,经 `xim:apple-simulator-tools` | 同上。 |
598598
| **汇编器(`nasm`)** | 先取钉住的 `xim:nasm`;只有那条路服务不了时才取宿主的,**且被用到时在构建报告里点名** | 一台离线而本来就装了可用汇编器的机器仍然能构建。它此前是反着的——见下。 |
599599
| **PATH 上的 C++ 编译器(`$CXX`,否则 `g++`)** | 只有 `mcpp doctor` | 那个命令的职责就是报告宿主。构建那条路在每一个到得了这个探针的分支上都从解析出的载荷设定编译器,载荷解析不了时**拒绝**,而不是落到 PATH。 |
600+
| **命令解释器(`/bin/sh`,Windows 上 `cmd.exe`)** | `[hooks]``run_shell_deadline`,xlings CLI 走 `run_streaming_bounded`,另有分离式 codegen 命令 | 一条 hook 是**用户自己**用 shell 语法写下的那一行。自带一个 shell 会改变那一行被解读所用的语言,所以这里依赖的不是一个它能打包的工具,而是宿主对那一行含义的约定。 |
601+
| **MSVC 工具集与 Windows SDK** | 用户点名 `msvc@system`;或一个受管工具集旁边没有 SDK 载荷 | 不可再分发,与 Apple SDK 同类。受管工具集**绑定**自己的 SDK,即使 `WindowsSdkDir` 被设置也不理会——一个环境能覆盖的钉不是钉;回落到机器自己那份能用、不可复现,因此带一句说明(`SdkChoice::note`,调用方必须把它呈现出来)。 |
602+
603+
这张表意在穷举,而它是**推导出来的**,不是回忆出来的。四次扫描就能重新得到它。每一处
604+
`fs::which` 调用——**恰好五处**,每一处都对应上面的一行:`toolchain/probe``$CXX`
605+
`config``fallback/xlings_binary` 两处取 xlings、`xlings/xlings` 取汇编器。每一个以
606+
`/usr``/bin``/opt``/etc` 为根的字符串字面量。每一处 `cmd.exe``COMSPEC`
607+
以及每一个读取宿主工具链所设变量的 `getenv`——`CXX``SDKROOT``WindowsSdkDir`
608+
`WindowsSdkVersion``VSINSTALLDIR``MACOSX_DEPLOYMENT_TARGET`(其余 `getenv` 读的是
609+
mcpp 自己的 `MCPP_*` 旋钮与 `HOME`,不指向任何宿主工具)。
610+
这张表的第一版只做了第一次扫描,因此缺了最后两行;把扫描方式写在这里,是为了让下一个
611+
读者去****这张表而不是****它。
612+
613+
其中两条扫描结果值得点名,因为它们指向相反的方向。`mcpp.toolchain.registry` **拒绝**
614+
一个 `frontend` 写着 `/usr/bin/g++` 或用 `../` 爬出去的载荷描述符——并且是按**字符串**
615+
校验而不是经 `std::filesystem::path`,因为 `path("/usr/bin/g++").is_absolute()`
616+
Windows 上为假,那道闸恰恰在那台宿主上没有看(2026-09-11 实测)。而 `src/runtime/elf`
617+
里写下 `/usr/lib``/usr/lib64`,只是为了**建模**运行期加载器将要搜索的地方,mcpp
618+
不从那里读任何东西。
600619

601620
其余全部来自图或 xlings,包括最常被当成宿主的那几个:编译器与链接器(载荷)、
602621
C 库与 C++ 运行时(包)、`ninja``patchelf`(xlings),以及 `ar` / `strip` /

0 commit comments

Comments
 (0)