Skip to content

Commit 570d654

Browse files
committed
ci: dist-apple's iOS row builds, packs and runs for real on macos-15
tests/ios-app-consumer, until now checked only at the plan level (no runner in this workflow but macos-15 has an Apple SDK), gains a real target row: `[target.aarch64-ios-sim] runner = ["simctl-run"]`, backed by `xim:apple-simulator-tools` 0.2.0 (published today; its `.app`-operand branch installs and launches a bundle rather than spawning a bare executable) and `[build] ios_deployment_target = "17.0"`. The fixture's program now prints `1-2-3`, matching the ecosystem's other device rows. The new `rules-cross-platform` step mirrors mcpp's own `ci-macos-ios.yml`: gated on `xcrun --sdk iphonesimulator --show-sdk-path` succeeding, and skipped rather than failed when the SDK is absent from the runner image. It builds and packs `--target aarch64-ios-sim --format app`, asserts the bundle is flat (no Contents/), that Info.plist's MinimumOSVersion and CFBundleSupportedPlatforms carry the fixture's own declared values, and runs it with `mcpp run --target aarch64-ios-sim --format app`, asserting exit 0 and the `1-2-3` line. The existing plan-level Linux step is unchanged and still passes against the same fixture.
1 parent d768b81 commit 570d654

3 files changed

Lines changed: 121 additions & 9 deletions

File tree

