From 64d9190b00dc30bf143e0b6f0a4a3f1c55aa50c1 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Thu, 11 Jun 2026 11:28:15 -0700 Subject: [PATCH] darwin: strip Python.app launcher from packaged macOS xcframework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPython's macOS framework build embeds Python.app under Python.framework/Versions//Resources/Python.app. The launcher's Mach-O carries the configure-time --enable-framework path as a hardcoded `LC_LOAD_DYLIB` load command: /Users/runner/work/python-build/python-build/darwin/install/ macOS/macosx/python-X.Y.Z/Python.framework/Versions/X.Y/Python DYLD can't resolve that path on any machine other than the runner that produced the build. The CPython source tree's `make install` doesn't post-process this — Beeware's Python-Apple-support patches install_names to @rpath, but we don't run that step. The consequence in downstream consumers: when the xcframework lands inside a host .app's Contents/Frameworks/Python.framework/, macOS LaunchServices' nested-bundle scan finds Python.app and tries to launch it, producing a "Python quit unexpectedly" crash report dialog every time a `flet build` artifact starts. flet-dev/serious-python is currently working around this by `find ... -name Python.app | xargs rm -rf` after extracting the tarball; that should live here, in the build pipeline. For the embedded-interpreter use case (which is all flet-dev/serious- python builds for) the launcher has no role: libdart_bridge dlopens Python.framework's main binary directly, the host application supplies the NSApplication context, and sys.executable resolves to the host app binary — Python.app would never be exercised. Iff a downstream consumer needs a true standalone macOS Python launcher they can take it directly from Python-Apple-support; we'd reintroduce a fix-up step then. For now: drop it. Proper upstream fix (Python-Apple-support relocating LC_LOAD_DYLIB to @rpath in Python.app) tracked as a follow-up. --- darwin/python-darwin-framework.exclude | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/darwin/python-darwin-framework.exclude b/darwin/python-darwin-framework.exclude index 0c1f1c6..3192509 100644 --- a/darwin/python-darwin-framework.exclude +++ b/darwin/python-darwin-framework.exclude @@ -14,6 +14,17 @@ ios-arm64_x86_64-simulator/Python.framework/Headers/module.modulemap macos-arm64_x86_64/Python.framework/Headers macos-arm64_x86_64/Python.framework/Versions/*/_CodeSignature macos-arm64_x86_64/Python.framework/Versions/*/Headers +# Standalone launcher app baked in by `make install` of CPython's framework +# build. Its Mach-O carries the configure-time `--enable-framework` prefix +# (e.g. /Users/runner/work/python-build/.../Python.framework/Versions/X.Y/ +# Python) as a hardcoded load command, so it can't dyld-load anywhere +# except the original build host. When the produced xcframework lands +# inside a host .app's Contents/Frameworks/, macOS LaunchServices scans +# nested .app bundles and tries to launch this one — every scan produces +# a "Python quit unexpectedly" dialog. It's never useful for the embedded +# Python use case (libdart_bridge dlopens the framework binary directly, +# the host app supplies the NSApplication context), so strip it here. +macos-arm64_x86_64/Python.framework/Versions/*/Resources/Python.app macos-arm64_x86_64/Python.framework/Versions/*/bin macos-arm64_x86_64/Python.framework/Versions/*/share macos-arm64_x86_64/Python.framework/Versions/*/include