@@ -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
457599This 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