diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eecade1..3b24b15 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ on: default: "" env: MCPP_SOURCE_REF: ${{ github.event.inputs.mcpp_ref || vars.MCPP_SOURCE_REF }} - MCPP_VERSION: 2026.11.9.1 + MCPP_VERSION: 2026.11.14.1 XLINGS_VERSION: v2026.10.26.1 # The mtest engine the runs are reported with: the conformance suite's cases # (tools/run-conformance.sh with MTEST set) and `mcpp test`'s store (target/mtest). @@ -255,6 +255,23 @@ jobs: test "$missing" -eq 0 done + # AND WITH THE TARGET REQUESTED, which is a different link on this + # machine. The steps above build natively, where no target is requested + # and the stub of `libSystem` was never supplied; `--target aarch64-macos` + # here is the build in which it was, ahead of the SDK the link carries + # (0.23.3, `undefined symbol: strlen`). The SDK must answer, so this + # needs an mcpp that states it (`MCPP_TARGET_SDK`, 2026.11.14.1+). + - name: This package's own tests, the target requested + run: | + set -euo pipefail + mcpp test --target aarch64-macos 2>&1 | tee tests-target.log + missing=0 + for f in tests/*.cpp; do + name="$(basename "$f" .cpp)" + grep -q "^$name \.\.\. ok" tests-target.log || { echo "did not run or did not pass: $name (--target)" >&2; missing=1; } + done + test "$missing" -eq 0 + - name: This package's test runs, kept for the report if: always() run: | @@ -460,8 +477,8 @@ jobs: - name: The failing cases, explained if: failure() run: | - [ -n "${MTEST:-}" ] && [ -d .spec/conformance/.mtest ] || exit 0 - ( cd .spec/conformance && "$MTEST" explain ) || true + [ -n "${MTEST:-}" ] && [ -d .spec/tests/cts/.mtest ] || exit 0 + ( cd .spec/tests/cts && "$MTEST" explain ) || true # THE RUNS OF THIS JOB, REPORTED: the conformance suite's (one case per # interface, its observations within it) and `mcpp test`'s (one case per @@ -473,7 +490,7 @@ jobs: [ -n "${MTEST:-}" ] || { echo "no mtest engine in this job"; exit 0; } store="$(cygpath -u "$RUNNER_TEMP" 2> /dev/null || printf '%s' "$RUNNER_TEMP")/mtest-store" mkdir -p "$store"; here="$PWD" - for from in "$here/.spec/conformance/.mtest" "$RUNNER_TEMP/mcpp-test-runs"; do + for from in "$here/.spec/tests/cts/.mtest" "$RUNNER_TEMP/mcpp-test-runs"; do if [ -f "$from/index.ndjson" ]; then ( cd "$store" && "$MTEST" store import --from "$from" ); fi done [ -f "$store/.mtest/index.ndjson" ] || { echo "no run was kept"; exit 0; } diff --git a/README.md b/README.md index 537477a..dcb4574 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ written on the kernel's own calls. openkal = "0.25.0" [target.'cfg(os = "macos")'.dependencies] -openkal-macos = "0.23.2" +openkal-macos = "0.23.3" ``` Its purpose is as much to test the specification as to be used. A specification @@ -183,6 +183,17 @@ same image parses as fast on Linux arm64. Since 0.17.1 it is the same kernel ide this system's library keeps for each thread (`pthread_threadid_np`, a name no C library in this ecosystem defines). +## What 0.23.3 corrects + +**The stub of `libSystem` is supplied only when the link has no SDK.** A build +for this system with a target requested (`mcpp build --target aarch64-macos`) on +a Mac put `port/` on the link, ahead of the SDK that mcpp has named there since +2026.8.25.2, and the three names of the stub shadowed the SDK's complete library +(`undefined symbol: strlen`). The build program now asks mcpp's +`MCPP_TARGET_SDK` (2026.11.14.1+), the SDK the link names, and supplies the stub +when a target was requested and that is empty: a cross link from another host. +An older mcpp sets no such variable, and the condition is then the previous one. + ## What 0.23.2 corrects The manifest declares `openkal = "^0.25.0"`. An implementation written against a diff --git a/build.mcpp b/build.mcpp index 0523aaf..ba0ae2b 100644 --- a/build.mcpp +++ b/build.mcpp @@ -54,42 +54,37 @@ import std; // links against it just as well and names the same library. int main() { - // THE CONDITION IS NOT "WHICH MACHINE", AND THE FIRST TWO ATTEMPTS AT - // IT BOTH WERE. + // THE QUESTION IS WHETHER THE SYSTEM'S OWN STUB IS ON THE LINK, AND mcpp + // ANSWERS IT: `MCPP_TARGET_SDK` names the SDK the link carries with + // `-isysroot`, and is empty when the link names none (mcpp 2026.11.14.1+). + // Ours is supplied exactly when a target was requested and no SDK is on + // the link — a cross link to this system from another host. // - // Attempt one supplied the stub always, and on this system it SHADOWED the - // vendor's — which lists every name rather than three (see above). - // Attempt two asked whether the host was this system, and that failed the - // other way: `mcpp build --target aarch64-macos` ON a Mac is a build whose - // target side comes from the graph, and the build tool deliberately keeps - // this machine's SDK off such a link. The vendor's stub was then not there - // either, and neither was ours: + // THE THREE ATTEMPTS BEFORE THIS ONE EACH ASKED A NEIGHBOURING QUESTION. + // + // Always: the stub shadowed the vendor's on this system (above). + // The host: `mcpp build --target aarch64-macos` ON a Mac then had no + // `libSystem` at all, because mcpp kept the SDK off such a link for one + // day (2026-08-24): // // ld64.lld: error: library not found for -lSystem - // ld64.lld: error: undefined symbol: clock_gettime_nsec_np - // ld64.lld: error: undefined symbol: pthread_create_from_mach_thread // - // The fact that decides it is whether the build was POINTED AT A TARGET. - // When it was, the tool supplies no system of its own and this package is - // the only thing that can name one. When it was not — a native build, which - // is what this package's own conformance suite does — the SDK is on the - // link and is the complete answer. - // `MCPP_TARGET_REQUESTED` AND NOT `MCPP_TARGET`. The second is filled in - // with the host when nobody named a target, so it is never empty and the - // test was always true — which put this stub on a NATIVE link, where the - // SDK's complete one was already there and ours shadowed it: + // A requested target (`MCPP_TARGET_REQUESTED`, which is empty on a native + // build, unlike `MCPP_TARGET`): right for that day's mcpp, and wrong from + // the next, which kept `-isysroot` on every link of this system's format on + // a Mac (2026.8.25.2). The stub was put ahead of the SDK's and shadowed it + // again, on a Mac with `--target` only — a case no build here exercised + // until mcpp's canary `cxx aarch64-macos test` (2026-11-14): // - // ld64.lld: error: undefined symbol: wcslen / strtoul / __error + // ld64.lld: error: undefined symbol: strlen / memcpy / pthread_create // - // The first is the value unfilled: empty exactly when this is an ordinary - // native build. See mcpp's `build_program.cppm` for why the two are - // different questions even when the triples are equal. + // Each was a proxy for the fact; the fact is the tool's to state. // - // An mcpp too old to set it leaves it empty, and that is the right answer - // for such a build tool: it has no graph-supplied target side, so the - // system is always on the link. + // An mcpp too old to set `MCPP_TARGET_SDK` leaves it empty, and the + // condition is then the previous one: such a build behaves as it did. const char* requested = std::getenv("MCPP_TARGET_REQUESTED"); - if (requested && *requested) + const char* sdk = std::getenv("MCPP_TARGET_SDK"); + if (requested && *requested && !(sdk && *sdk)) mcpp::link_search("port"); mcpp::rerun_if_changed("port/libSystem.tbd"); return 0; diff --git a/mcpp.toml b/mcpp.toml index 2655574..12357c0 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,7 +1,7 @@ [package] namespace = "mcpplibs" name = "openkal-macos" -version = "0.23.2" +version = "0.23.3" description = "An implementation of openkal for macOS, written on the kernel's own calls. Its purpose is as much to test the specification as to be used." license = "Apache-2.0"