Skip to content

Fix Mach-O assembly selection for watchOS and visionOS - #152

Open
proggeramlug wants to merge 1 commit into
rust-lang:masterfrom
proggeramlug:fix/watchos-visionos-macho-asm
Open

Fix Mach-O assembly selection for watchOS and visionOS#152
proggeramlug wants to merge 1 commit into
rust-lang:masterfrom
proggeramlug:fix/watchos-visionos-macho-asm

Conversation

@proggeramlug

Copy link
Copy Markdown

psm fails to build for *-apple-watchos and *-apple-visionos:

psm@0.1.32: src/arch/aarch_aapcs64.s:32:1: error: unknown directive
psm@0.1.32: .type rust_psm_stack_direction,@function
psm@0.1.32: ^
psm@0.1.32: src/arch/aarch_aapcs64.s:38:1: error: unknown directive
psm@0.1.32: .size rust_psm_stack_direction,.-rust_psm_stack_direction
error: failed to run custom build command for `psm v0.1.32`

Cause

build.rs defines CFG_TARGET_OS_<os> generically from CARGO_CFG_TARGET_OS:

cfg.define(&*format!("CFG_TARGET_OS_{}", os), None);

but the Mach-O branch enumerates only four of the Apple OS names:

#if defined(CFG_TARGET_OS_darwin) || defined(CFG_TARGET_OS_macos) || defined(CFG_TARGET_OS_ios) || defined(CFG_TARGET_OS_tvos)

For watchOS and visionOS the macro is CFG_TARGET_OS_watchos / CFG_TARGET_OS_visionos, no branch matches, and the file falls through to the #else ELF branch — emitting .type and .size, which the Mach-O assembler rejects. macOS, iOS and tvOS are unaffected, which is why this went unnoticed.

The same guard with the same omission appears in all four files that have it: aarch_aapcs64.s, arm_aapcs.s, x86.s, x86_64.s.

Fix

Add the two missing OS names to the Apple branch. No other change.

Verification

Reproduced and verified downstream in a project that reaches psm via stackerswc_ecma_parser. With this patch applied via [patch.crates-io], both targets build where they previously failed in the build script:

target before after
aarch64-apple-watchos build-script failure builds
aarch64-apple-visionos build-script failure builds
aarch64-apple-ios builds builds
aarch64-apple-tvos builds builds
aarch64-apple-darwin builds builds

A possible alternative, if you prefer it

build.rs could instead define CFG_TARGET_VENDOR_<vendor> and the guard become #if defined(CFG_TARGET_VENDOR_apple), which would cover future Apple platforms without another edit. I kept this PR to the minimal change because that variant alters the guard's semantics — the existing branch spells out darwin explicitly alongside macos — and that seemed like your call rather than mine. Happy to switch it over.

psm fails to build for *-apple-watchos and *-apple-visionos:

  src/arch/aarch_aapcs64.s:32:1: error: unknown directive
  .type rust_psm_stack_direction,@function

build.rs defines CFG_TARGET_OS_<os> generically from CARGO_CFG_TARGET_OS, but
the Mach-O branch in the four affected .s files enumerates only four of the
Apple OS names. For watchOS and visionOS the macro is CFG_TARGET_OS_watchos /
CFG_TARGET_OS_visionos, no branch matches, and the file falls through to the
#else ELF branch -- emitting .type and .size, which the Mach-O assembler
rejects. macOS, iOS and tvOS are unaffected, which is why this went unnoticed.

Add the two missing OS names to the Apple branch in all four files that carry
the guard: aarch_aapcs64.s, arm_aapcs.s, x86.s, x86_64.s.
proggeramlug added a commit to PerryTS/perry that referenced this pull request Aug 4, 2026
* fix(release): restore watchOS, unbreak visionOS

Two problems, one latent since 2026-07-18.

visionOS was broken and no release had caught it. dyn-eval joined
perry-runtime's `default` in #6584 and reaches psm three crates down
(dyn-eval -> perry-parser -> swc_ecma_parser -> stacker -> psm), whose Mach-O
guard enumerates darwin/macos/ios/tvos and omits watchos/visionos -- so both
fall through to psm's ELF branch and emit .type/.size, which the Mach-O
assembler rejects. Nothing in Perry is involved. release-packages.yml builds
these with default features and its last successful run was 2026-07-04,
before the regression, so it would have surfaced at the next release. Fixed
upstream as rust-lang/stacker#152; until that lands these two build `default`
minus `dyn-eval`, losing only runtime `new Function`.

watchOS was dropped for a reason that never applied to the triple it ships
on. The v0.5.888 note blamed ring 0.17.14's pointer-size assertion -- real,
but specific to the ILP32 arm64_32-apple-watchos triple.
aarch64-apple-watchos is LP64; ring builds for it, as does perry-ui-watchos.
The LP64 device triple and its simulator are restored across all three sites
that needed it: the build: cross loop, the build-cross matrix, and bottle
staging. arm64_32 stays out until ring is fixed or pinned.

Verified per target on stable with the exact feature list the workflow now
passes: runtime+static, stdlib+static and the UI crate all build for
watchos, watchos-sim, visionos and visionos-sim. library_search.rs already
maps _watchos/_watchos_sim, so no compiler-side change was needed.

Three stale comments claiming watchOS was dropped, and one asserting the
device triple is arm64_32, are corrected -- the second is what kept the
platform out for months.

Claude-Session: https://claude.ai/code/session_01EaD6yNwoinzdW1JbYNkMMF

* docs: rename changelog fragment to the real PR number (#7379)

Claude-Session: https://claude.ai/code/session_01EaD6yNwoinzdW1JbYNkMMF

---------

Co-authored-by: Ralph Küpper <ralph@skelpo.com>
@nagisa

nagisa commented Aug 4, 2026

Copy link
Copy Markdown
Member

If you could summarize the description into a sentence or two for the commit message, that would be amazing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants