@@ -446,6 +446,148 @@ used in ``python.sh``:
446
446
.. _wasmtime : https://wasmtime.dev
447
447
.. _WebAssembly : https://webassembly.org
448
448
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
+
449
591
.. _build-dependencies :
450
592
.. _deps-on-linux :
451
593
.. _macOS and OS X :
@@ -455,7 +597,7 @@ Install dependencies
455
597
====================
456
598
457
599
This section explains how to install additional extensions (e.g. ``zlib ``)
458
- on Linux and macOS .
600
+ on Linux, macOS and iOS .
459
601
460
602
.. tab :: Linux
461
603
@@ -597,6 +739,24 @@ on Linux and macOS.
597
739
598
740
On Windows, extensions are already included and built automatically.
599
741
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.
600
760
601
761
.. _regenerate_configure :
602
762
0 commit comments