Reconcile what __config_site declares with what the port provides - #7
Open
Sunrisepeak wants to merge 7 commits into
Open
Reconcile what __config_site declares with what the port provides#7Sunrisepeak wants to merge 7 commits into
Sunrisepeak wants to merge 7 commits into
Conversation
`__config_site` is this package's statement about the environment it was configured for, and that environment is openkal-musl. A statement that drifts from what the port actually provides does not fail to build and does not fail to link. It produces a program that takes a path the environment cannot support, and reports nothing. `_LIBCPP_HAS_TERMINAL` is the position where that happened. It gates `std::__is_posix_terminal`, which is `isatty(fileno(stream))` and nothing else. The port answered `isatty` with TCGETS while musl asks with TIOCGWINSZ, so every `isatty` returned zero --- for a real terminal as readily as for a pipe --- and `std::print` never took its terminal path. Nothing failed; a program deciding on colour or on line buffering decided wrongly and in silence. THE REMEDY WAS TO FIX THE PORT RATHER THAN TO WITHDRAW THE DECLARATION. The design document proposed setting the position to zero, which would have been a correct description of a broken port and would have left every program above it without a facility the environment can in fact provide. openkal-musl now answers the question musl asks, so the declaration is true, and this step is what keeps it true rather than leaving it to be checked once and assumed afterwards. The criterion is a relation and not a value. Asserting that a terminal is detected would need a terminal; asserting that a pipe is not would have passed throughout the defect. What must hold is that the two DIFFER, and that they differ the way the system's own C library does --- which is why a control built with the host compiler runs through the same harness. The step also fails in the other direction. A declaration of zero beside a working `isatty` is drift of the same kind, and the remedy there is to raise the declaration rather than to leave it stale. The declared versions move in step with openkal 0.8 and openkal-musl 0.4.
…ry does This repository had no MCPP_SOURCE_REF mechanism while the other seven in the ecosystem did. An engine change could therefore be validated against seven repositories and not against the one that carries a C++ standard library. That is the repository where a change to how a target side is assembled shows first. A standard library is not portable in the sense a program is: it is configured for one C library and compiled against that library's headers, so a change in which headers reach a translation unit reaches this package before it reaches anything above it. The mechanism is the one the other repositories use, so that a reader who knows one knows all of them: empty in an ordinary run, in which case the released pin is what is tested; set through the workflow_dispatch input or the repository variable, in which case the engine is built from that source and put ahead on the path. The version it reports is echoed, because a path entry that does not win looks exactly like one that does until something is built with the wrong engine.
…ished
This package declares openkal-musl by version, which is what a published
manifest must say. A change spanning the two repositories cannot be tested that
way: the version named does not exist in the index until the other half is
released, and the run fails with
E_NOT_FOUND: package 'openkal-musl@0.4.0' not found in the synced index
which reads as a mistake in this manifest and is nothing of the kind.
Every other repository in this ecosystem solves it by substituting a working
tree. This one now does the same, for both halves of the stack beneath it: the C
library at this branch where it has one, and the specification that C library
reaches, so that what is tested is the stack as written rather than a mixture of
one branch and one release.
The substitution is asserted rather than assumed. One that matched nothing would
leave the manifest naming a version, the resolver would fetch a published C
library, and the run would report on that one while appearing to report on this
branch --- which is the failure this whole mechanism exists to prevent, arriving
by a different route.
The substitution reached the C library and the specification and stopped there.
openkal-musl also names a BACKEND, whose version moves with the same change, so
the run failed one link further down for the same reason it had failed at the
top:
E_NOT_FOUND: package 'openkal-linux@0.6.0' not found in the synced index
Every dependency that moves with a change spanning these repositories is now
substituted, and each substitution is asserted rather than assumed --- one that
matched nothing would leave a manifest naming a published version, and the run
would report on that one while appearing to report on this branch.
⚠️ That the first attempt stopped two links down is worth recording. A chain is
substituted correctly only when it is followed to its end, and 'I substituted the
dependency' is not the same statement as 'nothing in the graph still names a
version that does not exist'.
openkal-musl names a backend per target --- linux, macos, windows and opensbi,
each conditional --- and every one of their versions moves with a change that
spans these repositories. Each left unsubstituted fails the same way, one link
further down:
E_NOT_FOUND: package 'openkal-linux@0.6.0' (the host build)
E_NOT_FOUND: package 'openkal-opensbi@0.2.0' (the bare-metal one)
I named the first and the second appeared. The commit that named the first said
"a chain is substituted correctly only when it is followed to its end", and then
followed it by hand to one entry short of the end, which is the ordinary outcome
of a list written from memory.
The set is now read out of the manifest, so it cannot fall behind what that
manifest declares.
⭐ AND THE LAST CHECK IS THE ONE THAT WOULD HAVE CAUGHT BOTH: after every
substitution, nothing anywhere in the graph may still name a version. That is a
property of the whole graph rather than of the entries someone remembered, and it
fails at the substitution rather than at a resolver error further on, where the
message names a package instead of naming the omission.
…y job
The host-dimension job resolved this ecosystem from the index and installed the
released engine. Both were wrong for a change that spans these repositories, and
the first announced itself:
E_NOT_FOUND: package 'compat.openkal-musl@0.4.0' not found in the synced
index, synced 0 seconds ago
The second would not have. A manifest key the engine does not recognise is
accepted rather than refused, so that job would have built manifests written for
an unreleased engine using a released one, and the semantics the new key asks
for would simply be absent from the result.
The remedy is not a second copy of the procedure. Two copies that must agree are
two copies that will not, which is how one job came to have neither. Both are
now scripts that each job calls:
tools/install-mcpp.sh the engine this run is judged by
tools/branch-graph.sh the working trees of this ecosystem, in place of the
versions the manifests name
Three consequences follow from the extraction.
The substituted paths are now relative. An absolute path names a directory of
one machine; a manifest carrying one has been committed in this ecosystem and
published, and every consumer resolving it was handed a path that exists
nowhere. Relative paths cannot express that mistake. They are also the only form
that works unchanged on all three hosts, since `pwd` under MSYS reports
`/d/a/...`. Measured before adoption: a dependency named by a relative path
resolves against the manifest that contains it rather than against the working
directory, at three levels of nesting, and the substituted graph of six
repositories resolves with no absolute path anywhere in it.
In-place editing no longer uses `sed -i`. BSD sed, which is macOS's, reads the
argument after -i as a backup suffix, so the command that edits a file on Linux
consumes the next expression on macOS --- and this script now runs on macOS.
The engine on PATH is compared against the engine that was built. GITHUB_PATH
governs the steps that follow, so the step that appends cannot observe its own
effect, and whether the appended spelling is one the runner accepts is a
property of the runner. Unasserted, a cross-validation run on a host that
ignored it would build with the released engine and report the change under
review as tested.
main moved MCPP_VERSION from 2026.8.24.4 to 2026.8.26.2 while this branch rewrote the file that holds it, so the two changes met in one line. The pin is main's, since it names the more recent release and is what an ordinary run of this repository should test; everything else is this branch's.⚠️ A pull request in a conflicting state builds no `pull_request` runs at all, so the checks did not fail --- they were never created. The runs that judged this branch while it was in that state were dispatched against the branch rather than raised by the pull request, and this merge is what restores the ordinary path.
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.
Paired with mcpplibs/openkal#13 and mcpplibs/openkal-musl#15.
__config_siteis this package's statement about the environment it was configured for, and that environment is openkal-musl. A statement that drifts from what the port provides does not fail to build and does not fail to link. It produces a program that takes a path the environment cannot support, and reports nothing._LIBCPP_HAS_TERMINALis where that happened. It gatesstd::__is_posix_terminal, which isisatty(fileno(stream))and nothing else. The port answeredisattywith TCGETS while musl asks with TIOCGWINSZ, so everyisattyreturned zero — for a real terminal as readily as for a pipe — andstd::printnever took its terminal path.The remedy was to fix the port, not to withdraw the declaration
The design document proposed setting the position to
0. That would have been a correct description of a broken port, and it would have left every program above it without a facility the environment can in fact provide. openkal-musl#15 makesisattyanswer the question musl asks, so the declaration is now true.This step is what keeps it true, rather than leaving it to be checked once and assumed afterwards.
The criterion is a relation, not a value
Asserting "a terminal is detected" would need a terminal. Asserting "a pipe is not" would have passed throughout the defect. What must hold is that the two differ, and that they differ the way the system's own C library does — which is why a control built with the host compiler runs through the same harness.
The step fails in the other direction too: a declaration of
0beside a workingisattyis drift of the same kind, and the remedy there is to raise the declaration rather than leave it stale.Declared versions move in step with openkal 0.8 and openkal-musl 0.4.