700 lines
56 KiB
HTML
700 lines
56 KiB
HTML
|
|
|||
|
<!DOCTYPE html>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="utf-8">
|
|||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|||
|
<meta name="color-scheme" content="light dark">
|
|||
|
<title>PEP 730 – Adding iOS as a supported platform | peps.python.org</title>
|
|||
|
<link rel="shortcut icon" href="../_static/py.png">
|
|||
|
<link rel="canonical" href="https://peps.python.org/pep-0730/">
|
|||
|
<link rel="stylesheet" href="../_static/style.css" type="text/css">
|
|||
|
<link rel="stylesheet" href="../_static/mq.css" type="text/css">
|
|||
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" media="(prefers-color-scheme: light)" id="pyg-light">
|
|||
|
<link rel="stylesheet" href="../_static/pygments_dark.css" type="text/css" media="(prefers-color-scheme: dark)" id="pyg-dark">
|
|||
|
<link rel="alternate" type="application/rss+xml" title="Latest PEPs" href="https://peps.python.org/peps.rss">
|
|||
|
<meta property="og:title" content='PEP 730 – Adding iOS as a supported platform | peps.python.org'>
|
|||
|
<meta property="og:description" content="This PEP proposes adding iOS as a supported platform in CPython. The initial goal is to achieve Tier 3 support for Python 3.13. This PEP describes the technical aspects of the changes that are required to support iOS. It also describes the project manag...">
|
|||
|
<meta property="og:type" content="website">
|
|||
|
<meta property="og:url" content="https://peps.python.org/pep-0730/">
|
|||
|
<meta property="og:site_name" content="Python Enhancement Proposals (PEPs)">
|
|||
|
<meta property="og:image" content="https://peps.python.org/_static/og-image.png">
|
|||
|
<meta property="og:image:alt" content="Python PEPs">
|
|||
|
<meta property="og:image:width" content="200">
|
|||
|
<meta property="og:image:height" content="200">
|
|||
|
<meta name="description" content="This PEP proposes adding iOS as a supported platform in CPython. The initial goal is to achieve Tier 3 support for Python 3.13. This PEP describes the technical aspects of the changes that are required to support iOS. It also describes the project manag...">
|
|||
|
<meta name="theme-color" content="#3776ab">
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
|
|||
|
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
|||
|
<symbol id="svg-sun-half" viewBox="0 0 24 24" pointer-events="all">
|
|||
|
<title>Following system colour scheme</title>
|
|||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
|||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|||
|
<circle cx="12" cy="12" r="9"></circle>
|
|||
|
<path d="M12 3v18m0-12l4.65-4.65M12 14.3l7.37-7.37M12 19.6l8.85-8.85"></path>
|
|||
|
</svg>
|
|||
|
</symbol>
|
|||
|
<symbol id="svg-moon" viewBox="0 0 24 24" pointer-events="all">
|
|||
|
<title>Selected dark colour scheme</title>
|
|||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
|||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
|||
|
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z"></path>
|
|||
|
</svg>
|
|||
|
</symbol>
|
|||
|
<symbol id="svg-sun" viewBox="0 0 24 24" pointer-events="all">
|
|||
|
<title>Selected light colour scheme</title>
|
|||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"
|
|||
|
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|||
|
<circle cx="12" cy="12" r="5"></circle>
|
|||
|
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|||
|
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|||
|
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|||
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|||
|
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|||
|
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|||
|
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|||
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|||
|
</svg>
|
|||
|
</symbol>
|
|||
|
</svg>
|
|||
|
<script>
|
|||
|
|
|||
|
document.documentElement.dataset.colour_scheme = localStorage.getItem("colour_scheme") || "auto"
|
|||
|
</script>
|
|||
|
<section id="pep-page-section">
|
|||
|
<header>
|
|||
|
<h1>Python Enhancement Proposals</h1>
|
|||
|
<ul class="breadcrumbs">
|
|||
|
<li><a href="https://www.python.org/" title="The Python Programming Language">Python</a> » </li>
|
|||
|
<li><a href="../pep-0000/">PEP Index</a> » </li>
|
|||
|
<li>PEP 730</li>
|
|||
|
</ul>
|
|||
|
<button id="colour-scheme-cycler" onClick="setColourScheme(nextColourScheme())">
|
|||
|
<svg aria-hidden="true" class="colour-scheme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
|||
|
<svg aria-hidden="true" class="colour-scheme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|||
|
<svg aria-hidden="true" class="colour-scheme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|||
|
<span class="visually-hidden">Toggle light / dark / auto colour theme</span>
|
|||
|
</button>
|
|||
|
</header>
|
|||
|
<article>
|
|||
|
<section id="pep-content">
|
|||
|
<h1 class="page-title">PEP 730 – Adding iOS as a supported platform</h1>
|
|||
|
<dl class="rfc2822 field-list simple">
|
|||
|
<dt class="field-odd">Author<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd">Russell Keith-Magee <russell at keith-magee.com></dd>
|
|||
|
<dt class="field-even">Sponsor<span class="colon">:</span></dt>
|
|||
|
<dd class="field-even">Ned Deily <nad at python.org></dd>
|
|||
|
<dt class="field-odd">Discussions-To<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd"><a class="reference external" href="https://discuss.python.org/t/pep730-adding-ios-as-a-supported-platform/35854">Discourse thread</a></dd>
|
|||
|
<dt class="field-even">Status<span class="colon">:</span></dt>
|
|||
|
<dd class="field-even"><abbr title="Accepted and implementation complete, or no longer active">Final</abbr></dd>
|
|||
|
<dt class="field-odd">Type<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd"><abbr title="Normative PEP with a new feature for Python, implementation change for CPython or interoperability standard for the ecosystem">Standards Track</abbr></dd>
|
|||
|
<dt class="field-even">Created<span class="colon">:</span></dt>
|
|||
|
<dd class="field-even">09-Oct-2023</dd>
|
|||
|
<dt class="field-odd">Python-Version<span class="colon">:</span></dt>
|
|||
|
<dd class="field-odd">3.13</dd>
|
|||
|
<dt class="field-even">Resolution<span class="colon">:</span></dt>
|
|||
|
<dd class="field-even"><a class="reference external" href="https://discuss.python.org/t/pep-730-adding-ios-as-a-supported-platform/35854/66">Discourse message</a></dd>
|
|||
|
</dl>
|
|||
|
<hr class="docutils" />
|
|||
|
<section id="contents">
|
|||
|
<details><summary>Table of Contents</summary><ul class="simple">
|
|||
|
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
|||
|
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
|||
|
<li><a class="reference internal" href="#rationale">Rationale</a><ul>
|
|||
|
<li><a class="reference internal" href="#development-landscape">Development landscape</a></li>
|
|||
|
<li><a class="reference internal" href="#posix-compliance">POSIX compliance</a></li>
|
|||
|
<li><a class="reference internal" href="#dynamic-libraries">Dynamic libraries</a></li>
|
|||
|
<li><a class="reference internal" href="#console-and-interactive-usage">Console and interactive usage</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
|||
|
<li><a class="reference internal" href="#platform-identification">Platform identification</a><ul>
|
|||
|
<li><a class="reference internal" href="#sys"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#platform"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#os"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#sysconfig"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#subprocess-support">Subprocess support</a></li>
|
|||
|
<li><a class="reference internal" href="#dynamic-module-loading">Dynamic module loading</a></li>
|
|||
|
<li><a class="reference internal" href="#compilation">Compilation</a></li>
|
|||
|
<li><a class="reference internal" href="#distribution">Distribution</a></li>
|
|||
|
<li><a class="reference internal" href="#ci-resources">CI resources</a></li>
|
|||
|
<li><a class="reference internal" href="#packaging">Packaging</a></li>
|
|||
|
<li><a class="reference internal" href="#pep-11-update">PEP 11 Update</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
|||
|
<li><a class="reference internal" href="#security-implications">Security Implications</a></li>
|
|||
|
<li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li>
|
|||
|
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
|||
|
<li><a class="reference internal" href="#rejected-ideas">Rejected Ideas</a><ul>
|
|||
|
<li><a class="reference internal" href="#simulator-identification">Simulator identification</a></li>
|
|||
|
<li><a class="reference internal" href="#gnu-compiler-triples">GNU compiler triples</a></li>
|
|||
|
<li><a class="reference internal" href="#universal-wheel-format">“Universal” wheel format</a></li>
|
|||
|
<li><a class="reference internal" href="#supporting-static-builds">Supporting static builds</a></li>
|
|||
|
<li><a class="reference internal" href="#interactive-repl-mode">Interactive/REPL mode</a></li>
|
|||
|
<li><a class="reference internal" href="#x86-64-simulator-support">x86_64 simulator support</a></li>
|
|||
|
<li><a class="reference internal" href="#on-device-testing">On-device testing</a></li>
|
|||
|
<li><a class="reference internal" href="#ordering-of-multiarch-tags">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></li>
|
|||
|
<li><a class="reference internal" href="#values-returned-by-platform-ios-ver">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
|||
|
</ul>
|
|||
|
</details></section>
|
|||
|
<section id="abstract">
|
|||
|
<h2><a class="toc-backref" href="#abstract" role="doc-backlink">Abstract</a></h2>
|
|||
|
<p>This PEP proposes adding iOS as a supported platform in CPython. The initial
|
|||
|
goal is to achieve Tier 3 support for Python 3.13. This PEP describes the
|
|||
|
technical aspects of the changes that are required to support iOS. It also
|
|||
|
describes the project management concerns related to adoption of iOS as a Tier 3
|
|||
|
platform.</p>
|
|||
|
</section>
|
|||
|
<section id="motivation">
|
|||
|
<h2><a class="toc-backref" href="#motivation" role="doc-backlink">Motivation</a></h2>
|
|||
|
<p>Over the last 15 years, mobile platforms have become increasingly important
|
|||
|
parts of the computing landscape. iOS is one of two operating systems that
|
|||
|
control the vast majority of these devices. However, there is no official
|
|||
|
support for iOS in CPython.</p>
|
|||
|
<p>The <a class="reference external" href="https://beeware.org">BeeWare Project</a> and <a class="reference external" href="https://kivy.org">Kivy</a>
|
|||
|
have both supported iOS for almost 10 years. This support has been able to
|
|||
|
generate applications that have been accepted for publication in the iOS App
|
|||
|
Store. This demonstrates the technical feasibility of iOS support.</p>
|
|||
|
<p>It is important for the future of Python as a language that it is able to be
|
|||
|
used on any hardware or OS that has widespread adoption. If Python cannot be
|
|||
|
used a on a platform that has widespread use, adoption of the language will be
|
|||
|
impacted as potential users will adopt other languages that <em>do</em> provide support
|
|||
|
for these platforms.</p>
|
|||
|
</section>
|
|||
|
<section id="rationale">
|
|||
|
<h2><a class="toc-backref" href="#rationale" role="doc-backlink">Rationale</a></h2>
|
|||
|
<section id="development-landscape">
|
|||
|
<h3><a class="toc-backref" href="#development-landscape" role="doc-backlink">Development landscape</a></h3>
|
|||
|
<p>iOS provides a single API, but 2 distinct ABIs - <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code> (physical
|
|||
|
devices), and <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>. Each of these ABIs can be provided on
|
|||
|
multiple CPU architectures. At time of writing, Apple officially supports
|
|||
|
<code class="docutils literal notranslate"><span class="pre">arm64</span></code> on the device ABI, and <code class="docutils literal notranslate"><span class="pre">arm64</span></code> and <code class="docutils literal notranslate"><span class="pre">x86_64</span></code> are supported on the
|
|||
|
simulator ABI.</p>
|
|||
|
<p>As with macOS, iOS supports the creation of “fat” binaries that contains
|
|||
|
multiple CPU architectures. However, fat binaries <em>cannot</em> span ABIs. That is,
|
|||
|
it is possible to have a fat <em>simulator</em> binary, and a fat <em>device</em> binary, but
|
|||
|
it is not possible to create a single fat “iOS” binary that covers both
|
|||
|
simulator and device needs. To support distribution of a single development
|
|||
|
artefact, Apple uses an “XCframework” structure - a wrapper around multiple ABIs
|
|||
|
that implement a common API.</p>
|
|||
|
<p>iOS runs on a Darwin kernel, similar to macOS. However, there is a need to
|
|||
|
differentiate between macOS and iOS at an implementation level, as there are
|
|||
|
significant platform differences between iOS and macOS.</p>
|
|||
|
<p>iOS code is compiled for compatibility against a minimum iOS version.</p>
|
|||
|
<p>Apple frequently refers to “iPadOS” in their marketing material. However, from a
|
|||
|
development perspective, there is no discernable difference between iPadOS and
|
|||
|
iOS. A binary that has been compiled for the <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code> or <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>
|
|||
|
ABIs can be deployed on iPad.</p>
|
|||
|
<p>Other Apple platforms, such as tvOS, watchOS, and visionOS, use different ABIs,
|
|||
|
and are not covered by this PEP.</p>
|
|||
|
</section>
|
|||
|
<section id="posix-compliance">
|
|||
|
<h3><a class="toc-backref" href="#posix-compliance" role="doc-backlink">POSIX compliance</a></h3>
|
|||
|
<p>iOS is broadly a POSIX platform. However, similar to WASI/Emscripten, there are
|
|||
|
POSIX APIs that exist on iOS, but cannot be used; and POSIX APIs that don’t
|
|||
|
exist at all.</p>
|
|||
|
<p>Most notable of these is the fact that iOS does not provide any form of
|
|||
|
multiprocess support. <code class="docutils literal notranslate"><span class="pre">fork</span></code> and <code class="docutils literal notranslate"><span class="pre">spawn</span></code> both <em>exist</em> in the iOS API;
|
|||
|
however, if they are invoked, the invoking iOS process stops, and the new
|
|||
|
process doesn’t start.</p>
|
|||
|
<p>Unlike WASI/Emscripten, threading <em>is</em> supported on iOS.</p>
|
|||
|
<p>There are also significant limits to socket handling. Due to process sandboxing,
|
|||
|
there is no availability of interprocess communication via socket. However,
|
|||
|
sockets for network communication <em>are</em> available.</p>
|
|||
|
</section>
|
|||
|
<section id="dynamic-libraries">
|
|||
|
<h3><a class="toc-backref" href="#dynamic-libraries" role="doc-backlink">Dynamic libraries</a></h3>
|
|||
|
<p>The iOS <a class="reference external" href="https://developer.apple.com/app-store/review/guidelines">App Store guidelines</a> allow apps to be
|
|||
|
written in languages other than Objective C or Swift. However, they have very
|
|||
|
strict guidelines about the structure of apps that are submitted for
|
|||
|
distribution.</p>
|
|||
|
<p>iOS apps can use dynamically loaded libraries; however, there are very strict
|
|||
|
requirements on how dynamically loaded content is packaged for use on iOS:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li>Dynamic binary content must be compiled as dynamic libraries, not shared
|
|||
|
objects or binary bundles.</li>
|
|||
|
<li>They must be packaged in the app bundle as Frameworks.</li>
|
|||
|
<li>Each Framework can only contain a single dynamic library.</li>
|
|||
|
<li>The Framework <em>must</em> be contained in the iOS App’s <code class="docutils literal notranslate"><span class="pre">Frameworks</span></code> folder.</li>
|
|||
|
<li>A Framework may not contain any non-library content.</li>
|
|||
|
</ul>
|
|||
|
<p>This imposes some constraints on the operation of CPython. It is not possible
|
|||
|
store binary modules in the <code class="docutils literal notranslate"><span class="pre">lib-dynload</span></code> and/or <code class="docutils literal notranslate"><span class="pre">site-packages</span></code> folders;
|
|||
|
they must be stored in the app’s Frameworks folder, with each module wrapped in
|
|||
|
a Framework. This also means that the common assumption that a Python module can
|
|||
|
construct the location of a binary module by using the <code class="docutils literal notranslate"><span class="pre">__file__</span></code> attribute of
|
|||
|
the Python module no longer holds.</p>
|
|||
|
<p>As with macOS, compiling a binary module that is accessible from a
|
|||
|
statically-linked build of Python requires the use of the <code class="docutils literal notranslate"><span class="pre">--undefined</span>
|
|||
|
<span class="pre">dynamic_lookup</span></code> option to avoid linking <code class="docutils literal notranslate"><span class="pre">libpython3.x</span></code> into every binary
|
|||
|
module. However, on iOS, this compiler flag raises a deprecation warning when it
|
|||
|
is used. A warning from this flag has been observed on macOS as well - however,
|
|||
|
responses from Apple staff suggest that they <a class="reference external" href="https://github.com/python/cpython/issues/97524#issuecomment-1458855301">do not intend to break the CPython
|
|||
|
ecosystem by removing this option</a>. As
|
|||
|
Python does not currently have a notable presence on iOS, it is difficult to
|
|||
|
judge whether iOS usage of this flag would fall under the same umbrella.</p>
|
|||
|
</section>
|
|||
|
<section id="console-and-interactive-usage">
|
|||
|
<h3><a class="toc-backref" href="#console-and-interactive-usage" role="doc-backlink">Console and interactive usage</a></h3>
|
|||
|
<p>Distribution of a traditional CPython REPL or interactive “python.exe” should
|
|||
|
not be considered a goal of this work.</p>
|
|||
|
<p>Mobile devices (including iOS) do not provide a TTY-style console. They do not
|
|||
|
provide <code class="docutils literal notranslate"><span class="pre">stdin</span></code>, <code class="docutils literal notranslate"><span class="pre">stdout</span></code> or <code class="docutils literal notranslate"><span class="pre">stderr</span></code>. iOS provides a system log, and it
|
|||
|
is possible to install a redirection so that all <code class="docutils literal notranslate"><span class="pre">stdout</span></code> and <code class="docutils literal notranslate"><span class="pre">stderr</span></code>
|
|||
|
content is redirected to the system log; but there is no analog for <code class="docutils literal notranslate"><span class="pre">stdin</span></code>.</p>
|
|||
|
<p>In addition, iOS places restrictions on downloading additional code at runtime
|
|||
|
(as this behavior would be functionally indistinguishable from trying to work
|
|||
|
around App Store review). As a result, a traditional “create a virtual
|
|||
|
environment and pip install” development experience will not be viable on iOS.</p>
|
|||
|
<p>It is <em>possible</em> to build an native iOS application that provides a REPL
|
|||
|
interface. This would be closer to an IDLE-style user experience; however,
|
|||
|
Tkinter cannot be used on iOS, so any app would require a ground-up rewrite. The
|
|||
|
iOS app store already contains several examples of apps in this category (e.g.,
|
|||
|
<a class="reference external" href="http://www.omz-software.com/pythonista/">Pythonista</a> and <a class="reference external" href="https://pyto.readthedocs.io/">Pyto</a>). The focus of this work would be to provide
|
|||
|
an embedded distribution that IDE-style native interfaces could utilize, not a
|
|||
|
user-facing “app” interface to iOS on Python.</p>
|
|||
|
</section>
|
|||
|
</section>
|
|||
|
<section id="specification">
|
|||
|
<h2><a class="toc-backref" href="#specification" role="doc-backlink">Specification</a></h2>
|
|||
|
<section id="platform-identification">
|
|||
|
<h3><a class="toc-backref" href="#platform-identification" role="doc-backlink">Platform identification</a></h3>
|
|||
|
<section id="sys">
|
|||
|
<h4><a class="toc-backref" href="#sys" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></h4>
|
|||
|
<p><code class="docutils literal notranslate"><span class="pre">sys.platform</span></code> will identify as <code class="docutils literal notranslate"><span class="pre">"ios"</span></code> on both simulator and physical
|
|||
|
devices.</p>
|
|||
|
<p><code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code> will describe the ABI and CPU architecture:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">"arm64-iphoneos"</span></code> for ARM64 devices</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">"arm64-iphonesimulator"</span></code> for ARM64 simulators</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">"x86_64-iphonesimulator"</span></code> for x86_64 simulators</li>
|
|||
|
</ul>
|
|||
|
</section>
|
|||
|
<section id="platform">
|
|||
|
<h4><a class="toc-backref" href="#platform" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></h4>
|
|||
|
<p><code class="docutils literal notranslate"><span class="pre">platform</span></code> will be modified to support returning iOS-specific details. Most of
|
|||
|
the values returned by the <code class="docutils literal notranslate"><span class="pre">platform</span></code> module will match those returned by
|
|||
|
<code class="docutils literal notranslate"><span class="pre">os.uname()</span></code>, with the exception of:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">platform.system()</span></code> - <code class="docutils literal notranslate"><span class="pre">"iOS"</span></code> or <code class="docutils literal notranslate"><span class="pre">iPadOS</span></code> (depending on the hardware in
|
|||
|
use), instead of <code class="docutils literal notranslate"><span class="pre">"Darwin"</span></code></li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">platform.release()</span></code> - the iOS version number, as a string (e.g.,
|
|||
|
<code class="docutils literal notranslate"><span class="pre">"16.6.1"</span></code>), instead of the Darwin kernel version.</li>
|
|||
|
</ul>
|
|||
|
<p>In addition, a <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code> method will be added. This mirrors
|
|||
|
<code class="docutils literal notranslate"><span class="pre">platform.mac_ver()</span></code>, which can be used to provide macOS version information.
|
|||
|
<code class="docutils literal notranslate"><span class="pre">ios_ver()</span></code> will return a namedtuple that contains the following:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">system</span></code> - the OS name (<code class="docutils literal notranslate"><span class="pre">iOS</span></code> or <code class="docutils literal notranslate"><span class="pre">iPadOS</span></code>, depending on hardware)</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - the iOS version, as a string (e.g., <code class="docutils literal notranslate"><span class="pre">"16.6.1"</span></code>).</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">model</span></code> - the model identifier of the device, as a string (e.g.,
|
|||
|
<code class="docutils literal notranslate"><span class="pre">"iPhone13,2"</span></code>). On simulators, this will return <code class="docutils literal notranslate"><span class="pre">"iPhone"</span></code> or <code class="docutils literal notranslate"><span class="pre">"iPad"</span></code>,
|
|||
|
depending on the simulator device.</li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">is_simulator</span></code> - a boolean indicating if the device is a simulator.</li>
|
|||
|
</ul>
|
|||
|
</section>
|
|||
|
<section id="os">
|
|||
|
<h4><a class="toc-backref" href="#os" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></h4>
|
|||
|
<p><code class="docutils literal notranslate"><span class="pre">os.uname()</span></code> will return the raw result of a POSIX <code class="docutils literal notranslate"><span class="pre">uname()</span></code> call. This will
|
|||
|
result in the following values:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">sysname</span></code> - <code class="docutils literal notranslate"><span class="pre">"Darwin"</span></code></li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">release</span></code> - The Darwin kernel version (e.g., <code class="docutils literal notranslate"><span class="pre">"22.6.0"</span></code>)</li>
|
|||
|
</ul>
|
|||
|
<p>This approach treats the <code class="docutils literal notranslate"><span class="pre">os</span></code> module as a “raw” interface to system APIs, and
|
|||
|
<code class="docutils literal notranslate"><span class="pre">platform</span></code> as a higher-level API providing more generally useful values.</p>
|
|||
|
</section>
|
|||
|
<section id="sysconfig">
|
|||
|
<h4><a class="toc-backref" href="#sysconfig" role="doc-backlink"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></h4>
|
|||
|
<p>The <code class="docutils literal notranslate"><span class="pre">sysconfig</span></code> module will use the minimum iOS version as part of
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sysconfig.get_platform()</span></code> (e.g., <code class="docutils literal notranslate"><span class="pre">"ios-12.0-arm64-iphoneos"</span></code>). The
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sysconfigdata_name</span></code> and Config makefile will follow the same patterns as
|
|||
|
existing platforms (using <code class="docutils literal notranslate"><span class="pre">sys.platform</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code>
|
|||
|
etc.) to construct identifiers.</p>
|
|||
|
</section>
|
|||
|
</section>
|
|||
|
<section id="subprocess-support">
|
|||
|
<h3><a class="toc-backref" href="#subprocess-support" role="doc-backlink">Subprocess support</a></h3>
|
|||
|
<p>iOS will leverage the pattern for disabling subprocesses established by
|
|||
|
WASI/Emscripten. The <code class="docutils literal notranslate"><span class="pre">subprocess</span></code> module will raise an exception if an attempt
|
|||
|
is made to start a subprocess, and <code class="docutils literal notranslate"><span class="pre">os.fork</span></code> and <code class="docutils literal notranslate"><span class="pre">os.spawn</span></code> calls will raise
|
|||
|
an <code class="docutils literal notranslate"><span class="pre">OSError</span></code>.</p>
|
|||
|
</section>
|
|||
|
<section id="dynamic-module-loading">
|
|||
|
<h3><a class="toc-backref" href="#dynamic-module-loading" role="doc-backlink">Dynamic module loading</a></h3>
|
|||
|
<p>To accommodate iOS dynamic loading, the <code class="docutils literal notranslate"><span class="pre">importlib</span></code> bootstrap will be extended
|
|||
|
to add a metapath finder that can convert a request for a Python binary module
|
|||
|
into a Framework location. This finder will only be installed if <code class="docutils literal notranslate"><span class="pre">sys.platform</span>
|
|||
|
<span class="pre">==</span> <span class="pre">"ios"</span></code>.</p>
|
|||
|
<p>This finder will convert a Python module name (e.g., <code class="docutils literal notranslate"><span class="pre">foo.bar._whiz</span></code>) into a
|
|||
|
unique Framework name by using the full module name as the framework name (i.e.,
|
|||
|
<code class="docutils literal notranslate"><span class="pre">foo.bar._whiz.framework</span></code>). A framework is a directory; the finder will look
|
|||
|
for a binary named <code class="docutils literal notranslate"><span class="pre">foo.bar._whiz</span></code> in that directory.</p>
|
|||
|
</section>
|
|||
|
<section id="compilation">
|
|||
|
<h3><a class="toc-backref" href="#compilation" role="doc-backlink">Compilation</a></h3>
|
|||
|
<p>The only binary format that will be supported is a dynamically-linkable
|
|||
|
<code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code>, packaged in an iOS-compatible framework format. While
|
|||
|
the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> compiler option currently works, the
|
|||
|
long-term viability of the option cannot be guaranteed. Rather than rely on a
|
|||
|
compiler flag with an uncertain future, binary modules on iOS will be linked
|
|||
|
with <code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code>. This means iOS binary modules will not be loadable
|
|||
|
by an executable that has been statically linked against <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code>.
|
|||
|
Therefore, a static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> iOS library will not be supported. This
|
|||
|
is the same pattern used by CPython on Windows.</p>
|
|||
|
<p>Building CPython for iOS requires the use of the cross-platform tooling in
|
|||
|
CPython’s <code class="docutils literal notranslate"><span class="pre">configure</span></code> build system. A single <code class="docutils literal notranslate"><span class="pre">configure</span></code>/<code class="docutils literal notranslate"><span class="pre">make</span></code>/<code class="docutils literal notranslate"><span class="pre">make</span>
|
|||
|
<span class="pre">install</span></code> pass will produce a <code class="docutils literal notranslate"><span class="pre">Python.framework</span></code> artefact that can be used on
|
|||
|
a single ABI and architecture.</p>
|
|||
|
<p>Additional tooling will be required to merge the <code class="docutils literal notranslate"><span class="pre">Python.framework</span></code> builds for
|
|||
|
multiple architectures into a single “fat” library. Tooling will also be
|
|||
|
required to merge multiple ABIs into the <code class="docutils literal notranslate"><span class="pre">XCframework</span></code> format that Apple uses
|
|||
|
to distribute multiple frameworks for different ABIs in a single bundle.</p>
|
|||
|
<p>An Xcode project will be provided for the purpose of running the CPython test
|
|||
|
suite. Tooling will be provided to automate the process of compiling the test
|
|||
|
suite binary, start the simulator, install the test suite, and execute it.</p>
|
|||
|
</section>
|
|||
|
<section id="distribution">
|
|||
|
<h3><a class="toc-backref" href="#distribution" role="doc-backlink">Distribution</a></h3>
|
|||
|
<p>Adding iOS as a Tier 3 platform only requires adding support for compiling an
|
|||
|
iOS-compatible build from an unpatched CPython code checkout. It does not
|
|||
|
require production of officially distributed iOS artefacts for use by end-users.</p>
|
|||
|
<p>If/when iOS is updated to Tier 2 or 1 support, the tooling used to generate an
|
|||
|
<code class="docutils literal notranslate"><span class="pre">XCframework</span></code> package could be used to produce an iOS distribution artefact.
|
|||
|
This could then be distributed as an “embedded distribution” analogous to the
|
|||
|
Windows embedded distribution, or as a CocoaPod or Swift package that could be
|
|||
|
added to an Xcode project.</p>
|
|||
|
</section>
|
|||
|
<section id="ci-resources">
|
|||
|
<h3><a class="toc-backref" href="#ci-resources" role="doc-backlink">CI resources</a></h3>
|
|||
|
<p><a class="reference external" href="https://anaconda.com">Anaconda</a> has offered to provide physical hardware to
|
|||
|
run iOS buildbots.</p>
|
|||
|
<p>GitHub Actions is able to host iOS simulators on their macOS machines, and the
|
|||
|
iOS simulator can be controlled by scripting environments. The free tier
|
|||
|
currently only provides x86_64 macOS machines; however ARM64 runners <a class="reference external" href="https://github.blog/2023-10-02-introducing-the-new-apple-silicon-powered-m1-macos-larger-runner-for-github-actions/">recently
|
|||
|
became available on paid plans</a>.
|
|||
|
However, in order to avoid exhausting macOS runner resources, a GitHub Actions
|
|||
|
run for iOS will not be added as part of the standard CI configuration.</p>
|
|||
|
</section>
|
|||
|
<section id="packaging">
|
|||
|
<h3><a class="toc-backref" href="#packaging" role="doc-backlink">Packaging</a></h3>
|
|||
|
<p>iOS will not provide a “universal” wheel format. Instead, wheels will be
|
|||
|
provided for each ABI-arch combination.</p>
|
|||
|
<p>iOS wheels will use tags:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_arm64_iphoneos</span></code></li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_arm64_iphonesimulator</span></code></li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">ios_12_0_x86_64_iphonesimulator</span></code></li>
|
|||
|
</ul>
|
|||
|
<p>In these tags, “12.0” is the minimum supported iOS version. As with macOS, the
|
|||
|
tag will incorporate the minimum iOS version that is selected when the wheel is
|
|||
|
compiled; a wheel compiled with a minimum iOS version of 15.0 would use the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">ios_15_0_*</span></code> tags. At time of writing, iOS 12.0 exposes most significant iOS
|
|||
|
features, while reaching near 100% of devices; this will be used as a floor for
|
|||
|
iOS version matching.</p>
|
|||
|
<p>These wheels can include binary modules in-situ (i.e., co-located with the
|
|||
|
Python source, in the same way as wheels for a desktop platform); however, they
|
|||
|
will need to be post-processed as binary modules need to be moved into the
|
|||
|
“Frameworks” location for distribution. This can be automated with an Xcode
|
|||
|
build step.</p>
|
|||
|
</section>
|
|||
|
<section id="pep-11-update">
|
|||
|
<h3><a class="toc-backref" href="#pep-11-update" role="doc-backlink">PEP 11 Update</a></h3>
|
|||
|
<p><a class="pep reference internal" href="../pep-0011/" title="PEP 11 – CPython platform support">PEP 11</a> will be updated to include two of the iOS ABIs:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">arm64-apple-ios</span></code></li>
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">arm64-apple-ios-simulator</span></code></li>
|
|||
|
</ul>
|
|||
|
<p>Ned Deily will serve as the initial core team contact for these ABIs.</p>
|
|||
|
<p>The <code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios-simulator</span></code> target will be supported on a best-effort
|
|||
|
basis, but will not be targeted for tier 3 support. This is due to the impending
|
|||
|
deprecation of x86_64 as a simulation platform, combined with the difficulty of
|
|||
|
commissioning x86_64 macOS hardware at this time.</p>
|
|||
|
</section>
|
|||
|
</section>
|
|||
|
<section id="backwards-compatibility">
|
|||
|
<h2><a class="toc-backref" href="#backwards-compatibility" role="doc-backlink">Backwards Compatibility</a></h2>
|
|||
|
<p>Adding a new platform does not introduce any backwards compatibility concerns to
|
|||
|
CPython itself.</p>
|
|||
|
<p>There may be some backwards compatibility implications on the projects that have
|
|||
|
historically provided CPython support (i.e., BeeWare and Kivy) if the final form
|
|||
|
of any CPython patches don’t align with the patches they have historically used.</p>
|
|||
|
<p>Although not strictly a backwards compatibility issue, there <em>is</em> a platform
|
|||
|
adoption consideration. Although CPython itself may support iOS, if it is
|
|||
|
unclear how to produce iOS-compatible wheels, and prominent libraries like
|
|||
|
cryptography, Pillow, and NumPy don’t provide iOS wheels, the ability of the
|
|||
|
community to adopt Python on iOS will be limited. Therefore, it will be
|
|||
|
necessary to clearly document how projects can add iOS builds to their CI and
|
|||
|
release tooling. Adding iOS support to tools like <a class="reference external" href="https://crossenv.readthedocs.io/">crossenv</a> and <a class="reference external" href="https://cibuildwheel.readthedocs.io/">cibuildwheel</a> may be one way to achieve this.</p>
|
|||
|
</section>
|
|||
|
<section id="security-implications">
|
|||
|
<h2><a class="toc-backref" href="#security-implications" role="doc-backlink">Security Implications</a></h2>
|
|||
|
<p>Adding iOS as a new platform does not add any security implications.</p>
|
|||
|
</section>
|
|||
|
<section id="how-to-teach-this">
|
|||
|
<h2><a class="toc-backref" href="#how-to-teach-this" role="doc-backlink">How to Teach This</a></h2>
|
|||
|
<p>The education needs related to this PEP mostly relate to how end-users can add
|
|||
|
iOS support to their own Xcode projects. This can be accomplished with
|
|||
|
documentation and tutorials on that process. The need for this documentation
|
|||
|
will increase if/when support raises from Tier 3 to Tier 2 or 1; however, this
|
|||
|
transition should also be accompanied with simplified deployment artefacts (such
|
|||
|
as a Cocoapod or Swift package) that are integrated with Xcode development.</p>
|
|||
|
</section>
|
|||
|
<section id="reference-implementation">
|
|||
|
<h2><a class="toc-backref" href="#reference-implementation" role="doc-backlink">Reference Implementation</a></h2>
|
|||
|
<p>The BeeWare <a class="reference external" href="https://github.com/beeware/Python-Apple-support">Python-Apple-support</a> repository contains a
|
|||
|
reference patch and build tooling to compile a distributable artefact.</p>
|
|||
|
<p><a class="reference external" href="https://briefcase.readthedocs.org">Briefcase</a> provides a reference
|
|||
|
implementation of code to execute test suites on iOS simulators. The <a class="reference external" href="https://github.com/beeware/toga/tree/main/testbed">Toga
|
|||
|
Testbed</a> is an example of
|
|||
|
a test suite that is executed on the iOS simulator using GitHub Actions.</p>
|
|||
|
</section>
|
|||
|
<section id="rejected-ideas">
|
|||
|
<h2><a class="toc-backref" href="#rejected-ideas" role="doc-backlink">Rejected Ideas</a></h2>
|
|||
|
<section id="simulator-identification">
|
|||
|
<h3><a class="toc-backref" href="#simulator-identification" role="doc-backlink">Simulator identification</a></h3>
|
|||
|
<p>Earlier versions of this PEP suggested the inclusion of
|
|||
|
<code class="docutils literal notranslate"><span class="pre">sys.implementation._simulator</span></code> attribute to identify when code is running on
|
|||
|
device, or on a simulator. This was rejected due to the use of a protected name
|
|||
|
for a public API, plus the pollution of the <code class="docutils literal notranslate"><span class="pre">sys</span></code> namespace with an
|
|||
|
iOS-specific detail.</p>
|
|||
|
<p>Another proposal during discussion was to include a generic
|
|||
|
<code class="docutils literal notranslate"><span class="pre">platform.is_emulator()</span></code> API that could be implemented by any platform - for
|
|||
|
example to differentiate running on x86_64 code on ARM64 hardware, or when
|
|||
|
running in QEMU or other virtualization methods. This was rejected on the basis
|
|||
|
that it wasn’t clear what a consistent interpretation of “emulator” would be, or
|
|||
|
how an emulator would be detected outside of the iOS case.</p>
|
|||
|
<p>The decision was made to keep this detail iOS-specific, and include it on the
|
|||
|
<code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code> API.</p>
|
|||
|
</section>
|
|||
|
<section id="gnu-compiler-triples">
|
|||
|
<h3><a class="toc-backref" href="#gnu-compiler-triples" role="doc-backlink">GNU compiler triples</a></h3>
|
|||
|
<p><code class="docutils literal notranslate"><span class="pre">autoconf</span></code> requires the use of a GNU compiler triple to identify build and
|
|||
|
host platforms. However, the <code class="docutils literal notranslate"><span class="pre">autoconf</span></code> toolchain doesn’t provide native
|
|||
|
support for iOS simulators, so we are left with the task of working out how to
|
|||
|
squeeze iOS hardware into GNU’s naming regimen.</p>
|
|||
|
<p>This can be done (with some patching of <code class="docutils literal notranslate"><span class="pre">config.sub</span></code>), but it leads to 2 major
|
|||
|
sources of naming inconsistency:</p>
|
|||
|
<ul class="simple">
|
|||
|
<li><code class="docutils literal notranslate"><span class="pre">arm64</span></code> vs <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> as an identifier of 64-bit ARM hardware; and</li>
|
|||
|
<li>What identifier is used to represent simulators.</li>
|
|||
|
</ul>
|
|||
|
<p>Apple’s own tools use <code class="docutils literal notranslate"><span class="pre">arm64</span></code> as the architecture, but appear to be tolerant
|
|||
|
of <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> in some cases. The device platform is identified as <code class="docutils literal notranslate"><span class="pre">iphoneos</span></code>
|
|||
|
and <code class="docutils literal notranslate"><span class="pre">iphonesimulator</span></code>.</p>
|
|||
|
<p>Rust toolchains uses <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> as the architecture, and use
|
|||
|
<code class="docutils literal notranslate"><span class="pre">aarch64-apple-ios</span></code> and <code class="docutils literal notranslate"><span class="pre">aarch64-apple-ios-sim</span></code> to identify the device
|
|||
|
platform; however, they use <code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios</span></code> to represent iOS <em>simulators</em>
|
|||
|
on x86_64 hardware.</p>
|
|||
|
<p>The decision was made to use <code class="docutils literal notranslate"><span class="pre">arm64-apple-ios</span></code> and
|
|||
|
<code class="docutils literal notranslate"><span class="pre">arm64-apple-ios-simulator</span></code> because:</p>
|
|||
|
<ol class="arabic simple">
|
|||
|
<li>The <code class="docutils literal notranslate"><span class="pre">autoconf</span></code> toolchain already contains support for <code class="docutils literal notranslate"><span class="pre">ios</span></code> as a platform
|
|||
|
in <code class="docutils literal notranslate"><span class="pre">config.sub</span></code>; it’s only the simulator that doesn’t have a representation.</li>
|
|||
|
<li>The third part of the host triple is used as <code class="docutils literal notranslate"><span class="pre">sys.platform</span></code>.</li>
|
|||
|
<li>When Apple’s own tools reference CPU architecture, they use <code class="docutils literal notranslate"><span class="pre">arm64</span></code>, and
|
|||
|
the GNU tooling usage of the architecture isn’t visible outside the build
|
|||
|
process.</li>
|
|||
|
<li>When Apple’s own tools reference simulator status independent of the OS
|
|||
|
(e.g., in the naming of Swift submodules), they use a <code class="docutils literal notranslate"><span class="pre">-simulator</span></code> suffix.</li>
|
|||
|
<li>While <em>some</em> iOS packages will use Rust, <em>all</em> iOS packages will use Apple’s
|
|||
|
tooling.</li>
|
|||
|
</ol>
|
|||
|
<p>The initially accepted version of this document used the <code class="docutils literal notranslate"><span class="pre">aarch64</span></code> form as the PEP 11 identifier; this was corrected during finalization.</p>
|
|||
|
</section>
|
|||
|
<section id="universal-wheel-format">
|
|||
|
<h3><a class="toc-backref" href="#universal-wheel-format" role="doc-backlink">“Universal” wheel format</a></h3>
|
|||
|
<p>macOS currently supports 2 CPU architectures. To aid the end-user development
|
|||
|
experience, Python defines a “universal2” wheel format that incorporates both
|
|||
|
x86_64 and ARM64 binaries.</p>
|
|||
|
<p>It would be conceptually possible to offer an analogous “universal” iOS wheel
|
|||
|
format. However, this PEP does not use this approach, for 2 reasons.</p>
|
|||
|
<p>Firstly, the experience on macOS, especially in the numerical Python ecosystem,
|
|||
|
has been that universal wheels can be exceedingly difficult to accommodate.
|
|||
|
While native macOS libraries maintain strong multi-platform support, and Python
|
|||
|
itself has been updated, the vast majority of upstream non-Python libraries do
|
|||
|
not provide multi-architecture build support. As a result, compiling universal
|
|||
|
wheels inevitably requires multiple compilation passes, and complex decisions
|
|||
|
over how to distribute header files for different architectures. As a result of
|
|||
|
this complexity, many popular projects (including NumPy and Pillow) do not
|
|||
|
provide universal wheels at all, instead providing separate ARM64 and x86_64
|
|||
|
wheels.</p>
|
|||
|
<p>Secondly, historical experience is that iOS would require a much more fluid
|
|||
|
“universal” definition. In the last 10 years, there have been <em>at least</em> 5
|
|||
|
different possible interpretations of “universal” that would apply to iOS,
|
|||
|
including various combinations of armv6, armv7, armv7s, arm64, x86 and x86_64
|
|||
|
architectures, on device and simulator. If defined right now, “universal-iOS”
|
|||
|
would likely include x86_64 and arm64 on simulator, and arm64 on device;
|
|||
|
however, the pending deprecation of x86_64 hardware would add another
|
|||
|
interpretation; and there may be a need to add arm64e as a new device
|
|||
|
architecture in the future. Specifying iOS wheels as single-platform-only means
|
|||
|
the Python core team can avoid an ongoing standardization discussion about the
|
|||
|
updated “universal” formats.</p>
|
|||
|
<p>It also means wheel publishers are able to make per-project decisions over which
|
|||
|
platforms are feasible to support. For example, a project may choose to drop
|
|||
|
x86_64 support, or adopt a new architecture earlier than other parts of the
|
|||
|
Python ecosystem. Using platform-specific wheels means this decision can be left
|
|||
|
to individual package publishers.</p>
|
|||
|
<p>This decision comes at cost of making deployment more complicated. However,
|
|||
|
deployment on iOS is already a complicated process that is best aided by tools.
|
|||
|
At present, no binary merging is required, as there is only one on-device
|
|||
|
architecture, and simulator binaries are not considered to be distributable
|
|||
|
artefacts, so only one architecture is needed to build an app for a simulator.</p>
|
|||
|
</section>
|
|||
|
<section id="supporting-static-builds">
|
|||
|
<h3><a class="toc-backref" href="#supporting-static-builds" role="doc-backlink">Supporting static builds</a></h3>
|
|||
|
<p>While the long-term viability of the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> option
|
|||
|
cannot be guaranteed, the option does exist, and it works. One option would be
|
|||
|
to ignore the deprecation warning, and hope that Apple either reverses the
|
|||
|
deprecation decision, or never finalizes the deprecation.</p>
|
|||
|
<p>Given that Apple’s decision-making process is entirely opaque, this would be, at
|
|||
|
best, a risky option. When combined with the fact that the broader iOS
|
|||
|
development ecosystem encourages the use of frameworks, there are no legacy uses
|
|||
|
of a static library to consider, and the only benefit to a statically-linked iOS
|
|||
|
<code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> is a very slightly reduced app startup time, omitting support
|
|||
|
for static builds of <code class="docutils literal notranslate"><span class="pre">libpython3.x</span></code> seems a reasonable compromise.</p>
|
|||
|
<p>It is worth noting that there has been some discussion on <a class="reference external" href="https://github.com/python/cpython/issues/103306">an alternate approach
|
|||
|
to linking on macOS</a> that
|
|||
|
would remove the need for the <code class="docutils literal notranslate"><span class="pre">--undefined</span> <span class="pre">dynamic_lookup</span></code> option, although
|
|||
|
discussion on this approach appears to have stalled due to complications in
|
|||
|
implementation. If those complications were to be overcome, it is highly likely
|
|||
|
that the same approach <em>could</em> be used on iOS, which <em>would</em> make a statically
|
|||
|
linked <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> plausible.</p>
|
|||
|
<p>The decision to link binary modules against <code class="docutils literal notranslate"><span class="pre">libpython3.x.dylib</span></code> would
|
|||
|
complicate the introduction of static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code> builds in the future,
|
|||
|
as the process of moving to a different binary module linking approach would
|
|||
|
require a clear way to differentate “dynamically-linked” iOS binary modules from
|
|||
|
“static-compatible” iOS binary modules. However, given the lack of tangible
|
|||
|
benefits of a static <code class="docutils literal notranslate"><span class="pre">libpython3.x.a</span></code>, it seems unlikely that there will be
|
|||
|
any requirement to make this change.</p>
|
|||
|
</section>
|
|||
|
<section id="interactive-repl-mode">
|
|||
|
<h3><a class="toc-backref" href="#interactive-repl-mode" role="doc-backlink">Interactive/REPL mode</a></h3>
|
|||
|
<p>A traditional <code class="docutils literal notranslate"><span class="pre">python.exe</span></code> command line experience isn’t really viable on
|
|||
|
mobile devices, because mobile devices don’t have a command line. iOS apps don’t
|
|||
|
have a stdout, stderr or stdin; and while you can redirect stdout and stderr to
|
|||
|
the system log, there’s no source for stdin that exists that doesn’t also
|
|||
|
involve building a very specific user-facing app that would be closer to an
|
|||
|
IDLE-style IDE experience. Therefore, the decision was made to only focus on
|
|||
|
“embedded mode” as a target for mobile distribution.</p>
|
|||
|
</section>
|
|||
|
<section id="x86-64-simulator-support">
|
|||
|
<h3><a class="toc-backref" href="#x86-64-simulator-support" role="doc-backlink">x86_64 simulator support</a></h3>
|
|||
|
<p>Apple no longer sells x86_64 hardware. As a result, commissioning an x86_64
|
|||
|
buildbot can be difficult. It is possible to run macOS binaries in x86_64
|
|||
|
compatibility mode on ARM64 hardware; however, this isn’t ideal for testing
|
|||
|
purposes. Therefore, the x86_64 Simulator (<code class="docutils literal notranslate"><span class="pre">x86_64-apple-ios-simulator</span></code>) will
|
|||
|
not be added as a Tier 3 target. It is highly likely that iOS support will work
|
|||
|
on the x86_64 without any modification; this only impacts on the <em>official</em> Tier
|
|||
|
3 status.</p>
|
|||
|
</section>
|
|||
|
<section id="on-device-testing">
|
|||
|
<h3><a class="toc-backref" href="#on-device-testing" role="doc-backlink">On-device testing</a></h3>
|
|||
|
<p>CI testing on simulators can be accommodated reasonably easily. On-device
|
|||
|
testing is much harder, as availability of device farms that could be configured
|
|||
|
to provide Buildbots or Github Actions runners is limited.</p>
|
|||
|
<p>However, on device testing may not be necessary. As a data point - Apple’s Xcode
|
|||
|
Cloud solution doesn’t provide on-device testing. They rely on the fact that the
|
|||
|
API is consistent between device and simulator, and ARM64 simulator testing is
|
|||
|
sufficient to reveal CPU-specific issues.</p>
|
|||
|
</section>
|
|||
|
<section id="ordering-of-multiarch-tags">
|
|||
|
<h3><a class="toc-backref" href="#ordering-of-multiarch-tags" role="doc-backlink">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></h3>
|
|||
|
<p>The initially accepted version of this document used <code class="docutils literal notranslate"><span class="pre"><platform>-<arch></span></code>
|
|||
|
ordering (e.g., <code class="docutils literal notranslate"><span class="pre">iphoneos-arm64</span></code>) for <code class="docutils literal notranslate"><span class="pre">sys.implementation._multiarch</span></code> (and
|
|||
|
related values, such as wheel tags). The final merged version uses the
|
|||
|
<code class="docutils literal notranslate"><span class="pre"><arch>-<platform></span></code> ordering (e.g., <code class="docutils literal notranslate"><span class="pre">arm64-iphoneos</span></code>). This is for
|
|||
|
consistency with compiler triples on other platforms (especially Linux), which
|
|||
|
specify the architecture before the operating system.</p>
|
|||
|
</section>
|
|||
|
<section id="values-returned-by-platform-ios-ver">
|
|||
|
<h3><a class="toc-backref" href="#values-returned-by-platform-ios-ver" role="doc-backlink">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></h3>
|
|||
|
<p>The initially accepted version of this document didn’t include a <code class="docutils literal notranslate"><span class="pre">system</span></code>
|
|||
|
identifier. This was added during the implementation phase to support the implementation of <code class="docutils literal notranslate"><span class="pre">platform.system()</span></code>.</p>
|
|||
|
<p>The initially accepted version of this document also described that
|
|||
|
<code class="docutils literal notranslate"><span class="pre">min_release</span></code> would be returned in the <code class="docutils literal notranslate"><span class="pre">ios_ver()</span></code> result. The final version
|
|||
|
omits the <code class="docutils literal notranslate"><span class="pre">min_release</span></code> value, as it is not significant at runtime; it only
|
|||
|
impacts on binary compatibility. The minimum version <em>is</em> included in the value
|
|||
|
returned by <code class="docutils literal notranslate"><span class="pre">sysconfig.get_platform()</span></code>, as this is used to define wheel (and
|
|||
|
other binary) compatibility.</p>
|
|||
|
</section>
|
|||
|
</section>
|
|||
|
<section id="copyright">
|
|||
|
<h2><a class="toc-backref" href="#copyright" role="doc-backlink">Copyright</a></h2>
|
|||
|
<p>This document is placed in the public domain or under the CC0-1.0-Universal
|
|||
|
license, whichever is more permissive.</p>
|
|||
|
</section>
|
|||
|
</section>
|
|||
|
<hr class="docutils" />
|
|||
|
<p>Source: <a class="reference external" href="https://github.com/python/peps/blob/main/peps/pep-0730.rst">https://github.com/python/peps/blob/main/peps/pep-0730.rst</a></p>
|
|||
|
<p>Last modified: <a class="reference external" href="https://github.com/python/peps/commits/main/peps/pep-0730.rst">2024-04-21 03:05:49 GMT</a></p>
|
|||
|
|
|||
|
</article>
|
|||
|
<nav id="pep-sidebar">
|
|||
|
<h2>Contents</h2>
|
|||
|
<ul>
|
|||
|
<li><a class="reference internal" href="#abstract">Abstract</a></li>
|
|||
|
<li><a class="reference internal" href="#motivation">Motivation</a></li>
|
|||
|
<li><a class="reference internal" href="#rationale">Rationale</a><ul>
|
|||
|
<li><a class="reference internal" href="#development-landscape">Development landscape</a></li>
|
|||
|
<li><a class="reference internal" href="#posix-compliance">POSIX compliance</a></li>
|
|||
|
<li><a class="reference internal" href="#dynamic-libraries">Dynamic libraries</a></li>
|
|||
|
<li><a class="reference internal" href="#console-and-interactive-usage">Console and interactive usage</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#specification">Specification</a><ul>
|
|||
|
<li><a class="reference internal" href="#platform-identification">Platform identification</a><ul>
|
|||
|
<li><a class="reference internal" href="#sys"><code class="docutils literal notranslate"><span class="pre">sys</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#platform"><code class="docutils literal notranslate"><span class="pre">platform</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#os"><code class="docutils literal notranslate"><span class="pre">os</span></code></a></li>
|
|||
|
<li><a class="reference internal" href="#sysconfig"><code class="docutils literal notranslate"><span class="pre">sysconfig</span></code></a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#subprocess-support">Subprocess support</a></li>
|
|||
|
<li><a class="reference internal" href="#dynamic-module-loading">Dynamic module loading</a></li>
|
|||
|
<li><a class="reference internal" href="#compilation">Compilation</a></li>
|
|||
|
<li><a class="reference internal" href="#distribution">Distribution</a></li>
|
|||
|
<li><a class="reference internal" href="#ci-resources">CI resources</a></li>
|
|||
|
<li><a class="reference internal" href="#packaging">Packaging</a></li>
|
|||
|
<li><a class="reference internal" href="#pep-11-update">PEP 11 Update</a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#backwards-compatibility">Backwards Compatibility</a></li>
|
|||
|
<li><a class="reference internal" href="#security-implications">Security Implications</a></li>
|
|||
|
<li><a class="reference internal" href="#how-to-teach-this">How to Teach This</a></li>
|
|||
|
<li><a class="reference internal" href="#reference-implementation">Reference Implementation</a></li>
|
|||
|
<li><a class="reference internal" href="#rejected-ideas">Rejected Ideas</a><ul>
|
|||
|
<li><a class="reference internal" href="#simulator-identification">Simulator identification</a></li>
|
|||
|
<li><a class="reference internal" href="#gnu-compiler-triples">GNU compiler triples</a></li>
|
|||
|
<li><a class="reference internal" href="#universal-wheel-format">“Universal” wheel format</a></li>
|
|||
|
<li><a class="reference internal" href="#supporting-static-builds">Supporting static builds</a></li>
|
|||
|
<li><a class="reference internal" href="#interactive-repl-mode">Interactive/REPL mode</a></li>
|
|||
|
<li><a class="reference internal" href="#x86-64-simulator-support">x86_64 simulator support</a></li>
|
|||
|
<li><a class="reference internal" href="#on-device-testing">On-device testing</a></li>
|
|||
|
<li><a class="reference internal" href="#ordering-of-multiarch-tags">Ordering of <code class="docutils literal notranslate"><span class="pre">_multiarch</span></code> tags</a></li>
|
|||
|
<li><a class="reference internal" href="#values-returned-by-platform-ios-ver">Values returned by <code class="docutils literal notranslate"><span class="pre">platform.ios_ver()</span></code></a></li>
|
|||
|
</ul>
|
|||
|
</li>
|
|||
|
<li><a class="reference internal" href="#copyright">Copyright</a></li>
|
|||
|
</ul>
|
|||
|
|
|||
|
<br>
|
|||
|
<a id="source" href="https://github.com/python/peps/blob/main/peps/pep-0730.rst">Page Source (GitHub)</a>
|
|||
|
</nav>
|
|||
|
</section>
|
|||
|
<script src="../_static/colour_scheme.js"></script>
|
|||
|
<script src="../_static/wrap_tables.js"></script>
|
|||
|
<script src="../_static/sticky_banner.js"></script>
|
|||
|
</body>
|
|||
|
</html>
|