Skip to content

Commit 006f03f

Browse files
FeodorFitsnerclaude
andcommitted
Build Python from source for darwin/iOS; de-pin Linux; bump to 3.12.13/3.13.13/3.14.5
Move iOS/macOS off the beeware Python-Apple-support repo onto CPython's standard build mechanism, and stop hand-pinning the Linux python-build-standalone release. macOS (build_macos.py): universal2 Python.framework built from source for all versions. OpenSSL + xz (+ zstd on 3.14) built universal2 from source (the macOS SDK ships neither OpenSSL nor lzma.h); OpenSSL is shared and bundled into the framework with @rpath install names, matching the released layout; binaries stripped. iOS (build_ios.py): one unified path using CPython's in-tree `Apple build iOS` tool. 3.14 is native; 3.13/3.12 apply a vendored back-port patch (ios_patches/) that adds the Apple tooling (+ the PEP 730 runtime for 3.12) -- no dependency on the Python-Apple-support repo. Reshapes the cross-build output into both the dart bundle and the mobile-forge install/support tree (per-arch dep dirs, VERSIONS, bin stub, platform-config sysconfig), and embeds the iOS deployment version into HOST_GNU_TYPE so mobile-forge's crossenv resolves the iOS release. Linux (resolve_pbs.py): auto-resolve the newest python-build-standalone release for the target micro+arch (PYTHON_DIST_RELEASE kept as optional override); keep x86_64_v2. Workflows: bump matrix to 3.12.13/3.13.13/3.14.5, darwin runner -> macos-26, and only publish GitHub release assets from the main branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3622069 commit 006f03f

17 files changed

Lines changed: 22152 additions & 27 deletions

.github/workflows/build-python-version.yml

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,21 @@ on:
1414
required: true
1515
type: choice
1616
options:
17-
- 3.12.12
18-
- 3.13.12
19-
- 3.14.3
17+
- 3.12.13
18+
- 3.13.13
19+
- 3.14.5
2020

2121
env:
2222
PYTHON_VERSION: ${{ inputs.python_version || github.event.inputs.python_version }}
23-
PYTHON_DIST_RELEASE: 20260203 # https://github.com/astral-sh/python-build-standalone/releases
23+
# Optional override: pin a specific python-build-standalone release date
24+
# (https://github.com/astral-sh/python-build-standalone/releases). When empty,
25+
# linux/package-for-linux.sh auto-resolves the newest release for PYTHON_VERSION.
26+
PYTHON_DIST_RELEASE: ""
2427

2528
jobs:
2629
build-darwin:
2730
name: Build Python for iOS and macOS
28-
runs-on: macos-15
31+
runs-on: macos-26
2932
permissions:
3033
contents: write
3134

@@ -49,17 +52,21 @@ jobs:
4952
working-directory: darwin
5053
shell: bash
5154
run: |
52-
git clone --branch="$PYTHON_VERSION_SHORT" https://github.com/beeware/Python-Apple-support.git
5355
mkdir -p dist
5456
55-
pushd Python-Apple-support
56-
make iOS
57-
tar -czf ../dist/python-ios-mobile-forge-$PYTHON_VERSION_SHORT.tar.gz install support -C .
58-
make macOS
59-
popd
57+
# iOS: 3.14+ uses CPython's in-tree Apple tooling, 3.13 builds from source per
58+
# iOS/README.rst, 3.12 uses beeware. Emits normalized ./install + ./support.
59+
python build_ios.py "$PYTHON_VERSION"
6060
61-
bash ./package-ios-for-dart.sh Python-Apple-support "$PYTHON_VERSION_SHORT"
62-
bash ./package-macos-for-dart.sh Python-Apple-support "$PYTHON_VERSION_SHORT"
61+
# mobile-forge artifact: iOS-only install+support tree (same structure as before).
62+
# Captured before the macOS build also writes into ./support / ./install.
63+
tar -czf dist/python-ios-mobile-forge-$PYTHON_VERSION_SHORT.tar.gz install support
64+
65+
# macOS: universal2 framework built from source (all versions).
66+
python build_macos.py "$PYTHON_VERSION"
67+
68+
bash ./package-ios-for-dart.sh . "$PYTHON_VERSION_SHORT"
69+
bash ./package-macos-for-dart.sh . "$PYTHON_VERSION_SHORT"
6370
6471
- name: Upload Darwin build artifacts
6572
uses: actions/upload-artifact@v4
@@ -124,6 +131,9 @@ jobs:
124131
- run: python --version
125132
- working-directory: linux
126133
shell: bash
134+
env:
135+
# Lets resolve_pbs.py authenticate to the GitHub API and avoid rate limits.
136+
GITHUB_TOKEN: ${{ github.token }}
127137
run: |
128138
bash ./package-for-linux.sh x86_64 "_v2"
129139
bash ./package-for-linux.sh aarch64 ""
@@ -169,6 +179,9 @@ jobs:
169179
publish-release:
170180
name: Publish Release Assets
171181
runs-on: ubuntu-latest
182+
# Only publish GitHub release assets from the main branch; other branches still
183+
# build (and upload per-job artifacts) but don't touch releases.
184+
if: github.ref == 'refs/heads/main'
172185
needs:
173186
- build-darwin
174187
- build-android

