Skip to content

Commit 45f7b02

Browse files
freakboy3742ezio-melottihugovk
authored
Add iOS instructions to the devguide (#1296)
Co-authored-by: Ezio Melotti <[email protected]> Co-authored-by: Hugo van Kemenade <[email protected]>
1 parent d92fda3 commit 45f7b02

File tree

2 files changed

+169
-1
lines changed

2 files changed

+169
-1
lines changed

README.rst

+8
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ Render HTML
2727
To render the devguide to HTML under ``_build/html``, run::
2828

2929
make html
30+
31+
To render the devguide to HTML, and open the result in a browser, run::
32+
33+
make htmlview
34+
35+
To maintain a live view of edits as they are saved, run::
36+
37+
make htmllive

getting-started/setup-building.rst

+161-1
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,148 @@ used in ``python.sh``:
446446
.. _wasmtime: https://wasmtime.dev
447447
.. _WebAssembly: https://webassembly.org
448448

449+
iOS
450+
---
451+
452+
Compiling Python for iOS requires a macOS machine, on a recent version of macOS,
453+
running a recent version of Xcode. Apple expects developers to keep their
454+
operating systems and tools up-to-date; if your macOS version is more than one
455+
major release out of date, or your Xcode version is more than a couple of minor
456+
versions out of date, you'll likely encounter difficulties. It is not possible
457+
to compile for iOS using Windows or Linux as a build machine.
458+
459+
A complete build for Python on iOS requires compiling CPython four times: once for
460+
macOS; then once for each of the three underlying platforms used by iOS:
461+
462+
* An ARM64 device (an iPhone or iPad);
463+
* An ARM64 simulator running on a recent macOS machine; and
464+
* An x86_64 simulator running on older macOS machine.
465+
466+
The macOS build is required because building Python involves running some Python
467+
code. On a normal desktop build of Python, you can compile a Python interpreter
468+
and then use that interpreter to run Python code. However, the binaries produced
469+
for iOS won't run on macOS, so you need to provide an external Python
470+
interpreter. From the root of a CPython code checkout, run the following::
471+
472+
$ ./configure --prefix=$(pwd)/cross-build/macOS
473+
$ make -j4 all
474+
$ make install
475+
476+
This will build and install Python for macOS into the ``cross-build/macOS``
477+
directory.
478+
479+
The CPython build system can compile a single platform at a time. It is possible
480+
to *test* a single platform at a time; however, for distribution purposes, you
481+
must compile all three, and merge the results. See the `iOS README
482+
<https://github.com/python/cpython/blob/main/iOS/README.rst#merge-thin-frameworks-into-fat-frameworks>`__
483+
for details on this merging process.
484+
485+
The following instructions will build CPython for iOS with all extensions
486+
enabled, provided you have installed the build dependencies XZ, BZip2, OpenSSL
487+
and libFFI in subfolders of the ``cross-build`` folder. See :ref:`the iOS
488+
section on installing build dependencies <build-dependencies>` for details on
489+
how to obtain these dependencies. These dependencies are all strictly optional,
490+
however, including libFFI is *highly* recommended, as it is required by the
491+
:py:mod:`ctypes` module which is used on iOS to support accessing native system APIs.
492+
493+
.. tab:: ARM64 device
494+
495+
.. code-block:: console
496+
497+
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
498+
$ ./configure \
499+
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/xz/include" \
500+
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/xz/lib -llzma" \
501+
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/bzip2/include" \
502+
BZIP2_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/bzip2/lib -lbz2" \
503+
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphoneos.arm64/libffi/include" \
504+
LIBFFI_LIBS="-L$(pwd)/cross-build/iphoneos.arm64/libffi/lib -lffi" \
505+
--with-openssl="$(pwd)/cross-build/iphoneos.arm64/openssl" \
506+
--host=arm64-apple-ios12.0 \
507+
--build=arm64-apple-darwin \
508+
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
509+
--enable-framework
510+
$ make -j4 all
511+
$ make install
512+
513+
.. tab:: ARM64 simulator
514+
515+
.. code-block:: console
516+
517+
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
518+
$ ./configure \
519+
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/xz/include" \
520+
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/xz/lib -llzma" \
521+
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/bzip2/include" \
522+
BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/bzip2/lib -lbz2" \
523+
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.arm64/libffi/include" \
524+
LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.arm64/libffi/lib -lffi" \
525+
--with-openssl="$(pwd)/cross-build/iphonesimulator.arm64/openssl" \
526+
--host=arm64-apple-ios12.0-simulator \
527+
--build=arm64-apple-darwin \
528+
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
529+
--enable-framework
530+
$ make -j4 all
531+
$ make install
532+
533+
.. tab:: x86-64 simulator
534+
535+
.. code-block:: console
536+
537+
$ export PATH="$(pwd)/iOS/Resources/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin"
538+
$ ./configure \
539+
LIBLZMA_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/xz/include" \
540+
LIBLZMA_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/xz/lib -llzma" \
541+
BZIP2_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/include" \
542+
BZIP2_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/bzip2/lib -lbz2" \
543+
LIBFFI_CFLAGS="-I$(pwd)/cross-build/iphonesimulator.x86_64/libffi/include" \
544+
LIBFFI_LIBS="-L$(pwd)/cross-build/iphonesimulator.x86_64/libffi/lib -lffi" \
545+
--with-openssl="$(pwd)/cross-build/iphonesimulator.x86_64/openssl" \
546+
--host=x86_64-apple-ios12.0-simulator \
547+
--build=arm64-apple-darwin \
548+
--with-build-python=$(pwd)/cross-build/macOS/bin/python3.13 \
549+
--enable-framework
550+
$ make -j4 all
551+
$ make install
552+
553+
These instructions modify your ``PATH`` before the build. As iOS and macOS share
554+
a hardware architecture (ARM64), it is easy for a macOS ARM64 binary to be
555+
accidentally linked into your iOS build. This is especially common when Homebrew
556+
is present on the build system. The most reliable way to avoid this problem is
557+
to remove any potential source of other libraries from your ``PATH``.
558+
559+
However, the ``PATH`` is not completely bare --- it includes the
560+
``iOS/Resources/bin`` folder. This folder contains a collection of scripts that
561+
wrap the invocation of the Xcode :program:`xcrun` tool, removing user- and
562+
version-specific paths from the values encoded in the :py:mod:`sysconfig`
563+
module. Copies of these scripts are included in the final build products.
564+
565+
Once this build completes, the ``iOS/Frameworks`` folder will contain a
566+
``Python.framework`` that can be used for testing.
567+
568+
To run the test suite on iOS, complete a build for a *simulator* platform,
569+
ensure the path modifications from the build are still in effect, and run::
570+
571+
$ make testios
572+
573+
The full test suite takes approximately 12 minutes to run on a 2022 M1 MacBook
574+
Pro, plus a couple of extra minutes to build the testbed application and boot
575+
the simulator. There will be an initial burst of console output while the Xcode
576+
test project is compiled; however, while the test suite is running, there is no
577+
console output or progress. This is a side effect of how Xcode operates when
578+
executed at the command line. You should see an iOS simulator appear during the
579+
testing process; the simulator will booth to an iOS landing screen, the testbed
580+
app will be installed, and then started. The screen of the simulator will be
581+
black while the test suite is running. When the test suite completes, success or
582+
failure will be reported at the command line. In the case of failure, you will
583+
see the full log of CPython test suite output.
584+
585+
You can also run the test suite in Xcode itself. This is required if you want to
586+
run on a physical device; it is also the easiest approach if you need to run a
587+
single test, or a subset of tests. See the `iOS README
588+
<https://github.com/python/cpython/blob/main/iOS/README.rst#debugging-test-failures>`__
589+
for details.
590+
449591
.. _build-dependencies:
450592
.. _deps-on-linux:
451593
.. _macOS and OS X:
@@ -455,7 +597,7 @@ Install dependencies
455597
====================
456598

457599
This section explains how to install additional extensions (e.g. ``zlib``)
458-
on Linux and macOS.
600+
on Linux, macOS and iOS.
459601

460602
.. tab:: Linux
461603

@@ -597,6 +739,24 @@ on Linux and macOS.
597739

598740
On Windows, extensions are already included and built automatically.
599741

742+
.. tab:: iOS
743+
744+
As with CPython itself, the dependencies for CPython must be compiled for
745+
each of the hardware architectures that iOS supports. Consult the
746+
documentation for `XZ <https://xz.tukaani.org/xz-utils/>`__, `bzip2
747+
<https://sourceware.org/bzip2/>`__, `OpenSSL <https://www.openssl.org>`__ and
748+
`libffi <https://github.com/libffi/libffi>`__ for details on how to configure
749+
the project for cross-platform iOS builds.
750+
751+
Alternatively, the `BeeWare Project <https://beeware.org>`__ maintains a
752+
`project for building iOS dependencies
753+
<https://github.com/beeware/cpython-apple-source-deps>`__, and distributes
754+
`pre-compiled binaries
755+
<https://github.com/beeware/cpython-apple-source-deps/releases>`__ for each
756+
of the dependencies. If you use this project to build the dependencies
757+
yourself, the subfolders of the ``install`` folder can be used to configure
758+
CPython. If you use the pre-compiled binaries, you should unpack each tarball
759+
into a separate folder, and use that folder as the configuration target.
600760

601761
.. _regenerate_configure:
602762

0 commit comments

Comments
 (0)