Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

gh-138171: Migrate iOS testbed location and add Apple build script#138176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
freakboy3742 merged 17 commits intopython:mainfromfreakboy3742:apple-build
Sep 19, 2025

Conversation

@freakboy3742
Copy link
Contributor

@freakboy3742freakboy3742 commentedAug 27, 2025
edited
Loading

This script simplifies the process of configuring, compiling and packaging an XCframework for an Apple platform. This is an analog of the scripts used to build Android and Emscripten artefacts. It is a precursor to adding GitHub Action builds for iOS, and producing iOS build artefacts.

At present, it only supports iOS, but it has been constructed so that it could be used on any Apple platform (including, potentially, a redistributable macOS XCframework).

The simplest usage of this script is:

  $ python Apple ci iOS

which will:

  • Clean any pre-existing build artefacts
  • Configure and make a Python that can be used for the build
  • Configure and make a Python for each supported iOS architecture and ABI
  • Combine the outputs of the builds from the previous step into a single
    XCframework, merging binaries into a "fat" binary if necessary
  • Clone a copy of the testbed, configured to use the XCframework
  • Construct a tarball containing the release artefacts
  • Run the test suite using the generated XCframework.

This is the complete sequence that would be needed in CI to build and test a candidate release artefact. The output of the command will detect if it's running in a GitHub Actions and use output groups to make the log output easier to digest.

Each individual step can be invoked individually - there are commands toclean,configure-build,make-build,configure-host,make-host,package, andtest.

There is also abuild command that can be used to combine the configure and make steps for the build Python, an individual host, all hosts, or all builds.

One of the steps is to manage the download of binary artefacts; these artefacts are downloaded to thecross-build/downloads folder by default, but an alternate cache location can be provided.

There are three potentially controversial parts to this PR:

MovingiOS toApple/iOS

As part of recognising that iOS is one of (potentially) many Apple platforms, and to prevent future proliferation of top-level directories for other Apple platforms, it migrates the iOS folder into a top level Apple folder. This change isn't strictly required, but if we don't make this change now, there is potential for a proliferation of directories if/when we add support for tvOS, watchOS, visionOS, macCatalyst. It also provides a convenient home for "cross platform" apple concerns, like the testbed script and the build script itself, as well as place for the existing content in theMac directory to migrate to as part of a cleanup of macOS builds - something that@ned-deily has expressed an interest in doing1

Universal simulator binaries

This PR generates a build that includes x86_64 simulator binaries. The iOS simulator slice of the XCframework is effectively a "universal" build covering both x86_64 and ARM64; although it has to be compiled in 2 passes and binaries merged after the fact. It's possible to both compileand test x86_64 binaries on ARM64 machines (pass--simulator "iPhone 16e,arch=x86_64" to theci ortest target, or to the testbed script), although running the test suite in emulator mode currently causes some test failure related tobuild-details.json not being fully cross-platform aware.

x86_64 isn't a Tier 3 platform for Python due to the difficulties of commissioning a buildbot; but x86_64 is still a supported platform for Apple. If we're going to produce official binaries, it seems to me like we should still support x86_64.

If we choose not to support x86_64, then there will be some changes required to the build script and testbed, as the name of the simulator slice will change fromios_arm64_x86_64_simulator toios_arm64_simulator. It would also allow removing the most complicated part of this script - the part that does the merging of binaries.

Backporting to 3.13 and 3.14

I've proposed this for backport to 3.13 and 3.14. This is primarily so that the buildbots can be migrated to use this script, and CI jobs can be added for iOS. The directory reorganization is a significant change to make in a backport, especially in the year-old 3.13 release; however, when I floated this idea at the CPython core team summit,@Yhg1s suggested1 that while it is a big change, the set of affected iOS users would be small, so the impact wasn't a huge concern.


NOTE: This PR currently contains a duplicate of theiOS/Resources/bin directory; this is needed because the location is hard-coded into the buildbots. Once the location change is confirmed, I can add the new path to the buildbot configuration, and remove the duplicate bin scripts.


📚 Documentation preview 📚:https://cpython-previews--138176.org.readthedocs.build/

Footnotes

  1. https://pyfound.blogspot.com/2025/06/python-language-summit-2025-python-on-mobile.html2

@freakboy3742

This comment was marked as resolved.

@bedevere-bot

This comment was marked as outdated.

@freakboy3742
Copy link
ContributorAuthor

