0.2.4: every rule brings its own environment - #8
Merged
Conversation
A project that wanted a device island wrote two things: the rule edge, and
the rule's own package list repeated with exact pins. The second is a copy
that goes stale silently -- the rule moves and the projects do not.
Each rule now declares the payloads it drives, under the feature that
selects it and the accelerator it serves, so a project writes one edge:
[build-dependencies.mcpp]
plugins = { version = "0.2.4", features = ["rules-cuda"], host-module = true }
Two gates, and both must open before a byte is downloaded: the feature says
whether the rule is wanted, the selector says whether this build compiles
for the device. A CPU-only build opens neither.
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, so the 12.9 line is offered and a project with newer machines names
13.x itself. A floor (`>=`) where no such coupling exists: glslang, dpcpp,
the CANN toolkit. mcpp reads the difference: a bare version is a choice and
a project pinning another wins; a `>=` is a requirement and a pin below it
is refused naming both sides.
Not moved: anything the produced PROGRAM chooses to run on. A Vulkan ICD is
a device, and a rule declaring one would force a software renderer onto
consumers that have a GPU. The runtime adapters stay in the project for that
reason and because this package is a [build-dependencies] edge.
Two fixtures declared fewer accelerators than their globs name: on the
NVIDIA platform HIP and SYCL both compile THROUGH the CUDA back end, so
`cuda` belongs in their `[package] accelerators`. mcpp 2026.9.6.5 refuses
that mismatch; the CI pin was older, so only raising it surfaced them.
The floor for every rule is now 2026.9.6.6, the release in which a payload a
dependency declared is both installed and answerable.
新加的那步在一次**构建成功**的运行上红了:`rm -rf ~/.mcpp/provisioned` 什么都 没删,于是前面几步写下的 stamp 还在,供给那一行不再打印。 已发布的 mcpp 是自包含的:没有 `MCPP_HOME` 时它的 home 就是解开的那个 tarball 目录。所以 `~/.mcpp` 从来不是它的 home——而这个 job 的 cache 正是 `path: ~/.mcpp`, 它保存和恢复的是一个 mcpp 从不碰的目录。**每一次运行都是冷的**,而下面那 90 分钟 的预算正是按冷的算的。 两处一起改: * `MCPP_HOME: /home/runner/.mcpp` 进 env。mcpp 自己的 ci-linux.yml 为同一个理由 钉了它并写明「so the cache keys restore into the same path」。 * 判据不再假定路径,改成问 `mcpp self env`。⚠️ 本地预演之所以通过,是因为**开发构建被排除在自包含模式之外**,它确实用 `~/.mcpp` —— 预演与 CI 清的是两个不同的目录。判据的对象在两个环境里不是同一个。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes for a project
Before:
After:
The second block was the rule's own knowledge, repeated by everyone who used
it — a copy that goes stale silently, because the rule moves and the projects
do not. Each rule now declares it, under the feature that selects the rule and
the accelerator it serves:
Two gates, and both must open before a byte is downloaded. The feature says
whether the rule is wanted; the selector says whether this build compiles for
the device. A CPU-only build of the same project opens neither.
All five rules, with no exception. "Sometimes you have to supply it yourself"
is a rule nothing can state precisely enough to be useful.
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, and the 12.9 line reaches every driver from r525 onward
where 13.x raises that to r580. A floor (
>=) where no such couplingexists: glslang, dpcpp, the CANN toolkit.
mcpp reads the difference. A bare version is a choice, so a project pinning a
different one wins and the override is reported; a
>=is a requirement, soa project pinning below it is refused naming both sides. Either way one version
is installed — which is what mcpp 2026.9.6.6 makes true, and why that is the
floor for every rule here.
Overriding is one line in the project:
What is deliberately not moved
Anything the produced program chooses to run on.
xim:mesa-lavapipeis adevice, and a rule declaring one would force a software renderer onto consumers
that have a GPU. The runtime adapters (
compat:cuda-runtime,compat:sycl-runtime,compat:vulkan-runtime) stay in the project for thesame reason and for a structural one: this package is reached through a
[build-dependencies]edge, so its own[dependencies]deliberately do notreach the consumer's target.
Two fixtures were short by one accelerator
Raising the CI pin to 2026.9.6.6 turned
hip-consumerred immediately: itsglob names
accel = "hip, cuda12.9+{sm_89}"while[package] acceleratorslisted only
hip.sycl-consumerhas the same shape, and so do mcpp's ownexamples/09-heterogeneous/{hip,sycl}.Neither CI could see it. mcpp skips those two examples in its example job, and
this repository's engine pin predated the check (2026.9.6.5). It took both
repositories moving.
Criteria
The four device fixtures now declare no payload at all and still build; that
alone does not distinguish "the rule declared it" from "the fixture still
does", so the new CI step asserts both halves:
[xlings.workspace]in the fixture's manifest — a property of a file thisrepository owns;
the root's (
entries declared by dependencies).That line only prints on a provisioning-stamp miss, and this job restores
~/.mcppfrom a cache — so the step clears the stamp first. Without that, thecriterion's "no" and "this ran on a warm cache" are the same reading.
multi-rule-consumerkeeps one override (xim:glslangpinned to the rule's ownfloor) and the step asserts one version is installed, so the override path is on
the CI graph and not only in mcpp's e2e.