.github/workflows/build-python.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
python_version:
16-
- 3.12.12
17-
- 3.13.12
18-
- 3.14.3
16+
- 3.12.13
17+
- 3.13.13
18+
- 3.14.5
1919
uses: ./.github/workflows/build-python-version.yml
2020
with:
2121
python_version: ${{ matrix.python_version }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

darwin/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@
22
/Python-Apple-support
33
/dist
44
/build
5+
/install
6+
/support
7+
/downloads
8+
/deps
9+
__pycache__/
510
.DS_Store

darwin/README.rst

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,72 @@
1-
Python Apple Support
2-
====================
1+
Darwin (iOS / macOS) Python builds
2+
==================================
33

4-
Building iOS and macOS "support" builds out of https://github.com/beeware/Python-Apple-support to use with Flet.
4+
Builds embeddable iOS and macOS Python runtimes for Flet, packaged for the Dart/Flutter
5+
side and for `mobile-forge <https://github.com/flet-dev/mobile-forge>`__.
6+
7+
Both ``build_ios.py`` and ``build_macos.py`` emit the same normalized layout, which the
8+
``package-*-for-dart.sh`` scripts (and the mobile-forge tarball) consume::
9+
10+
install/iOS/<target>/python-<ver>/... # per-arch installs incl. lib-dynload
11+
install/macOS/macosx/python-<ver>/Python.framework
12+
support/<short>/iOS/Python.xcframework # device + fat-simulator slices
13+
support/<short>/macOS/Python.xcframework # universal2 (macos-arm64_x86_64)
14+
15+
where ``<target>`` is ``iphoneos.arm64``, ``iphonesimulator.arm64`` or
16+
``iphonesimulator.x86_64``.
17+
18+
iOS — ``build_ios.py <full-version>``
19+
-------------------------------------
20+
21+
Every version is built with the **same** mechanism — CPython's in-tree ``Apple`` build
22+
tool (``python Apple build iOS``) — then ``cross-build/`` is reshaped into the layout above:
23+
24+
* **3.14+** — the ``Apple/`` tooling is native; build straight from the source tarball.
25+
* **3.13 / 3.12** — the tooling (and, for 3.12, the PEP 730 iOS runtime) isn't upstream
26+
yet, so a vendored back-port patch (``ios_patches/<short>/Python.patch``, see that
27+
directory's README) is applied first to add it. No dependency on beeware's
28+
Python-Apple-support repo.
29+
30+
The Apple tool downloads its own pre-compiled C deps (from
31+
`cpython-apple-source-deps <https://github.com/beeware/cpython-apple-source-deps>`__ — the
32+
URL CPython itself hard-codes, for every version), builds all slices, and creates the
33+
xcframework. Output is tee'd to ``build/iOS/build-ios-<ver>.log``.
34+
35+
The reshape also rebuilds the ``install``/``support`` tree that
36+
`mobile-forge <https://github.com/flet-dev/mobile-forge>`__ consumes (the
37+
``python-ios-mobile-forge-<short>.tar.gz`` artifact): per-arch ``install/iOS/<arch>/<dep>-<ver>/``
38+
dirs (re-extracted from the deps the Apple tool downloaded) + a ``support/<short>/iOS/VERSIONS``
39+
listing those versions, and in each xcframework slice a stub ``bin/python<short>`` plus the
40+
``_sysconfigdata`` under ``platform-config/<arch>-<sdk>/`` — the spots mobile-forge's
41+
``crossenv`` setup looks for. (The dart packager excludes all of these from its bundle.)
42+
43+
macOS — ``build_macos.py <full-version>``
44+
-----------------------------------------
45+
46+
Builds a universal2 ``Python.framework`` **from source** for all versions, then makes it
47+
relocatable (``@rpath``), codesigns it, and wraps it in an xcframework. Building from
48+
source (rather than re-bundling python.org's official ``.pkg``) means we get the exact
49+
micro version even when no macOS installer was published for it.
50+
51+
The macOS SDK supplies headers for bz2/sqlite/zlib/libffi and CPython bundles libmpdec,
52+
but it ships **no OpenSSL** and **no lzma.h** (only ``liblzma.dylib``), so **OpenSSL** and
53+
**xz/liblzma** are built universal2 from source here (``--openssl-version`` / ``--xz-version``).
54+
To match the official/beeware layout, OpenSSL is built **shared** and bundled into the
55+
framework (``Versions/<short>/lib/lib{ssl,crypto}.3.dylib``) with ``@rpath`` install names,
56+
which ``_ssl``/``_hashlib`` reference (the embedding host — e.g. serious_python — provides
57+
the rpath, exactly as the released artifact does); xz is linked **statically** into
58+
``_lzma``. On 3.14+, libzstd is also built from source (``--zstd-version``) and linked
59+
statically into ``_zstd`` (new in 3.14). All binaries are stripped (``strip -x``) before
60+
codesigning. Pass
61+
``--app-store-compliance`` to apply ``macos_support/app-store-compliance.patch`` (off by
62+
default; only for Mac App Store). Full build output is tee'd to
63+
``build/macOS/build-macos-<ver>.log``.
64+
65+
Packaging
66+
---------
67+
68+
``package-ios-for-dart.sh . <short>`` and ``package-macos-for-dart.sh . <short>`` turn the
69+
normalized layout into the Dart-consumable ``dist/python-{ios,macos}-dart-<short>.tar.gz``
70+
archives, reusing ``xcframework_utils.sh``, ``Modules/`` and the ``*.exclude`` lists.
71+
72+
This whole flow is driven in CI by ``.github/workflows/build-python-version.yml``.

0 commit comments

Comments
 (0)