The buildbot initially failed because the buildbot configuration references the olderiOS/Resource/bin location. As an immediate workaround, I've restored the shims to their old location; if the directory move is accepted as a change, then I can modify the buildbot and remove the duplicate.

@freakboy3742

This comment was marked as outdated.

@bedevere-bot

This comment was marked as outdated.

@freakboy3742
Copy link
ContributorAuthor

!buildbot iOS

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@freakboy3742 for commit68d671b 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F138176%2Fmerge

The command will test the builders whose names match following regular expression:iOS

The builders matched are:

  • iOS ARM64 Simulator PR

@AA-Turner
Copy link
Member

@freakboy3742 I imagine the CODEOWNERS entries will need updating in this PR?

freakboy3742 reacted with thumbs up emoji

.gitignore Outdated
Comment on lines 77 to 80
Apple/testbed/Python.xcframework/*-*/bin
Apple/testbed/Python.xcframework/*-*/include
Apple/testbed/Python.xcframework/*-*/lib
Apple/testbed/Python.xcframework/*-*/Python.framework
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Do we need*-* or would a simpler* pattern work?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Hrm - you may be right. I used the*-* pattern because there are files in that folder that need to be version controlled (most notably,Info.plist), but when combined with the suffixes, they should be unique.

Copy link
Member

@hugovkhugovk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

+1 to moving these underApple.

Or should we go a step further and have abuild,platform or$bikeshed dir for all of Apple, Android and PC, and whatever comes next (Linux?)



defunpack_deps(host,prefix_dir,cache_dir=None):
deps_url="https://github.com/beeware/cpython-apple-source-deps/releases/download"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Are there plans to move this underhttps://github.com/python/?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yes.@emmatypingstarted a pre-PEP discussion recently about consolidating the various repos we have into a single "binary dependency management repo", so that we have a single source for all (or as many as possible) of the build systems as possible. iOS and Android binaries (which are both currently BeeWare hosted) are part of those discussions.

If there's a more pressing interest for an interim solution, I'm happy to transfer ownership of both the iOS and Android repos to the Python org, or to give maintainer access to the existing repos any core team member who wants it.

hugovk and mhsmith reacted with thumbs up emoji
freakboy3742and others added3 commitsAugust 29, 2025 07:25
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
@freakboy3742
Copy link
ContributorAuthor

I've just pushed an update that makes the final distribution size significantly better - it's now ~75MB compressed (down from ~140MB).

