Skip to content

Commit fb3a259

Browse files
committed
docs: the ways to name a tool are whole build programs, each compiled
The chapter stated four spellings by assigning the same option four times in one `main`, which is an index, not an example -- no project writes that. Each way is now a complete `build.mcpp`: a program path with deps-vcpkg, a tree with deps-cmake, PATH with rules-spirv, a toolkit root with rules-cuda, a plain root with rules-qt, and the vendored-plus-environment program with deps-vcpkg. Every one of them was compiled as a real build program before being written down, which is also how the missing `import mcpp.plugins.tool;` was found earlier. The table in 3.6 stays what it is: an index of which option each member reads and what it looks for under a root.
1 parent 7f5f0ed commit fb3a259

1 file changed

Lines changed: 116 additions & 35 deletions

File tree

‎docs/tool-sources.md‎

Lines changed: 116 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -67,50 +67,113 @@ This is the chapter for a project that wants its own tool rather than the one th
6767
plugin declares, stated in the build program and nowhere else -- no
6868
`[xlings.overrides]`, no environment variable. Chapter 4 covers those.
6969

70-
### 3.1 The four spellings
70+
### 3.1 Four ways, each a whole build program
7171

72-
Four spellings, all in `build.mcpp`, none of which downloads the payload. The
73-
example is `deps-vcpkg`, whose option is `options::vcpkg`; every member that
74-
drives a tool has the same shape, with its own option name (section 3.6).
72+
Every example here is a complete `build.mcpp` that compiles. A member reads one
73+
option (section 3.6 is the index); what differs is what the project states.
74+
75+
**A program this machine already has.** The plainest form: a string assigns to the
76+
option, so a project written before 0.19.0 keeps compiling unchanged.
7577

7678
```cpp
77-
// build.mcpp
79+
// build.mcpp -- features = ["deps-vcpkg"]
7880
import std;
7981
import mcpp;
8082
import mcpp.deps.vcpkg;
81-
import mcpp.plugins.tool; // for `tool::root` and `tool::on_path` below
8283

8384
int main() {
8485
mcpp::deps::vcpkg::options o;
85-
o.libraries = { "fmt", "spdlog" };
86+
o.libraries = { "fmt" };
87+
o.vcpkg = "/opt/vcpkg/vcpkg";
88+
return mcpp::deps::vcpkg::use(o) ? 0 : 1;
89+
}
90+
```
8691

87-
// 1. the program itself -- a string assigns, so code written before 0.19.0
88-
// keeps compiling
89-
o.vcpkg = "/opt/vcpkg/vcpkg";
92+
**A tree, with the member looking inside it.** `tool::root` states a directory and
93+
lets the member apply its own layout: `deps-cmake` looks for `cmake` in `bin` and
94+
in `CMake.app/Contents/bin`, `deps-vcpkg` directly under the root.
9095

91-
// 2. a tree. Each member states where it looks under a root: `deps-vcpkg`
92-
// expects `vcpkg` directly there, `deps-cmake` looks in `bin` and in
93-
// `CMake.app/Contents/bin`
94-
o.vcpkg = mcpp::plugins::tool::root("/opt/vcpkg");
96+
```cpp
97+
// build.mcpp -- features = ["deps-cmake"]
98+
import std;
99+
import mcpp;
100+
import mcpp.deps.cmake;
101+
import mcpp.plugins.tool;
95102

96-
// 3. the first one on PATH. A fallback is a choice, stated here, rather
97-
// than something a member does quietly
98-
o.vcpkg = mcpp::plugins::tool::on_path();
103+
int main() {
104+
mcpp::deps::cmake::options o;
105+
o.source = "greet";
106+
o.libraries = { "greet" };
107+
o.cmake = mcpp::plugins::tool::root("/opt/cmake-3.31.6");
108+
return mcpp::deps::cmake::use(o) ? 0 : 1;
109+
}
110+
```
99111

100-
// 4. the spelling `deps-vcpkg` has had since 0.18.1, still read: the same
101-
// statement as `tool::root(...)`
102-
o.vcpkg_root = "/opt/vcpkg";
112+
**Whatever is on PATH, as a stated choice.** A member never falls back to PATH on
113+
its own; `tool::on_path()` is how a project asks for that, so the log records that
114+
the build depends on the machine.
103115

104-
return mcpp::deps::vcpkg::use(o) ? 0 : 1;
116+
```cpp
117+
// build.mcpp -- features = ["rules-spirv"]
118+
import std;
119+
import mcpp;
120+
import mcpp.rules.spirv;
121+
import mcpp.plugins.tool;
122+
123+
int main() {
124+
mcpp::rules::spirv::options o;
125+
o.compiler = mcpp::plugins::tool::on_path();
126+
return mcpp::rules::spirv::compile(o) ? 0 : 1;
105127
}
106128
```
107129

108-
`mcpp.plugins.tool` needs no extra feature: `deps-vcpkg` implies `deps`, which
109-
implies `plugins-core`. It does need the `import` above, though -- a feature makes
110-
a module available, not visible. Assigning a plain string (form 1) and
111-
`vcpkg_root` (form 4) need no import; naming `tool::root` or `tool::on_path` does,
112-
and without it the compiler says `declaration of 'root' must be imported from
113-
module 'mcpp.plugins.tool' before it is required`.
130+
**A root that is the whole toolkit.** `rules-cuda` takes one tree holding nvcc, the
131+
runtime, CCCL and cuRAND, rather than a program:
132+
133+
```cpp
134+
// build.mcpp -- features = ["rules-cuda"]
135+
import std;
136+
import mcpp;
137+
import mcpp.rules.cuda;
138+
import mcpp.plugins.tool;
139+
140+
int main() {
141+
mcpp::rules::cuda::options o;
142+
o.toolkit = mcpp::plugins::tool::root("/usr/local/cuda-12.9");
143+
return mcpp::rules::cuda::compile(o) ? 0 : 1;
144+
}
145+
```
146+
147+
`rules-qt`, `rules-ascendc` and `dist-apk` state a root with a plain string,
148+
because their option has always been a directory:
149+
150+
```cpp
151+
// build.mcpp -- features = ["rules-qt"]
152+
import std;
153+
import mcpp;
154+
import mcpp.rules.qt;
155+
156+
int main() {
157+
mcpp::rules::qt::options o;
158+
o.modules = { "Core", "Widgets" };
159+
o.root = "/opt/Qt/6.11.1/gcc_64";
160+
return mcpp::rules::qt::compile(o) ? 0 : 1;
161+
}
162+
```
163+
164+
**The spelling `deps-vcpkg` has had since 0.18.1** states the same thing as
165+
`tool::root`, and is still read:
166+
167+
```cpp
168+
o.vcpkg_root = "/opt/vcpkg";
169+
```
170+
171+
`mcpp.plugins.tool` needs no extra feature: each `deps-*` and `rules-*` feature
172+
implies `plugins-core`. It does need the `import` shown above, though -- a feature
173+
makes a module available, not visible. Assigning a plain string needs no import;
174+
naming `tool::root` or `tool::on_path` does, and without it the compiler says
175+
`declaration of 'root' must be imported from module 'mcpp.plugins.tool' before it
176+
is required`.
114177

115178
### 3.2 Where a relative path points
116179

@@ -123,19 +186,37 @@ o.vcpkg = mcpp::plugins::tool::root("third_party/vcpkg");
123186

124187
### 3.3 Deciding inside the build program
125188

126-
**The choice is a value, so the decision is ordinary code.** Register the variable
127-
that informs it, and the build re-plans when it changes:
189+
**The choice is a value, so the decision is ordinary code.** A project that ships a
190+
vendored copy and also honours what CI provides writes both, and registers the
191+
variable so the build re-plans when it changes:
128192

129193
```cpp
130-
if (const char* r = std::getenv("VCPKG_ROOT"); r && *r) {
131-
mcpp::rerun_if_env_changed("VCPKG_ROOT");
132-
o.vcpkg = mcpp::plugins::tool::root(r); // use it where CI provides one
194+
// build.mcpp -- features = ["deps-vcpkg"]
195+
import std;
196+
import mcpp;
197+
import mcpp.deps.vcpkg;
198+
import mcpp.plugins.tool;
199+
200+
int main() {
201+
mcpp::deps::vcpkg::options o;
202+
o.libraries = { "fmt" };
203+
204+
// the copy in the repository, relative to the package root
205+
o.vcpkg = mcpp::plugins::tool::root("third_party/vcpkg");
206+
207+
// and the machine's own, where CI provides one
208+
if (const char* r = std::getenv("VCPKG_ROOT"); r && *r) {
209+
mcpp::rerun_if_env_changed("VCPKG_ROOT");
210+
o.vcpkg = mcpp::plugins::tool::root(r);
211+
}
212+
return mcpp::deps::vcpkg::use(o) ? 0 : 1;
133213
}
134-
// left default: the ecosystem's xim:vcpkg
135214
```
136215

137-
`mcpp::plugins::toolchain::env("VCPKG_ROOT")` is the same two lines, for a
138-
project that already enables `plugins-toolchain`.
216+
Leaving the option untouched in some branch is also a decision: that branch takes
217+
the ecosystem's `xim:vcpkg`. `mcpp::plugins::toolchain::env("VCPKG_ROOT")` is the
218+
same two lines as the `getenv` pair, for a project that already enables
219+
`plugins-toolchain`.
139220

140221
### 3.4 A stated choice that fails is not replaced
141222

0 commit comments

Comments
 (0)