From fb9cd55a0dde9cbb7896de3ff4c2f52ba0a32b3f Mon Sep 17 00:00:00 2001 From: Amitai Schleier Date: Sun, 13 Sep 2026 22:18:33 -0400 Subject: [PATCH] feat!: configure with shipyard-cmake; the README no longer promises self-registration shipyard's pkg postinstall stops writing the CMake user package registry, and MavericksShipyardConfig.cmake refuses any cmake but shipyard-cmake. Every cmake/ctest/cpack at command position moves to the shipyard-* wrapper, and build/msc.sh becomes shipyard's canonical template byte for byte -- its registry tier is gone, replaced by a shipyard-cmake probe. The README is the point of this commit. Its "Building" section told developers to install shipyard and rely on self-registration ("it self-registers, so find_package finds it with no CMAKE_PREFIX_PATH"), which is exactly the mechanism being deleted: a reader following it after the cutover installs nothing that any cmake can find. It now names the pkg, names shipyard-cmake as the only cmake that configures this repo, and does not describe the registry at all, because there will not be one. Also converted: the build and preset recipes a reader pastes from README.md, and the by-hand run instructions in tests/compat-sweep.sh, tests/differential.sh and tests/README.md's mutation-testing FIX. No gate reads any of those. Left alone deliberately: docs/superpowers/plans/ and specs/ (dated records of completed work, not instructions) and tests/README.md's past-tense account of a stale-object incident. No workflow step was added; install@v1's default mode already puts shipyard-cmake on PATH. Do not merge until shipyard has landed bc3082a. BREAKING CHANGE: this tree no longer configures with a plain cmake. It needs shipyard-cmake from the shipyard pkg, which exists on no runner until bc3082a is on @v1 -- so this repo's own CI fails until then, by design. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01GTxFde2TJMmp5p64DhvDSK --- .github/workflows/release.yml | 4 ++-- README.md | 19 +++++++++---------- build/msc.sh | 32 ++++++++++++++++++++++++-------- tests/README.md | 2 +- tests/compat-sweep.sh | 2 +- tests/differential.sh | 6 +++--- 6 files changed, 40 insertions(+), 25 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6727bd9..8619205 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -96,12 +96,12 @@ jobs: # the fetched 10.9 SDK. Building against the runner's own SDK with only # -mmacosx-version-min=10.9 would accept declarations 10.9 never had. - name: Configure (cross, against the pinned 10.9 SDK) - run: cmake --preset cross + run: shipyard-cmake --preset cross # Every tool is gated POST_BUILD by shipyard's compat guard: fails if a # binary declares a floor above 10.9 or imports a symbol 10.9 lacks. - name: Build + compat guard - run: cmake --build --preset cross + run: shipyard-cmake --build --preset cross # The shared runner takes the whole suite, so a newly added test runs the # day it lands rather than when someone remembers a CI line. Includes diff --git a/README.md b/README.md index 74a2ff7..46ab7a7 100644 --- a/README.md +++ b/README.md @@ -45,23 +45,22 @@ no dependencies, and edits binaries produced by toolchains fifteen years newer. ## Building ```sh -cmake -S . -B build && cmake --build build && ctest --test-dir build +shipyard-cmake -S . -B build && shipyard-cmake --build build && shipyard-ctest --test-dir build ``` Needs [shipyard](https://github.com/ModernMavericks/shipyard), the family's -shared CMake helpers — install it once and it self-registers, so `find_package` -finds it with no `CMAKE_PREFIX_PATH`: - -```sh -cmake -S ../mavericks-shipyard -B /tmp/sy -DCMAKE_INSTALL_PREFIX="$HOME/.local" -cmake --install /tmp/sy -``` +shared CMake helpers. Install its pkg once; among other things it puts +`shipyard-cmake`, `shipyard-ctest` and `shipyard-cpack` in `/usr/local/bin`. +**`shipyard-cmake` is the only cmake that configures this repo** — it supplies +the prefix `find_package(MavericksShipyard)` resolves from, and +`MavericksShipyardConfig.cmake` refuses any other cmake. Use `shipyard-ctest` +and `shipyard-cpack` for the same reason: same rule, same commands. Presets pick the build mode: ```sh -cmake --preset native # on 10.9, with its own clang -cmake --preset cross # on a modern host, against the pinned 10.9 SDK +shipyard-cmake --preset native # on 10.9, with its own clang +shipyard-cmake --preset cross # on a modern host, against the pinned 10.9 SDK ``` Every tool is gated by shipyard's compat guard, which fails the build if a diff --git a/build/msc.sh b/build/msc.sh index 9e7d20a..43c2af0 100644 --- a/build/msc.sh +++ b/build/msc.sh @@ -1,9 +1,25 @@ -# build/msc.sh -- sourced: locate the installed mavericks-shipyard scripts dir as $SHIPYARD. -# Resolution: $SHIPYARD_SCRIPTS (exported by install@v1 in CI) -> the CMake user package registry (a local -# `cmake --install`) -> a sibling checkout (a dev box that has never installed it). -# This is the only per-repo part of the version scaffolding; the logic itself lives in shipyard. +# usage: . build/msc.sh +# Sourced by a ModernMavericks product's build scripts: locates shipyard's scripts as +# $SHIPYARD and exports SHIPYARD_SCRIPTS. In CI, install@v1 has already exported +# SHIPYARD_SCRIPTS; anywhere else this asks shipyard-cmake -- the only cmake that configures +# against shipyard -- where find_package(MavericksShipyard) lands, so a CMAKE_PREFIX_PATH +# dev override moves the scripts together with the modules. About 2 s, exported so children +# skip it. CANONICAL COPY: shipyard's scripts/templates/msc.sh; conventions check 17 +# requires every product's copy to match it byte for byte, so change it there, not here. SHIPYARD="${SHIPYARD_SCRIPTS:-}" -[ -d "$SHIPYARD" ] || SHIPYARD="$(cat "$HOME/.cmake/packages/MavericksShipyard/"* 2>/dev/null | head -1)/scripts" -[ -d "$SHIPYARD" ] || SHIPYARD="$(cd "$(dirname "$0")/.." && pwd)/../mavericks-shipyard/scripts" -[ -d "$SHIPYARD" ] || { echo "cannot locate mavericks-shipyard scripts (install it, or set SHIPYARD_SCRIPTS)" >&2; return 1 2>/dev/null || exit 1; } -export SHIPYARD +if [ ! -d "$SHIPYARD" ]; then + _msc_probe="$(mktemp -d "${TMPDIR:-/tmp}/shipyard-probe.XXXXXX")" + printf '%s\n' 'cmake_minimum_required(VERSION 3.16)' 'project(shipyard_probe NONE)' \ + 'find_package(MavericksShipyard REQUIRED)' 'message(STATUS "SHIPYARD_DIR=${MavericksShipyard_DIR}")' \ + > "$_msc_probe/CMakeLists.txt" + # platform: appending /scripts to the substitution directly made a failed probe (no + # shipyard-cmake, a refused configure) yield the literal "/scripts" -- an absolute path, + # plausible-looking, and the error below would then complain about the wrong thing. So + # assign the probe's answer first and append only if there was one. + _msc_dir="$(shipyard-cmake -S "$_msc_probe" -B "$_msc_probe/b" 2>/dev/null | sed -n 's/^-- SHIPYARD_DIR=//p')" + if [ -n "$_msc_dir" ]; then SHIPYARD="$_msc_dir/scripts"; fi + rm -rf "$_msc_probe"; unset _msc_probe _msc_dir +fi +[ -d "$SHIPYARD" ] || { echo "msc.sh: cannot locate shipyard -- install the shipyard pkg (it provides shipyard-cmake), or set SHIPYARD_SCRIPTS" >&2; return 1 2>/dev/null || exit 1; } +SHIPYARD_SCRIPTS="$SHIPYARD" +export SHIPYARD SHIPYARD_SCRIPTS diff --git a/tests/README.md b/tests/README.md index 5b0cdd4..ec02294 100644 --- a/tests/README.md +++ b/tests/README.md @@ -277,7 +277,7 @@ reproducing the failure in new shapes: force the rebuild and confirm it actually happened — compile the test directly with `cc` (as this repo's hermetic tests' own header comments already suggest, e.g. `trie_test.c`'s), or `touch` the source and use - `cmake --build --clean-first`, or otherwise check the object's mtime + `shipyard-cmake --build --clean-first`, or otherwise check the object's mtime genuinely advanced past the edit. Never trust a mutation result from a build you did not affirmatively force. diff --git a/tests/compat-sweep.sh b/tests/compat-sweep.sh index d19bb30..2dc5998 100755 --- a/tests/compat-sweep.sh +++ b/tests/compat-sweep.sh @@ -30,7 +30,7 @@ # families of binaries built, it takes minutes, and Task 2 removes half of what # it drives. Run it by hand, on real 10.9, when the translation changes: # -# cmake --preset native-local && cmake --build --preset native-local +# shipyard-cmake --preset native-local && shipyard-cmake --build --preset native-local # MACHO_SWEEP_NEW_BIN=/private/tmp/mm-build/schmonz/macho-tools/native \ # sh tests/compat-sweep.sh /path/to/a/build-of-91b30b3 # diff --git a/tests/differential.sh b/tests/differential.sh index 5bec9a0..23b9534 100755 --- a/tests/differential.sh +++ b/tests/differential.sh @@ -17,10 +17,10 @@ # a rewrite is reached and want to show the rewrite itself did not move: # # git stash # or: git worktree add of the ref -# cmake -S . -B /tmp/ref -DMAVERICKS_EXPECTED_MODE=native -# cmake --build /tmp/ref +# shipyard-cmake -S . -B /tmp/ref -DMAVERICKS_EXPECTED_MODE=native +# shipyard-cmake --build /tmp/ref # git stash pop -# cmake --preset native-local && cmake --build --preset native-local +# shipyard-cmake --preset native-local && shipyard-cmake --build --preset native-local # sh tests/differential.sh /tmp/ref # # WHAT IT SWEEPS. There are ~86,000 regular files under the default roots on a