This has been achieved by:

  1. Providing a top-level copy of the standard library (inPython.XCframework/lib that contains all thenon-platform specific files
  2. Providing a platform and architecture specificlib-ARCH folders in each XCframework slice. This directory contains thesysconfigdata,sysconfig_vars,build-details.json, andlib-dynload files for each architecture.
  3. There's aPython.XCframework/build folder that contains autils.sh script; this script includes an updated version of the scripts that have historically been used to copy and sign the standard library. In any given build, this script merges the non-platform-specific and platform-specific parts of the standard library into a single library folder in the app bundle.

This means there is essentially no duplicated content in the distribution artefact; and we have a lot more liberty to modify XCframework structure over time, as we can update the build script in parallel with any structural changes in the XCframework. It also means we can move the dylib-Info-template.plist file into the XCframework as a build resource, rather than requiring the user to explicitly add it to their own project.

I've updated the user documentation to describe how to use the build script, which significantly simplifies those usage instructions.

mhsmith reacted with thumbs up emoji

Copy link
Member

@ned-deilyned-deily left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks for addressing the previous comments. I built and tested this commit usingpython3.13 Apple build iOS andpython3.13 Apple build test with the iOS 26 SDK on an Apple Silicon Mac running macOS Tahoe (26.0) and Xcode 26.0 as well as on an Intel Mac running macOS Sequoia (15.6.1) and Xcode (16.4). There were no Python test suite failures on either build.

@freakboy3742freakboy3742 removed needs backport to 3.13bugs and security fixes needs backport to 3.14bugs and security fixes labelsSep 19, 2025
@freakboy3742
Copy link
ContributorAuthor

After a discussion with@ambv, I think we don't need to backport this after all. The motivation to backport was so that we buildbots could use the new directory structure and build scripts. This is required because the buildbot can't currently differentiate PR builds based on the underlying Python version.

However, if we fix that underlying problem, we don't need to backport, as we can retain "old style" builds for pre-3.15, and use new-style builds going forward.

On that basis, I'll merge this to main, but not backport, and target adding iOS binaries for 3.15.

ned-deily reacted with thumbs up emoji

@freakboy3742
Copy link
ContributorAuthor

!buildbot iOS

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@freakboy3742 for commitebbbf32 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F138176%2Fmerge

The command will test the builders whose names match following regular expression:iOS

The builders matched are:

  • iOS ARM64 Simulator PR

@freakboy3742
Copy link
ContributorAuthor

!buildbot iOS

@bedevere-bot
Copy link

🤖 New build scheduled with the buildbot fleet by@freakboy3742 for commite0f6b5a 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F138176%2Fmerge

The command will test the builders whose names match following regular expression:iOS

The builders matched are:

  • iOS ARM64 Simulator PR

"--timeout=-1",
# Adding Python options requires the use of a subprocess to
# start a new Python interpreter.
"--dont-add-python-opts",
Copy link
Member

@mhsmithmhsmithSep 19, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

--dont-add-python-opts may reduce the effectiveness of the tests: see#138805 (comment).

However, resolving this in the Android testbed required a fairly significant refactoring, so since this PR doesn't make the iOS situation any worse, it's probably best left to a separate PR.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I'm not sure I agree it'sreducing effectiveness. It's preventing the use of a code branch that would otherwise be invoked as a consequence of using--fast-ci or--slow-ci; if that problem code branchis invoked, the test suite crashes. Using--fast-ci/--slow-ci improves testing consistency; the options that aren't being processed as a result of using this flag weren't being used previously, either.

I agree that the Python options that are enabled by that code branch should be factored into the iOS testbed - but as you have flagged, that would requires a much more substantial refactor, and it can be handled independently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sounds good. FYI, the reason why I made the Android testbed accept Python options on the command line, rather than hard-coding the options expected by the CPython test suite, is that some of those options might not be appropriate for third-party package tests run by cibuildwheel.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Sure - that makes sense. I've got some ideas for how this could be managed in the context of the iOS testbed - we can read options out of the Info.plist file to separate test suite options from interpreter options.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I found it simpler not to separate them at all, but to letPyConfig_SetBytesArgv handle both of them at once, just like in a normal Python executable.

@freakboy3742freakboy3742 merged commit35c7e52 intopython:mainSep 19, 2025
46 checks passed
@freakboy3742freakboy3742 deleted the apple-build branchSeptember 19, 2025 12:23
@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure⚠️⚠️⚠️

Hi! The buildbotx86 Debian Non-Debug with X 3.x (no tier) has failed when building commit35c7e52.

What do you need to do:

  1. Don't panic.
  2. Checkthe buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/1245/builds/6433) and take a look at the build logs.
  4. Check if the failure is related to this commit (35c7e52) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1245/builds/6433

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0mreturn func(*args,**kwds)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m596�[0m, in �[35mtest_interrupt�[0m    exitcode=self._kill_process(multiprocessing.Process.interrupt)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0mreturn func(*args,**kwds)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m577�[0m, in �[35m_kill_process�[0mself.assertEqual(�[31mjoin�[0m�[1;31m()�[0m,None)                     �[31m~~~~�[0m�[1;31m^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m250�[0m, in �[35m__call__�[0mreturn �[31mself.func�[0m�[1;31m(*args,**kwds)�[0m           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/process.py"�[0m, line �[35m156�[0m, in �[35mjoin�[0m    res=self._popen.wait(timeout)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/popen_fork.py"�[0m, line �[35m44�[0m, in �[35mwait�[0mreturn �[31mself.poll�[0m�[1;31m(os.WNOHANGif timeout==0.0else0)�[0m           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/popen_fork.py"�[0m, line �[35m28�[0m, in �[35mpoll�[0m    pid, sts= �[31mos.waitpid�[0m�[1;31m(self.pid, flag)�[0m               �[31m~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m573�[0m, in �[35mhandler�[0mraiseRuntimeError('join took too long:%s'% p)�[1;35mRuntimeError�[0m:�[35mjoin took too long: <Process name='Process-1' pid=28784 parent=28782 started daemon>�[0mTraceback (most recent call last):  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0mreturn func(*args,**kwds)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m596�[0m, in �[35mtest_interrupt�[0m    exitcode=self._kill_process(multiprocessing.Process.interrupt)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/contextlib.py"�[0m, line �[35m85�[0m, in �[35minner�[0mreturn func(*args,**kwds)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m577�[0m, in �[35m_kill_process�[0mself.assertEqual(�[31mjoin�[0m�[1;31m()�[0m,None)                     �[31m~~~~�[0m�[1;31m^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m250�[0m, in �[35m__call__�[0mreturn �[31mself.func�[0m�[1;31m(*args,**kwds)�[0m           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/process.py"�[0m, line �[35m156�[0m, in �[35mjoin�[0m    res=self._popen.wait(timeout)  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/popen_fork.py"�[0m, line �[35m44�[0m, in �[35mwait�[0mreturn �[31mself.poll�[0m�[1;31m(os.WNOHANGif timeout==0.0else0)�[0m           �[31m~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/multiprocessing/popen_fork.py"�[0m, line �[35m28�[0m, in �[35mpoll�[0m    pid, sts= �[31mos.waitpid�[0m�[1;31m(self.pid, flag)�[0m               �[31m~~~~~~~~~~�[0m�[1;31m^^^^^^^^^^^^^^^^�[0m  File �[35m"/buildbot/buildarea/3.x.ware-debian-x86.nondebug/build/Lib/test/_test_multiprocessing.py"�[0m, line �[35m573�[0m, in �[35mhandler�[0mraiseRuntimeError('join took too long:%s'% p)�[1;35mRuntimeError�[0m:�[35mjoin took too long: <Process name='Process-158' pid=21525 parent=20497 started daemon>�[0m

@freakboy3742freakboy3742 added the needs backport to 3.14bugs and security fixes labelSep 21, 2025
@miss-islington-app
Copy link

Thanks@freakboy3742 for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Sorry,@freakboy3742, I could not cleanly backport this to3.14 due to a conflict.
Please backport usingcherry_picker on command line.

cherry_picker 35c7e52b3ea3fdeb8eb77d2d8c803467a2ba6311 3.14

@freakboy3742
Copy link
ContributorAuthor

After a conversation with@hugovk, it might be worth back porting this to 3.14 so that it is in 3.14 final; even if we don't do a binary release until a 3.14.1 or later - or at all - having the directory renamed will make other maintenance and back porting easier.

freakboy3742 added a commit to freakboy3742/cpython that referenced this pull requestSep 21, 2025
…ipt (python#138176)Adds tooling to generate and test an iOS XCframework, in a way that will also facilitateadding other XCframework targets for other Apple platforms (tvOS, watchOS, visionOS andeven macOS, potentially).---------Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>(cherry picked from commit35c7e52)
@bedevere-app
Copy link

GH-139204 is a backport of this pull request to the3.14 branch.

@bedevere-appbedevere-appbot removed the needs backport to 3.14bugs and security fixes labelSep 21, 2025
freakboy3742 added a commit to freakboy3742/cpython that referenced this pull requestSep 28, 2025
…ipt (python#138176)Adds tooling to generate and test an iOS XCframework, in a way that will also facilitateadding other XCframework targets for other Apple platforms (tvOS, watchOS, visionOS andeven macOS, potentially).---------Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
hugovk added a commit that referenced this pull requestSep 29, 2025
…ript (#138176) (#139204)Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
freakboy3742 added a commit to freakboy3742/cpython that referenced this pull requestOct 8, 2025
…ild script (python#138176)Adds tooling to generate and test an iOS XCframework, in a way that will also facilitateadding other XCframework targets for other Apple platforms (tvOS, watchOS, visionOS andeven macOS, potentially).---------Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@mhsmithmhsmithmhsmith left review comments

@hugovkhugovkhugovk left review comments

@AA-TurnerAA-TurnerAA-Turner left review comments

@ned-deilyned-deilyned-deily approved these changes

@erlend-aaslanderlend-aaslandAwaiting requested review from erlend-aaslanderlend-aasland is a code owner

@corona10corona10Awaiting requested review from corona10corona10 is a code owner

@ezio-melottiezio-melottiAwaiting requested review from ezio-melottiezio-melotti is a code owner

@emmatypingemmatypingAwaiting requested review from emmatypingemmatyping is a code owner

Assignees

@freakboy3742freakboy3742

Labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

6 participants

@freakboy3742@bedevere-bot@AA-Turner@ned-deily@mhsmith@hugovk

[8]ページ先頭

©2009-2025 Movatter.jp