Skip to content

Commit 7d22dc0

Browse files
committed
docs: the four ways a build program names its own tool, compiled before being written down
The page had the three spellings as one trailing comment, which is not an account of them. Section 3.2 now gives each as code on `deps-vcpkg` -- a program, a tree, PATH, and the `vcpkg_root` spelling kept since 0.18.1 -- plus the relative-path rule, deciding from the environment inside the build program, and the fact that a stated choice which fails is refused rather than replaced. Compiling the example as a real build program found a defect in it: a feature makes a module available, not visible, so `tool::root` needs `import mcpp.plugins.tool;` while a plain string assignment does not. The page states that, with the compiler's own words. The refusal text it quotes was copied from a run.
1 parent 1911600 commit 7d22dc0

2 files changed

Lines changed: 88 additions & 2 deletions

File tree

‎.agents/docs/2026-10-01-ecosystem-build-plugin-framework-plan.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@ sha256 `40b9fa16be5628a5d277824f961faa33dadbf84d9520cff9fe2aeb9b0b217ebf`(下载
231231

232232
全部论断都对清单与源码核对过;删掉了一处无来源的「80% 用户」数字,改为陈述事实。
233233

234+
**§3.2 的四种写法是编译过的。** 第一版只用一行注释提了 `tool::on_path()` 与 `tool::root()`,
235+
不成介绍;补成完整示例后把它当成真的构建程序编译,立刻暴露一处文档缺陷:**特性让模块可用,
236+
不等于可见**——写 `tool::root(...)` 必须 `import mcpp.plugins.tool;`,否则编译器报
237+
`declaration of 'root' must be imported from module 'mcpp.plugins.tool' before it is required`;
238+
而赋一个字符串或写 `vcpkg_root` 不需要。页面现在把这条规则写出来了。页面里引的那段拒绝文案
239+
也是实测抄下来的:`consulted: options::vcpkg = root("/opt/vcpkg") (no vcpkg there)`。
240+
234241
## 5. 生态级 review
235242

236243
按「这条机制在生态的每个接缝处是否闭合」来看,而不是按仓库看。

‎docs/tool-sources.md‎

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,91 @@ or because `--format` took another branch — downloads nothing for it.
8181

8282
### 3.2 Name the tool the machine already has
8383

84+
Four spellings, all in `build.mcpp`, none of which downloads the payload. The
85+
example is `deps-vcpkg`, whose option is `options::vcpkg`; every member that
86+
drives a tool has the same shape, with its own option name (section 6).
87+
8488
```cpp
8589
// build.mcpp
86-
mcpp::deps::cmake::options o;
87-
o.cmake = "/usr/bin/cmake"; // or tool::on_path(), or tool::root("/opt/cmake")
90+
import std;
91+
import mcpp;
92+
import mcpp.deps.vcpkg;
93+
import mcpp.plugins.tool; // for `tool::root` and `tool::on_path` below
94+
95+
int main() {
96+
mcpp::deps::vcpkg::options o;
97+
o.libraries = { "fmt", "spdlog" };
98+
99+
// 1. the program itself -- a string assigns, so code written before 0.19.0
100+
// keeps compiling
101+
o.vcpkg = "/opt/vcpkg/vcpkg";
102+
103+
// 2. a tree. Each member states where it looks under a root: `deps-vcpkg`
104+
// expects `vcpkg` directly there, `deps-cmake` looks in `bin` and in
105+
// `CMake.app/Contents/bin`
106+
o.vcpkg = mcpp::plugins::tool::root("/opt/vcpkg");
107+
108+
// 3. the first one on PATH. A fallback is a choice, stated here, rather
109+
// than something a member does quietly
110+
o.vcpkg = mcpp::plugins::tool::on_path();
111+
112+
// 4. the spelling `deps-vcpkg` has had since 0.18.1, still read: the same
113+
// statement as `tool::root(...)`
114+
o.vcpkg_root = "/opt/vcpkg";
115+
116+
return mcpp::deps::vcpkg::use(o) ? 0 : 1;
117+
}
118+
```
119+
120+
A relative path is relative to the package root, which is where a project keeps
121+
a vendored copy:
122+
123+
```cpp
124+
o.vcpkg = mcpp::plugins::tool::root("third_party/vcpkg");
88125
```
89126

127+
`mcpp.plugins.tool` needs no extra feature: `deps-vcpkg` implies `deps`, which
128+
implies `plugins-core`. It does need the `import` above, though -- a feature makes
129+
a module available, not visible. Assigning a plain string (form 1) and
130+
`vcpkg_root` (form 4) need no import; naming `tool::root` or `tool::on_path` does,
131+
and without it the compiler says `declaration of 'root' must be imported from
132+
module 'mcpp.plugins.tool' before it is required`.
133+
134+
**Deciding in the build program, from whatever the machine says.** The choice is
135+
a value, so the decision is ordinary code. Register the variable, and the build
136+
re-plans when it changes:
137+
138+
```cpp
139+
if (const char* r = std::getenv("VCPKG_ROOT"); r && *r) {
140+
mcpp::rerun_if_env_changed("VCPKG_ROOT");
141+
o.vcpkg = mcpp::plugins::tool::root(r); // use it where CI provides one
142+
}
143+
// left default: the ecosystem's xim:vcpkg
144+
```
145+
146+
`mcpp::plugins::toolchain::env("VCPKG_ROOT")` is the same two lines, for a
147+
project that already enables `plugins-toolchain`.
148+
149+
**A stated choice that fails is not replaced by another source.** The member
150+
refuses and names what it consulted, rather than falling back to the payload:
151+
152+
```
153+
warning: my-app: mcpp.deps.vcpkg: no vcpkg.
154+
consulted: options::vcpkg = root("/opt/vcpkg") (no vcpkg there)
155+
…
156+
So this plan installs nothing.
157+
```
158+
159+
That is deliberate. Replacing a decision that was made explicitly, and failed,
160+
with a different source would make "was the one I named actually used" impossible
161+
to answer from the output.
162+
163+
**What makes this avoid the download** is that `deps-vcpkg` declares its payload
164+
`provision = "on-request"`, so the choice is read before anything is provisioned.
165+
For a member whose payload is eager -- `rules-cuda`'s toolkit, which the plan
166+
reads a version out of -- naming the tool in `build.mcpp` does not prevent the
167+
download, and `[xlings.overrides]` is the way out. Section 4.2 is the table.
168+
90169
```
91170
Using cmake (mcpp.deps.cmake) ← /usr/bin/cmake [program · build.mcpp:9]
92171
Finished dev [unoptimized + debuginfo] in 6.4s · program: cmake (mcpp.deps.cmake)

0 commit comments

Comments
 (0)