.github/workflows/ci.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,88 @@ jobs:
17151715
plutil -lint "$app/Contents/Info.plist"
17161716
echo "ok: one bundle, a valid plist, and it launches"
17171717
1718+
# THE iOS ROW, FOR REAL (#622 B1's other half). `tests/ios-app-consumer`
1719+
# is the same fixture the Linux `consumers` job checks at the plan
1720+
# level (see that fixture's own header); here it is built, packed and
1721+
# run against the real target, because this runner -- unlike every
1722+
# other host this workflow uses -- carries the Xcode SDKs and a
1723+
# bootable simulator that make `--target aarch64-ios-sim` reachable at
1724+
# all.
1725+
#
1726+
# GATED ON THE SAME PRECONDITION mcpp's OWN iOS LANE GATES ON
1727+
# (mcpp's `ci-macos-ios.yml`, `ios-host-surface`): the iPhoneSimulator
1728+
# SDK ships inside Xcode as a separate component, not the Command Line
1729+
# Tools alone, so its absence is a fact about the runner image and not
1730+
# a regression in this collection. Skipped rather than failed, and
1731+
# skipped before anything is provisioned -- the same order `dist-apple`
1732+
# itself refuses in, and the reason `docs/20-toolchains.md` (mcpp)
1733+
# gives: "a machine without Xcode should not download a compiler before
1734+
# being told the compiler is not what is missing."
1735+
- name: dist-apple's iOS row produces a bundle the simulator launches
1736+
if: runner.os == 'macOS'
1737+
working-directory: tests/ios-app-consumer
1738+
shell: bash
1739+
run: |
1740+
set -uo pipefail
1741+
if ! xcrun --sdk iphonesimulator --show-sdk-path >/dev/null 2>&1; then
1742+
echo "SKIP: no iphonesimulator SDK on this runner"
1743+
echo " (xcrun --sdk iphonesimulator --show-sdk-path failed) -- see"
1744+
echo " mcpp's docs/20-toolchains.md, 'The Apple SDKs Are Located, Not Installed'"
1745+
exit 0
1746+
fi
1747+
set -e
1748+
1749+
rm -rf target
1750+
"$MCPP" build --target aarch64-ios-sim
1751+
if find target -name '*.app' | grep -q .; then
1752+
echo "FAIL: a plain build produced a bundle"; exit 1
1753+
fi
1754+
"$MCPP" pack --target aarch64-ios-sim --format app | tee pack.log
1755+
app=$(find target -name '*.app' -type d | head -1)
1756+
test -n "$app" || { cat pack.log; echo "FAIL: no .app bundle"; exit 1; }
1757+
1758+
# FLAT, NOT Contents/-SHAPED -- the one difference from the macOS
1759+
# bundle above, and the whole reason iOS needed its own branch in
1760+
# `dist/apple.cppm`.
1761+
if [ -d "$app/Contents" ]; then
1762+
echo "FAIL: the simulator bundle carries Contents/ -- not a flat iOS layout"
1763+
exit 1
1764+
fi
1765+
plist="$app/Info.plist"
1766+
test -f "$plist" || { echo "FAIL: no Info.plist at the bundle root"; exit 1; }
1767+
plutil -lint "$plist"
1768+
1769+
# `MinimumOSVersion` MUST CARRY THIS FIXTURE'S OWN `[build]
1770+
# ios_deployment_target`, not a default the engine invented.
1771+
minos=$(/usr/libexec/PlistBuddy -c 'Print :MinimumOSVersion' "$plist")
1772+
[ "$minos" = "17.0" ] || {
1773+
echo "FAIL: MinimumOSVersion is '$minos', expected 17.0 (this fixture's ios_deployment_target)"
1774+
exit 1; }
1775+
plat=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleSupportedPlatforms:0' "$plist")
1776+
[ "$plat" = "iPhoneSimulator" ] || {
1777+
echo "FAIL: CFBundleSupportedPlatforms is '$plat', expected iPhoneSimulator"
1778+
exit 1; }
1779+
1780+
exe=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$plist")
1781+
test -x "$app/$exe" \
1782+
|| { echo "FAIL: $app/$exe is missing or not executable"; ls -la "$app"; exit 1; }
1783+
1784+
# THE SIMULATOR, THROUGH THE DECLARED RUNNER. `mcpp run --format
1785+
# app` hands the packaged bundle to `runner = ["simctl-run"]`
1786+
# (`xim:apple-simulator-tools` 0.2.0, declared on this target row),
1787+
# which installs and launches it rather than spawning a bare
1788+
# executable -- the branch that package's 0.2.0 header records as
1789+
# needed for an installed bundle. This is the same path a
1790+
# consumer's own `mcpp run --target aarch64-ios-sim --format app`
1791+
# takes, not a bare `simctl spawn` this step could call directly.
1792+
out=$("$MCPP" run --target aarch64-ios-sim --format app 2>&1) && rc=0 || rc=$?
1793+
printf '%s\n' "$out" | tail -20
1794+
[ "$rc" -eq 0 ] \
1795+
|| { echo "FAIL: mcpp run --target aarch64-ios-sim --format app exited $rc"; exit 1; }
1796+
grep -qx '1-2-3' <<<"$out" \
1797+
|| { echo "FAIL: the program's output line '1-2-3' is absent"; exit 1; }
1798+
echo "ok: a flat iOS Simulator bundle, MinimumOSVersion 17.0, and the simulator ran it"
1799+
17181800
- name: the rule declared its own compiler
17191801
working-directory: tests/spirv-consumer
17201802
run: |

