diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c068f76..2644b23 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -136,9 +136,9 @@ jobs: env: MAVERICKS_SDK_CACHE: ${{ github.workspace }}/.sdk-cache run: | - cmake --preset cross - cmake --build --preset cross - ctest --preset cross + shipyard-cmake --preset cross + shipyard-cmake --build --preset cross + shipyard-ctest --preset cross # Build the Sparkle updater .app on every build (catches updater breaks on PRs). The updater must # NOT link any docker product (self-update circularity); its own binary is named @@ -146,8 +146,8 @@ jobs: - name: Build the Sparkle updater (must not link docker) run: | # The x86_64 Sparkle slice is auto-derived from the updater's CMAKE_OSX_ARCHITECTURES. - cmake -S updater -B build/updater -DCMAKE_OBJC_COMPILER=/usr/bin/clang - cmake --build build/updater + shipyard-cmake -S updater -B build/updater -DCMAKE_OBJC_COMPILER=/usr/bin/clang + shipyard-cmake --build build/updater BIN=build/updater/ContainerToolsUpdater.app/Contents/MacOS/ContainerToolsUpdater otool -L "$BIN" | tee /tmp/o.txt if otool -L "$BIN" | tail -n +2 | grep -iq docker; then @@ -155,8 +155,8 @@ jobs: - name: Build the menu-bar app run: | - cmake -S menubar -B build/menubar -DCMAKE_OBJC_COMPILER=/usr/bin/clang - cmake --build build/menubar + shipyard-cmake -S menubar -B build/menubar -DCMAKE_OBJC_COMPILER=/usr/bin/clang + shipyard-cmake --build build/menubar # On tags: bundle the packaging inputs into ONE tarball so executable bits (binaries, the .app's # Mach-Os, the signer) survive the artifact round-trip -- artifacts otherwise drop file modes. diff --git a/CMakeLists.txt b/CMakeLists.txt index ee6ae3f..5ffd1c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -227,7 +227,7 @@ ExternalProject_Add(lazydocker BUILD_BYPRODUCTS "${LAZY_BIN}" ) -# Fail-closed build-artifact gates (run after `cmake --build`). +# Fail-closed build-artifact gates (run after `shipyard-cmake --build`). add_test(NAME compat_guard COMMAND sh "${MavericksShipyard_SCRIPTS}/assert_binary_compatible.sh" "${DOCKER_BIN}") add_test(NAME sdk_coverage @@ -270,7 +270,7 @@ add_test(NAME sdk_coverage_lazydocker add_test(NAME docker_cli_unit COMMAND sh "${CMAKE_SOURCE_DIR}/tests/docker_cli_test.sh" "${DOCKER_BIN}") # These exercise the gate scripts against the built binary -> pass DOCKER_BIN so they -# work with any build dir (cmake -B ), not a hardcoded build/. +# work with any build dir (shipyard-cmake -B ), not a hardcoded build/. add_test(NAME compat_guard_test COMMAND sh "${CMAKE_SOURCE_DIR}/tests/compat_guard_test.sh" "${DOCKER_BIN}" "${MavericksShipyard_SCRIPTS}/assert_binary_compatible.sh") add_test(NAME sdk_coverage_test diff --git a/cmake/demo_osinit_guard.sh b/cmake/demo_osinit_guard.sh index 198b6f9..9fe18cd 100755 --- a/cmake/demo_osinit_guard.sh +++ b/cmake/demo_osinit_guard.sh @@ -43,7 +43,7 @@ echo "guard says: $guard" CGO=1; LD="-mmacosx-version-min=10.9 -Wl,-undefined,dynamic_lookup" if [ "$(mavericks_docker_mode)" = native ]; then A="$ROOT/build/legacy-support/lib/libMacportsLegacySupport.a" - [ -f "$A" ] || { echo "build the shim first (cmake --build ); need $A"; exit 2; } + [ -f "$A" ] || { echo "build the shim first (shipyard-cmake --build ); need $A"; exit 2; } CC=${CC:-/usr/bin/clang}; LD="$A -lresolv $LD" else CC=${CC:-clang} diff --git a/cmake/package_pkg.sh b/cmake/package_pkg.sh index 0bb37ed..cb9bf09 100755 --- a/cmake/package_pkg.sh +++ b/cmake/package_pkg.sh @@ -16,7 +16,7 @@ export COPYFILE_DISABLE=1 OUT=""; VER=""; DOCKER=""; COMPOSE=""; MACHINE=""; LAZY=""; ISO=""; UPD_APP=""; DOCKED=""; SYNC="" BOOT=""; COMMON=""; CTL=""; MIGRATE=""; GETFUSION=""; MENUBAR=""; LAUNCHAGENT="" -SHIPYARD="${SHIPYARD_SCRIPTS:-}"; RES=""; WELCOME="" +SHIPYARD=""; RES=""; WELCOME="" while [ $# -gt 0 ]; do case "$1" in --out) OUT="$2"; shift 2;; @@ -46,7 +46,11 @@ done && [ -n "$LAZY" ] && [ -n "$ISO" ] && [ -n "$UPD_APP" ] && [ -n "$DOCKED" ] && [ -n "$SYNC" ] \ && [ -n "$BOOT" ] && [ -n "$COMMON" ] && [ -n "$CTL" ] && [ -n "$MIGRATE" ] && [ -n "$GETFUSION" ] && [ -n "$MENUBAR" ] && [ -n "$LAUNCHAGENT" ] \ || { echo "package_pkg: need --out --version --docker --compose --machine --lazydocker --iso --updater-app --docked --sync-helper --bootstrap --common --ctl --migrate --get-fusion --menubar-app --launch-agent" >&2; exit 2; } -[ -n "$SHIPYARD" ] || { echo "package_pkg: SHIPYARD_SCRIPTS unset (install mavericks-shipyard, or pass --msc-scripts)" >&2; exit 2; } +if [ -z "$SHIPYARD" ]; then + # --msc-scripts wins when given; otherwise msc.sh takes $SHIPYARD_SCRIPTS (install@v1 exports it in + # CI) or asks shipyard-cmake where find_package(MavericksShipyard) lands, and exits if neither works. + . "$(dirname "$0")/../msc.sh" +fi for f in "$DOCKER" "$COMPOSE" "$MACHINE" "$LAZY" "$ISO" "$DOCKED" "$SYNC" "$BOOT" "$COMMON" "$CTL" "$MIGRATE" "$GETFUSION" "$LAUNCHAGENT"; do [ -f "$f" ] || { echo "package_pkg: missing input: $f" >&2; exit 1; }; done [ -d "$UPD_APP" ] || { echo "package_pkg: no updater .app: $UPD_APP" >&2; exit 1; } [ -d "$MENUBAR" ] || { echo "package_pkg: no menubar .app: $MENUBAR" >&2; exit 1; } diff --git a/menubar/CMakeLists.txt b/menubar/CMakeLists.txt index cf7cf3a..67e6ff7 100644 --- a/menubar/CMakeLists.txt +++ b/menubar/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.16) # Menu-bar app for the container-tools product. Standalone project like updater/ (built -# on its own: `cmake -S menubar -B build/menubar`). Native ObjC, x86_64 / min-10.9. +# on its own: `shipyard-cmake -S menubar -B build/menubar`). Native ObjC, x86_64 / min-10.9. set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9 CACHE STRING "runs on the 10.9 box") set(CMAKE_OSX_ARCHITECTURES x86_64 CACHE STRING "Intel-only (10.9)") project(DockerMenu LANGUAGES OBJC) diff --git a/msc.sh b/msc.sh new file mode 100644 index 0000000..43c2af0 --- /dev/null +++ b/msc.sh @@ -0,0 +1,25 @@ +# 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:-}" +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/boot2docker_ci_test.sh b/tests/boot2docker_ci_test.sh index d6f0d69..48acef7 100644 --- a/tests/boot2docker_ci_test.sh +++ b/tests/boot2docker_ci_test.sh @@ -15,7 +15,20 @@ else echo "boot2docker_ci_test: no PyYAML; relying on structural grep checks" >&2 fi grep -q 'runs-on: ubuntu-latest' "$W" || { echo "not ubuntu-latest" >&2; exit 1; } -grep -q 'cmake --preset iso' "$W" || { echo "missing configure preset" >&2; exit 1; } -grep -q 'cmake --build --preset iso' "$W" || { echo "missing build preset" >&2; exit 1; } -grep -q 'ctest --preset iso' "$W" || { echo "missing test preset" >&2; exit 1; } +# Anchored at command position, deliberately: 'cmake --preset iso' unanchored is satisfied by +# 'shipyard-cmake --preset iso' too, so it could not fail. This job runs on ubuntu-latest, where +# shipyard ships no pkg and no shipyard-cmake, so PLAIN cmake is the correct call here -- and +# conventions check 18 skips non-macOS jobs for exactly that reason. +grep -qE '^[[:space:]]*cmake --preset iso[[:space:]]*$' "$W" \ + || { echo "missing configure preset" >&2; exit 1; } +grep -qE '^[[:space:]]*cmake --build --preset iso[[:space:]]*$' "$W" \ + || { echo "missing build preset" >&2; exit 1; } +grep -qE '^[[:space:]]*ctest --preset iso([[:space:]]|$)' "$W" \ + || { echo "missing test preset" >&2; exit 1; } +# The other half: a Linux job may NOT call shipyard-cmake, which cannot exist there. The positives +# above still pass if someone ADDS a shipyard-cmake beside them; this is what catches that. +if grep -qE '^[[:space:]]*shipyard-(cmake|ctest|cpack)([[:space:]]|$)' "$W"; then + echo "boot2docker.yml runs shipyard-cmake in a ubuntu job, where the shipyard pkg does not exist" >&2 + exit 1 +fi echo "boot2docker_ci_test: OK" diff --git a/tests/compat_guard_test.sh b/tests/compat_guard_test.sh index be4c6b1..cd36761 100644 --- a/tests/compat_guard_test.sh +++ b/tests/compat_guard_test.sh @@ -5,7 +5,7 @@ set -eu ROOT=$(cd "$(dirname "$0")/.." && pwd) BIN="${1:-$ROOT/build/docker-cli/docker}" GUARD="${2:?assert_binary_compatible.sh path required (arg 2)}" -[ -x "$BIN" ] || { echo "build docker-cli first (cmake --build )" >&2; exit 1; } +[ -x "$BIN" ] || { echo "build docker-cli first (shipyard-cmake --build )" >&2; exit 1; } sh "$GUARD" "$BIN" # Teeth: the gate must be fail-closed, not a rubber stamp. diff --git a/tests/docker_menubar_test.sh b/tests/docker_menubar_test.sh index a8ff5f7..95db1ba 100644 --- a/tests/docker_menubar_test.sh +++ b/tests/docker_menubar_test.sh @@ -54,7 +54,13 @@ grep -q 'Applications/Mavericks Container Tools.app' "$ROOT/cmake/package_pkg.sh grep -q 'asuser' "$ROOT/cmake/package_pkg.sh" || fail "postinstall must launch the app as the console user" grep -q -- '--menubar-app' "$ROOT/.github/workflows/release.yml" || fail "release.yml must pass --menubar-app" -grep -q 'cmake -S menubar' "$ROOT/.github/workflows/release.yml" || fail "release.yml must build the menubar app" +# Anchored at command position: 'cmake -S menubar' is a substring of 'shipyard-cmake -S menubar', so +# the unanchored form cannot fail either way. Asserting the line is the only version with teeth. +grep -qE '^[[:space:]]*shipyard-cmake -S menubar([[:space:]]|$)' "$ROOT/.github/workflows/release.yml" \ + || fail "release.yml must build the menubar app with shipyard-cmake" +if grep -qE '^[[:space:]]*cmake -S menubar([[:space:]]|$)' "$ROOT/.github/workflows/release.yml"; then + fail "release.yml configures menubar with a plain cmake (only shipyard-cmake configures against shipyard)" +fi # Fusion-absent is actionable: a "Get VMware Fusion" item/handler runs the get-fusion helper, and a # one-time alert (seeded in NSUserDefaults) prompts on first no-fusion. The old dead disabled item is gone. diff --git a/tests/sdk_coverage_test.sh b/tests/sdk_coverage_test.sh index dedf246..e218282 100644 --- a/tests/sdk_coverage_test.sh +++ b/tests/sdk_coverage_test.sh @@ -5,6 +5,6 @@ set -eu ROOT=$(cd "$(dirname "$0")/.." && pwd) BIN="${1:-$ROOT/build/docker-cli/docker}" FETCH_SCRIPT="${2:?fetch_sdk.sh path required (arg 2)}" -[ -x "$BIN" ] || { echo "build docker-cli first (cmake --build )" >&2; exit 1; } +[ -x "$BIN" ] || { echo "build docker-cli first (shipyard-cmake --build )" >&2; exit 1; } sh "$ROOT/cmake/sdk_coverage.sh" --fetch-script "$FETCH_SCRIPT" "$BIN" echo "sdk_coverage_test: OK" diff --git a/updater/CMakeLists.txt b/updater/CMakeLists.txt index 7d2e9f7..fc3dcb7 100644 --- a/updater/CMakeLists.txt +++ b/updater/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) # Cocoa/Sparkle auto-updater .app for the container-tools product. This is a SEPARATE project from # the docker build (the repo root is project(... LANGUAGES NONE) and guards against non-preset -# configures); build it on its own with `cmake -S updater -B build/updater`. Native only: the product +# configures); build it on its own with `shipyard-cmake -S updater -B build/updater`. Native only: the product # .pkg installs on the real 10.9 box, so the updater is x86_64 / min-10.9. It links Sparkle + Cocoa and # NOTHING from docker (a Sparkle host has no product code) -- the release workflow asserts that. set(CMAKE_OSX_DEPLOYMENT_TARGET 10.9 CACHE STRING "updater runs on the 10.9 box")