Skip to content

Add support for iOS cross-platform virtual environments#2828

Merged
messense merged 6 commits intoPyO3:mainfrom
freakboy3742:ios-cross
Nov 7, 2025
Merged

Add support for iOS cross-platform virtual environments#2828
messense merged 6 commits intoPyO3:mainfrom
freakboy3742:ios-cross

Conversation

@freakboy3742
Copy link
Copy Markdown
Contributor

@freakboy3742 freakboy3742 commented Nov 7, 2025

Tools such as cibuildwheel and xbuild manage building wheels for iOS by using a cross-platform virtual environment - a valid virtual environment for the build platform that can "pretend" to be the target/host platform when asked for sysconfigdata. This is done by monkeypatching key values in the sys, sysconfig, platform and os module when the interpreter starts. Many of these environments also set sys.cross_compiling = True as an indicator that they aren't "real" environments.

Maturin's concept of "cross-compiling", however, has more to do with whether the interpreter that is running the Maturin build can be used to interrogate details about the Python install for the purpose of configuring a build. To that end, somewhat counterintuitively, a cross-platform venv isn't "cross platform" from the perspective of Maturin.

This PR makes 3 changes:

  1. It marks iOS builds as not being cross-platform. This ensures that the sysconfigdata values from the interpreter running maturin are passed to the build
  2. When the build has not been given an explicit --target, or --interpreter, the build interpreter will be interrogated to see if it is a cross-compilation environment - and if it is, the target implied by the platform is used for the build.
  3. When an explicit --interpreter has been provided, the target will be modified if the environment is a cross-platform environment.

When combined with #2827, this means it is possible to create an iOS wheel with no more than maturin build, provided you're in an iOS cross-platform venv (such as those created by cibuildwheel and xbuild).

@messense
Copy link
Copy Markdown
Member

messense commented Nov 7, 2025

Thanks for the PR, having to use cibuildwheel or xbuild to compile iOS wheel is probably fine, but I just want to ask if it's possible to do it without them by only using maturin build and a working Xcode installation?

@freakboy3742
Copy link
Copy Markdown
Contributor Author

Thanks for the PR, having to use cibuildwheel or xbuild to compile iOS wheel is probably fine, but I just want to ask if it's possible to do it without them by only using maturin build and a working Xcode installation?

Yes, a build is possible without using cibuildwheel or xbuild; however, you also need to:

  1. Explicitly specify the target (i.e., maturin build --target aarch64-apple-ios)
  2. Configure your project so that it manually adds in the linking flags that are needed to ensure the iOS Python framework is linked into the module.

The benefit of the cross environment approach is that both these details are managed for you.

(FYI - I've made one additional change from the original PR, so the the cross-platform target discovery is also performed when an interpreter is explicitly provided; python -m build does this, so it seemed worth including).

@messense
Copy link
Copy Markdown
Member

messense commented Nov 7, 2025

  • Explicitly specify the target (i.e., maturin build --target aarch64-apple-ios)

I don't see this as an issue, we always pass it in github actions (maturin-action) when cross-compiling

  • Configure your project so that it manually adds in the linking flags that are needed to ensure the iOS Python framework is linked into the module.

maturin build could learn to add the required framework linking flags as long as we can query it from Xcode?

@messense messense merged commit 43b4972 into PyO3:main Nov 7, 2025
43 checks passed
@freakboy3742 freakboy3742 deleted the ios-cross branch November 9, 2025 21:43
@freakboy3742
Copy link
Copy Markdown
Contributor Author

maturin build could learn to add the required framework linking flags as long as we can query it from Xcode?

That's the problem though - it's not something Xcode knows about. You need to know the location where the iOS version of Python is installed, which is specific to a given user's install, and the version that they have installed.

messense pushed a commit that referenced this pull request Nov 10, 2025
At present, when targeting an `abi3` build, Maturin will use a dummy
interpreter to provide build configuration details, unless the user
specifies an interpreter with `--interpreter`, or the target is
cross-compiling, or Windows is being targeted.

The use of a dummy interpreter when a real interpreter is available can
lead to the interpreter details that are available and defined in
`sysconfigdata` not being used as part of the build process.

This was discovered in the process of working on iOS support (see #2827
and #2828); although the iOS build environment *does* provide build
configuration details, those details were not being passed down to the
PyO3 build configuration. With those two patches (and some patches to
PyO3 - see PyO3/pyo3#5605 and PyO3/pyo3#5606), it was possible to build
a non-abi3 wheel; but this patch was needed to build an abi3 wheel.
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