tests/ios-app-consumer/mcpp.toml

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Fixture: the iOS row of dist-apple, checked at the PLAN level.
1+
# Fixture: the iOS row of dist-apple.
22
#
3-
# NO HOST HERE CAN REACH A REAL MEASUREMENT. `--target aarch64-ios-sim`
4-
# refuses before `build.mcpp` ever runs, on every host without Xcode:
3+
# ONE FIXTURE, TWO CI LANES. On every host without Xcode, `--target
4+
# aarch64-ios-sim` refuses before `build.mcpp` ever runs:
55
#
66
# error: target aarch64-ios-sim needs the iphonesimulator SDK, which this
77
# machine does not provide.
@@ -10,10 +10,10 @@
1010
# measurement... only answerable on the platform the member serves") does not
1111
# even get this member as far as a plan-level assertion on a non-Apple CI
1212
# runner: there is no `--target` that reaches `plan_for` with `MCPP_TARGET_OS`
13-
# actually set to `ios` unless the runner IS a Mac with Xcode installed.
14-
#
15-
# This package is instead built for the HOST (an ordinary `mcpp build`, no
16-
# `--target`), which compiles `build.mcpp` into an ordinary ELF binary at
13+
# actually set to `ios` unless the runner IS a Mac with Xcode installed. On
14+
# such a runner (`ubuntu-24.04`, the `consumers` job) this package is instead
15+
# built for the HOST (an ordinary `mcpp build`, no `--target`), which compiles
16+
# `build.mcpp` into an ordinary ELF binary at
1717
# `target/.build-mcpp/build.mcpp.bin` and, on this row, does not even reach
1818
# `plan_for` at pack time (`generate()`'s call to it runs during the plain
1919
# build too, and returns `applies == false` because `pack_format()` is
@@ -25,10 +25,17 @@
2525
# `std::getenv` and nothing else (`hostprogram.cppm`), so this exercises the
2626
# exact same code `plan_for` runs under a real iOS build -- everything past
2727
# "which environment variables does this process see" is unchanged.
28+
#
29+
# On the `macos-15` runner (the `rules-cross-platform` job) the SAME fixture
30+
# is instead built, packed and run for real, through `--target
31+
# aarch64-ios-sim`: see that job's "dist-apple's iOS row produces a bundle the
32+
# simulator launches" step. `[target.aarch64-ios-sim]` below is what that step
33+
# exercises and the plan-level lane never reaches, because it never sets
34+
# `MCPP_TARGET` at all.
2835
[package]
2936
name = "ios-app-consumer"
3037
version = "0.3.0"
31-
description = "Fixture: the iOS row of dist-apple, checked at the plan level"
38+
description = "Fixture: the iOS row of dist-apple, checked at the plan level and, on macOS, for real"
3239
license = "Apache-2.0"
3340
authors = ["mcpp-community"]
3441

@@ -40,6 +47,29 @@ import_std = true
4047
[build-dependencies.mcpp]
4148
plugins = { path = "../..", features = ["dist-apple"], host-module = true }
4249

50+
# THE SAME KEY THE PLAN-LEVEL LANE SETS BY HAND (`MCPP_TARGET_MIN_PLATFORM_
51+
# VERSION` in `check-ios-plan.sh`), stated here for the real build the macOS
52+
# lane runs. `mcpp::min_platform_version()` reads this for the effective
53+
# triple; `dist-apple` copies it into `Info.plist`'s `MinimumOSVersion`
54+
# unchanged, which is the value the macOS lane compares against.
55+
[build]
56+
ios_deployment_target = "17.0"
57+
4358
[targets.ios-app-consumer]
4459
kind = "bin"
4560
main = "src/main.cpp"
61+
62+
# THE SIMULATOR ROW ONLY -- the device row (`aarch64-ios`) keeps `runner`
63+
# unset, as `examples/13-platform-targets/mcpp.toml` does: an artifact cannot
64+
# be run off an iOS device without a signature the developer owns.
65+
[target.aarch64-ios-sim]
66+
runner = ["simctl-run"]
67+
68+
# Declared beside the row that uses it, as every other cross-target fixture in
69+
# this ecosystem declares its runner's payload. `xim:apple-simulator-tools`
70+
# 0.2.0 is the release whose `simctl-run` installs and launches a `.app` when
71+
# the operand is a bundle (see this repository's README and CHANGELOG) --
72+
# `mcpp pack --format app` is what this fixture's macOS lane runs, so the
73+
# 0.1.0 bare-executable branch is not enough.
74+
[target.aarch64-ios-sim.xlings.workspace]
75+
"xim:apple-simulator-tools" = "0.2.0"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
#include <cstdio>
2-
int main() { std::puts("ios-app-consumer ok"); return 0; }
2+
int main() { std::puts("1-2-3"); return 0; }

0 commit comments

Comments
 (0)