macOS Intel bundles fail to launch: binary relocation strips /usr/lib/swift RPATH from appkit_launcher
- Dominant language
- Python
- Stars
- 50
- Forks
- 49
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 16
Description
## Summary
On Intel (x86_64) macOS, applications whose shortcut uses the Swift `appkit_launcher`
fail to start with:
```
dyld: Library not loaded: @rpath/libswiftCore.dylib
Referenced from: .../Contents/MacOS/
Reason: image not found
```
The cause is **not** in the launcher source. The prebuilt launcher in this repo has the
correct `/usr/lib/swift` RPATH, but **the conda package build (binary relocation) strips
that RPATH**, so the shipped launcher can no longer locate the OS Swift runtime on Intel.
Apple Silicon is unaffected (explained below), which is why this presents as Intel-only.
Discovered via the napari macOS installer (napari 0.7.0 and 0.7.1), but this affects any
Intel macOS bundle built from a conda-forge `menuinst` that uses the appkit launcher.
## Evidence
The `appkit_launcher` links three Swift runtime libs **non-weak** via `@rpath`
(`libswiftCore`, `libswiftos`, `libswiftFoundation`); the rest are weak. So at least
`libswiftCore` must be resolvable or the process never starts.
**1. This repo's prebuilt binary is correct** — it has `/usr/lib/swift`:
```
$ otool -l menuinst/data/appkit_launcher_x86_64 | grep -A2 LC_RPATH
path /usr/lib/swift
path @loader_path
path /Applications/Xcode.app/.../swift-5.5/macosx
```
**2. The conda-forge package has it stripped** (`menuinst-2.5.0-py311h52fad64_1`, osx-64):
```
$ otool -l /site-packages/menuinst/data/appkit_launcher_x86_64 | grep -A2 LC_RPATH
path @loader_path
path @loader_path/../../../..
# /usr/lib/swift and the Xcode toolchain path are gone
```
The same stripping happens to `appkit_launcher_arm64` in both osx-64 and osx-arm64
packages.
**3. Why Intel-only.** On arm64, dyld resolves `@rpath/libswiftCore.dylib` to
`/usr/lib/swift/libswiftCore.dylib` from the dyld shared cache **even without** a
`/usr/lib/swift` RPATH (verified on macOS 26, Apple Silicon — `DYLD_PRINT_LIBRARIES`
shows `/usr/lib/swift/libswiftCore.dylib` loading and no "Library not loaded" error).
x86_64 dyld has no such fallback, so the missing RPATH is fatal on Intel.
**4. Adding the RPATH back fixes the dyld error** (Intel, macOS 13.7.8):
```
install_name_tool -add_rpath /usr/lib/swift "/Contents/MacOS/"
codesign -f -s - "/Contents/MacOS/"
# "Library not loaded: @rpath/libswiftCore.dylib" no longer occurs; the app launches.
```
## Root cause
The launcher binaries under `menuinst/data/` are standalone `.app` *templates* that get
copied verbatim into the shortcuts menuinst creates. They are **not** linked into the
environment and should not be relocated. But conda package relocation (rattler-build /
conda-build) rewrites RPATHs on every Mach-O it finds and strips absolute RPATHs that
point outside the prefix — including the legitimate, stable system path `/usr/lib/swift`.
The recipe already deletes these launchers on Windows and Linux ("Apparently these files
make the post-build linkage analysis crash and we should not need them"), but on macOS
they are required and go through relocation, losing `/usr/lib/swift`.
## Fix
Disable binary relocation for the package in the conda-forge feedstock (menuinst is pure
Python; the launcher templates must keep their original RPATHs):
```yaml
# recipe/recipe.yaml
build:
dynamic_linking:
binary_relocation: false
```
Fix PR: conda-forge/menuinst-feedstock#62
Downstream report: napari/packaging#401
(A more surgical alternative would be `rpath_allowlist: [/usr/lib/swift]`, if that is
confirmed to prevent stripping rather than only suppressing the overlinking warning.)
## Environment
- Failing: macOS 13.7.8 (22H730), Intel (MacBookPro14,1), x86_64; napari 0.7.0 and 0.7.1
- Working (arm64 fallback verified): macOS 26, Apple Silicon
- menuinst 2.5.0 (conda-forge)
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with recipe/recipe.yaml in the conda-forge/menuinst-feedstock and review the referenced fix in conda-forge/menuinst-feedstock#62. Verify that the package build preserves /usr/lib/swift in the appkit_launcher RPATH, then confirm an Intel macOS bundle can launch without the libswiftCore.dylib error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, swift
- Domain
- build-system, operating-systems
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100