-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcpp.toml
More file actions
318 lines (291 loc) · 15.2 KB
/
Copy pathmcpp.toml
File metadata and controls
318 lines (291 loc) · 15.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
[package]
name = "plugins"
namespace = "mcpp"
version = "0.4.0"
description = "Official mcpp build plugins: rule packages under mcpp.rules.*, build-time utilities under mcpp.tools.*, each member selected by a feature"
license = "Apache-2.0"
authors = ["mcpp-community"]
repo = "https://github.com/mcpp-community/mcpp-plugins"
[language]
standard = "c++23"
modules = true
import_std = true
# The lib root alone is compiled for a consumer that activates no feature. Each
# member of the collection is a module interface unit that one feature adds to
# the source set; mcpp compiles every interface unit among the resolved
# sources as a host module under the name the unit declares (2026.9.5.3+).
[build]
# THE LIB ROOT ALONE, AND `src/declare.cppm` BEHIND A FEATURE.
#
# The two units divide by what they may import:
#
# src/plugins.cppm `mcpp.plugins.surface`, importing only `std`, so the
# same code compiles into `mcpp-embed` -- an ordinary
# program, which is what lets the generation be an ACTION
# and a payload be that action's declared input
# src/declare.cppm the build-program half: `mcpp::action`, `mcpp::generated`
# and the decision of how the generation reaches the graph
#
# The second one imports `mcpp`, which exists only inside a build program, so
# listing it here would break the ORDINARY build of this package -- the build
# that produces the tool. `[features.surface]` scopes it to the consumers that
# have a build program, and every member implies it.
#
# It also needs mcpp 2026.9.8.1: before that release a package's host modules
# were ordered by PATH, so `rules/spirv.cppm` was compiled before
# `src/declare.cppm` and importing it failed with "failed to read compiled
# module". They are ordered by their import graph now.
sources = ["src/plugins.cppm"]
# EACH RULE STATES WHAT IT COMPILES AND HOW TO REACH IT (mcpp 2026.9.7.1+).
#
# `device_extensions` says which device sources this rule compiles;
# `rule_module` says which module a consumer's build program imports to reach
# it. Two things follow, and neither puts this package's name inside mcpp:
#
# 1. A consumer that activates the feature gets those extensions classified
# as device sources, so a NEW device language costs no engine change.
# Slang measured the alternative: adding `.slang` to the engine's built-in
# table cost an mcpp release and a version bump in this file's CI before
# the rule could route one file.
# 2. `host-module = true` is implied, because a feature naming a rule module
# has already said that is the only way to use it. A consumer writes
# `features = ["rules-spirv"]` and nothing else.
#
# The feature is still requested BY NAME. An earlier revision activated it from
# the extensions a project's sources happened to carry; that was withdrawn
# because two packages may claim one extension -- a third-party CUDA rule is a
# thing someone will write -- and because a derived feature set is information
# a manifest no longer states.
#
# A consumer that outgrows the generated build program writes its own
# `build.mcpp`, which is the same program with edits. Each layer overrides the
# one above it; none is a different mechanism.
[features]
default = []
# The build-program half of the surface. Not a member a consumer names: every
# member that embeds a payload implies it, and a consumer that activates none
# of them compiles neither this nor anything that imports `mcpp`.
[features.surface]
sources = ["src/declare.cppm"]
[features.rules-ascendc]
sources = ["rules/ascendc.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.ascendc"
device_extensions = [".asc", ".cce"]
[features.rules-cuda]
sources = ["rules/cuda.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.cuda"
device_extensions = [".cu"]
[features.rules-hip]
sources = ["rules/hip.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.hip"
device_extensions = [".hip"]
[features.rules-slang]
sources = ["rules/slang.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.slang"
device_extensions = [".slang"]
# `.glsl` and `.hlsl` carry no stage and are claimed on purpose: the rule
# refuses them by name and says which extensions do carry one, which is a better
# message than the engine's "no rule compiles it".
[features.rules-spirv]
sources = ["rules/spirv.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.spirv"
device_extensions = [".comp", ".vert", ".frag", ".geom", ".tesc", ".tese",
".mesh", ".task", ".rgen", ".rint", ".rahit", ".rchit",
".rmiss", ".rcall", ".glsl", ".hlsl"]
[features.rules-sycl]
sources = ["rules/sycl.cppm"]
implies = ["surface"]
rule_module = "mcpp.rules.sycl"
device_extensions = [".sycl"]
# NOT device rules: these embed or declare things a project already has, so they
# claim no extension and name no rule module. A consumer calls them from its own
# `build.mcpp`.
[features.tools-embed]
sources = ["tools/embed.cppm"]
implies = ["surface"]
[features.tools-island]
sources = ["tools/island.cppm"]
implies = ["surface"]
# ── The environment each rule needs (mcpp 2026.9.6.6+) ──────────────────────
#
# A RULE OWNS THE LIST OF PACKAGES IT DRIVES. It is the code that runs the
# compiler, reads the headers and puts the library directory on the link line,
# so "which package, and which version of it" is its knowledge. Before this, a
# project repeated the list in its own `[xlings.workspace]` -- a copy that goes
# stale silently, because the rule moves and the projects do not.
#
# TWO GATES, AND BOTH MUST OPEN BEFORE A BYTE IS DOWNLOADED. The feature says
# whether this rule is wanted at all; `cfg(accelerator = ...)` says whether this
# particular build compiles for the device. A CPU-only build of a project that
# depends on this package with `features = ["rules-cuda"]` opens the first and
# not the second, and installs nothing -- which is the build CI runs, and the
# one a multi-gigabyte vendor toolkit would otherwise make the most expensive.
#
# THE SHAPE OF EACH DEFAULT IS A JUDGEMENT ABOUT COUPLING, not a style.
#
# - An EXACT version where the payload's version is coupled to something the
# rule cannot see. A CUDA runtime must not be newer than the driver it will
# meet: the 12.9 line reaches every driver from r525 onward, and the 13.x
# line raises that to r580. That is a property of the consumer's machines,
# so the rule offers a line it has verified and the project moves it.
# - A FLOOR (`>=`) where no such coupling exists and newer is simply newer.
#
# mcpp reads the difference: a bare version is a CHOICE, so a project pinning a
# different one wins and is reported; a `>=` is a REQUIREMENT, so a project
# pinning below it is refused naming both sides. See "One package, one version"
# in mcpp's docs/05.
#
# WHAT IS NOT HERE: anything the produced PROGRAM chooses to run on. A Vulkan
# ICD (`xim:mesa-lavapipe`) is a device, not a build tool, and a rule that
# declared one would force a software renderer onto consumers that have a GPU.
# The rule declares what it needs to COMPILE; the project declares what it needs
# to RUN. The runtime adapters (`compat:cuda-runtime`, `compat:sycl-runtime`,
# `compat:vulkan-runtime`) stay in the project for the same reason and for a
# second one: this package is a `[build-dependencies]` edge, so its own
# `[dependencies]` deliberately do not reach the consumer's target.
[target.'cfg(accelerator = "cuda")'.feature-xlings.rules-cuda]
"xim:cuda-nvcc" = "12.9.86"
"xim:cuda-cudart" = "12.9.79"
# clang's CUDA wrapper includes a cuRAND header for every device unit, and that
# header includes <nv/target> from CCCL. Neither is called by an ordinary
# kernel; on a developer machine the host's /usr/include supplied them silently.
"xim:libcurand" = "10.3.10.19"
"xim:cuda-cccl" = "12.9.27"
# The driver sentinel is Linux-only, and the OS goes in the PREDICATE rather
# than in the value: a value carrying platform keys under an already-predicated
# table would state the condition twice and let the two disagree.
[target.'cfg(all(accelerator = "cuda", linux))'.feature-xlings.rules-cuda]
"xim:libcuda-host-link" = "0.0.1"
# HIP on the NVIDIA platform is a header layer over the CUDA runtime, so this
# list is the CUDA one plus the header package HIP includes at its second line.
[target.'cfg(accelerator = "hip")'.feature-xlings.rules-hip]
"xim:hip-nvidia" = "7.2.4"
"xim:cuda-nvcc" = "12.9.86"
"xim:cuda-cudart" = "12.9.79"
"xim:libcurand" = "10.3.10.19"
"xim:cuda-cccl" = "12.9.27"
"xim:cuda-profiler-api" = "12.9.79"
[target.'cfg(all(accelerator = "hip", linux))'.feature-xlings.rules-hip]
"xim:libcuda-host-link" = "0.0.1"
# A floor: the compiler's version is not coupled to any driver, and the rule
# needs `-fsycl-link` to behave as it does from 7.1.0 onward.
[target.'cfg(accelerator = "sycl")'.feature-xlings.rules-sycl]
"xim:dpcpp" = ">=7.1.0"
# THE SECOND COMPILER MUST BE TOLD WHERE THE C LIBRARY IS. dpcpp's clang is not
# configured with this ecosystem's glibc, so without these its device units
# compile against the host's -- which no command line shows, because an implicit
# include search never appears on one.
[target.'cfg(all(accelerator = "sycl", linux))'.feature-xlings.rules-sycl]
"xim:gcc" = "15.1.0"
"xim:glibc" = ""
"xim:linux-headers" = ""
# Only when the SYCL build actually names an NVIDIA target. `accelerator` is a
# SET, so this is a conjunction of two membership tests rather than a
# contradiction -- and without it every SYCL build would download a CUDA
# toolkit it may have no target for.
#
# `linux` is part of the predicate for a reason that is measured rather than
# stylistic: upstream does not build the CUDA plugin for Windows, and the
# published Windows asset carries Level Zero and OpenCL adapters only. The rule
# refuses that combination on that host, and a refusal that arrives after a
# multi-gigabyte download is a worse refusal -- provisioning runs before the
# rule does.
[target.'cfg(all(accelerator = "sycl", accelerator = "cuda", linux))'.feature-xlings.rules-sycl]
"xim:cuda-nvcc" = "12.9.86"
# ONE COMPILER PER PLATFORM, AND NOT THE SAME ONE EVERYWHERE.
#
# This rule drives both reference compilers and writes the C declaration itself
# on the glslc route, so which one is present is not a difference a consumer
# sees. That is what makes cross-platform parity affordable: it is provided by
# the rule's ability to CHOOSE, not by publishing one compiler three times.
#
# Linux keeps `xim:glslang`, so nothing about an existing Linux build changes.
# macOS and Windows take `xim:shaderc`, which is the compiler this ecosystem
# publishes for them -- glslang has no upstream binary for either, and building
# it three times buys nothing glslc does not already give.
#
# Declaring both on one platform would install both and use one, so each block
# names exactly the compiler that platform will run.
[target.'cfg(all(accelerator = "vulkan", linux))'.feature-xlings.rules-spirv]
"xim:glslang" = ">=15.1.0"
# A FLOOR AGAIN, NOW THAT THE ENGINE ESCAPES THE ARGUMENT FOR cmd.exe.
#
# These two were an exact version for one release, and the reason was the
# engine's command line rather than the package. mcpp hands its provisioning
# request to xlings as a JSON argument on a shell command line; on Windows that
# line is parsed by cmd.exe, whose quoting rules are not the ones the JSON is
# escaped for. The `\"` sequences left cmd's quote state OFF by the time it
# reached the `>` in a version constraint, so the `>` was read as a REDIRECTION.
# Measured on windows-2022 with mcpp 2026.9.6.6:
#
# Provisioning [xlings.workspace] entries declared by dependencies
# (xim:shaderc@>=2026.3)
# The filename, directory name, or volume label syntax is incorrect.
# error: ... xlings exited 1
#
# -- cmd's own message about an unusable redirection target, arriving as a
# packaging failure. No declaration reachable on Windows had carried a `>`
# before, which is why the whole `>=` shape had never been exercised there.
#
# `mcpp.platform.shell` now escapes for both parsers, and MCPP_VERSION below
# pins the release that carries it, so the constraint these entries were always
# meant to state is expressible again.
[target.'cfg(all(accelerator = "vulkan", macos))'.feature-xlings.rules-spirv]
"xim:shaderc" = ">=2026.3"
[target.'cfg(all(accelerator = "vulkan", windows))'.feature-xlings.rules-spirv]
"xim:shaderc" = ">=2026.3"
# ONE TABLE FOR ALL THREE PLATFORMS, WHICH `rules-spirv` COULD NOT HAVE.
#
# `xim:slang` ships slangc for linux, macosx and windows and for both x86_64 and
# aarch64, so this rule does not change compilers by platform the way the GLSL
# rule does, and one table says everything.
#
# A FLOOR, WHICH IS WHAT THIS PACKAGE'S RULE FOR THE SHAPE ASKS FOR: Slang's
# version is coupled to no driver, so newer is simply newer.
#
# It is written once rather than per platform because the engine escapes the
# constraint for cmd.exe (see the note above), so the `>` survives on all three.
# An earlier revision of this file pinned it exactly on every platform to avoid
# that defect, and rejected the obvious alternative of `>=` on the two platforms
# that tolerated it: a floor holding on two of three would resolve DIFFERENT
# payloads for one project depending on the machine that built it, which is how
# a defect comes to exist on one operating system only.
[target.'cfg(accelerator = "vulkan")'.feature-xlings.rules-slang]
"xim:slang" = ">=2026.14.1"
# 8.5.0 is a real floor rather than a preference: the mixed-mode object -- the
# one carrying both the device binary and a host-callable launcher, which is
# what lets it join an ordinary link -- and the 38 SoC simulators are what this
# rule drives, and they are present from that version onward.
[target.'cfg(accelerator = "ascend")'.feature-xlings.rules-ascendc]
"xim:cann-toolkit" = ">=8.5.0"
[targets.plugins]
kind = "lib"
# mcpp-embed -- the surface generator as a PROGRAM, so that the graph can invoke
# it and the payloads it embeds can be declared inputs of that invocation.
#
# WHY THE TOOL IS BUILT FROM THIS PACKAGE RATHER THAN PUBLISHED SEPARATELY.
# docs/05 section 2.14 states the reason, and it is not convenience: "The tool's
# version IS the dependency's version, so a `protoc` that does not match its
# runtime is not expressible. This is the problem with packaging the tool
# separately, and it is the failure mode that bites at run time rather than
# compile time." The generator and the declarations it writes are one decision;
# a separately published payload would let them drift by one release.
#
# A consumer asks for it on the same edge that asks for the rules:
#
# [build-dependencies.mcpp]
# plugins = { version = "0.4.0", features = ["rules-spirv"],
# host-module = true, tools = ["mcpp-embed"] }
#
# Only under `storage::object`. The default storage compiles the payload in as
# generated source and needs no program, so nothing is built unless someone
# asks -- and a rule that needs it and cannot find it refuses, naming the line
# to add.
[targets.mcpp-embed]
kind = "bin"
main = "tools/embed_main.cpp"