Skip to content

fix(ci): the C-library check read a graph it did not write - #5

Merged
Sunrisepeak merged 1 commit into
mainfrom
fix/check-reads-the-graph-it-wrote
Sep 6, 2026
Merged

fix(ci): the C-library check read a graph it did not write#5
Sunrisepeak merged 1 commit into
mainfrom
fix/check-reads-the-graph-it-wrote

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

What

tools/check_device_c_library.sh builds a fixture and then inspects its build.ninja, selecting that file by globbing target/*/*/build.ninja and taking the first one that declares a device action.

A build directory is named by a fingerprint, so a tree built more than once holds one per configuration and one per engine or payload version it was built with. The first in glob order is whichever fingerprint sorts first, not the one this run produced.

Measured

2026-09-07, on examples/09-heterogeneous/sycl/app in the mcpp tree:

reading .../target/x86_64-linux-gnu/287a6f509a009ac6/build.ninja
ASSERT-FAIL: no ecosystem C library on the device compiler's search list

That graph was written the previous day by mcpp.plugins 0.2.0 — the version before the fix this check exists to guard. The graph the same command had just written (dbd6d29826ff18ba) carried both flags:

-isystem .../xim-x-glibc/2.44.2/include
-isystem .../xim-x-linux-headers/5.11.1/include

The check reported a defect in a build that was correct. It would report success for a broken one just as readily, whenever the stale directory happened to be the good one.

Why CI never saw it

The checkout is fresh, so every directory under target/ comes from the same run. Only an accumulating tree can distinguish the two.

Fix

target/ is removed before the build, so exactly one graph exists to read and the object of the check is produced by the check. The next step in ci.yml already does this for its own build.

The check builds the fixture and then inspects its build.ninja. It selected
that file by globbing `target/*/*/build.ninja` and taking the first one that
declares a device action.

A build directory is named by a fingerprint, so a tree that has been built more
than once holds one per configuration and one per engine or payload version it
was built with. The first in glob order is therefore whichever fingerprint
sorts first, not the one this run produced.

Measured 2026-09-07 on the SYCL example. The check reported

    ASSERT-FAIL: no ecosystem C library on the device compiler's search list

from a graph written the previous day by mcpp.plugins 0.2.0, which is the
version before the fix this check exists to guard. The graph the same command
had just written carried both `-isystem` flags and was correct. The check would
have reported success for a broken build just as readily, from a stale
directory that happened to be right.

It is invisible in CI, where the checkout is fresh and every directory under
`target/` comes from the same run. Only an accumulating tree can see it.

`target/` is now removed before the build, so exactly one graph exists to read
and the object of the check is produced by the check. That is what the next
step in ci.yml already does for its own build.
@Sunrisepeak
Sunrisepeak merged commit fc1f353 into main Sep 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant