PEP 730 – Hinzufügen von iOS als unterstützte Plattform
- Autor:
- Russell Keith-Magee <russell at keith-magee.com>
- Sponsor:
- Ned Deily <nad at python.org>
- Discussions-To:
- Discourse thread
- Status:
- Final
- Typ:
- Standards Track
- Erstellt:
- 09-Okt-2023
- Python-Version:
- 3.13
- Resolution:
- Discourse-Nachricht
Zusammenfassung
Diese PEP schlägt die Aufnahme von iOS als unterstützte Plattform in CPython vor. Das anfängliche Ziel ist die Erreichung der Tier-3-Unterstützung für Python 3.13. Diese PEP beschreibt die technischen Aspekte der Änderungen, die zur Unterstützung von iOS erforderlich sind. Sie beschreibt auch die Projektmanagement-Anliegen im Zusammenhang mit der Aufnahme von iOS als Tier-3-Plattform.
Motivation
In den letzten 15 Jahren sind mobile Plattformen zu einem immer wichtigeren Bestandteil der Computerlandschaft geworden. iOS ist eines von zwei Betriebssystemen, die die überwiegende Mehrheit dieser Geräte steuern. Es gibt jedoch keine offizielle Unterstützung für iOS in CPython.
Das BeeWare Project und Kivy unterstützen iOS seit fast 10 Jahren. Diese Unterstützung hat es ermöglicht, Anwendungen zu generieren, die für die Veröffentlichung im iOS App Store zugelassen wurden. Dies demonstriert die technische Machbarkeit der iOS-Unterstützung.
Für die Zukunft von Python als Sprache ist es wichtig, dass es auf jeder Hardware oder jedem Betriebssystem verwendet werden kann, das eine breite Akzeptanz findet. Wenn Python auf einer Plattform, die weit verbreitet ist, nicht verwendet werden kann, wird die Akzeptanz der Sprache beeinträchtigt, da potenzielle Benutzer andere Sprachen wählen werden, die eine Unterstützung für diese Plattformen *bieten*.
Begründung
Entwicklungslandschaft
iOS bietet eine einzige API, aber 2 verschiedene ABIs – iphoneos (physische Geräte) und iphonesimulator. Jede dieser ABIs kann auf mehreren CPU-Architekturen bereitgestellt werden. Zum Zeitpunkt der Erstellung unterstützt Apple offiziell arm64 für die Geräte-ABI und arm64 und x86_64 für die Simulator-ABI.
Wie macOS unterstützt auch iOS die Erstellung von „Fat“-Binärdateien, die mehrere CPU-Architekturen enthalten. Fat-Binärdateien *können* jedoch keine ABIs umfassen. Das heißt, es ist möglich, eine Fat-Simulator-Binärdatei und eine Fat-Geräte-Binärdatei zu haben, aber es ist nicht möglich, eine einzelne Fat-„iOS“-Binärdatei zu erstellen, die sowohl Simulator- als auch Geräteanforderungen abdeckt. Zur Verteilung eines einzigen Entwicklungsartefakts verwendet Apple eine „XCframework“-Struktur – einen Wrapper um mehrere ABIs, die eine gemeinsame API implementieren.
iOS läuft auf einem Darwin-Kernel, ähnlich wie macOS. Es besteht jedoch die Notwendigkeit, macOS und iOS auf Implementierungsebene zu unterscheiden, da es erhebliche Plattformunterschiede zwischen iOS und macOS gibt.
iOS-Code wird für die Kompatibilität mit einer minimalen iOS-Version kompiliert.
Apple bezieht sich in seinen Marketingmaterialien häufig auf „iPadOS“. Aus Entwicklungssicht gibt es jedoch keinen erkennbaren Unterschied zwischen iPadOS und iOS. Eine Binärdatei, die für die iphoneos- oder iphonesimulator-ABIs kompiliert wurde, kann auf iPads bereitgestellt werden.
Andere Apple-Plattformen wie tvOS, watchOS und visionOS verwenden andere ABIs und sind nicht Gegenstand dieser PEP.
POSIX-Konformität
iOS ist im Grunde eine POSIX-Plattform. Ähnlich wie bei WASI/Emscripten gibt es jedoch POSIX-APIs, die auf iOS existieren, aber nicht verwendet werden können; und POSIX-APIs, die überhaupt nicht existieren.
Das Bemerkenswerteste daran ist, dass iOS keine Form der Mehrprozessunterstützung bietet. fork und spawn *existieren* zwar in der iOS-API; wenn sie jedoch aufgerufen werden, stoppt der aufrufende iOS-Prozess, und der neue Prozess startet nicht.
Im Gegensatz zu WASI/Emscripten wird Threading unter iOS unterstützt.
Es gibt auch erhebliche Einschränkungen bei der Socket-Handhabung. Aufgrund der Sandbox-Beschränkungen von Prozessen ist keine Interprozesskommunikation über Sockets möglich. Sockets für die Netzwerkommunikation sind jedoch verfügbar.
Dynamische Bibliotheken
Die App Store-Richtlinien von iOS erlauben die Entwicklung von Apps in anderen Sprachen als Objective C oder Swift. Sie enthalten jedoch sehr strenge Richtlinien für die Struktur von Apps, die zur Verteilung eingereicht werden.
iOS-Apps können dynamisch geladene Bibliotheken verwenden; es gibt jedoch sehr strenge Anforderungen, wie dynamisch geladener Inhalt für die Verwendung unter iOS verpackt werden muss.
- Dynamische Binärinhalte müssen als dynamische Bibliotheken kompiliert werden, nicht als Shared Objects oder Binärpakete.
- Sie müssen im App-Bundle als Frameworks verpackt werden.
- Jedes Framework kann nur eine einzige dynamische Bibliothek enthalten.
- Das Framework *muss* im Ordner
Frameworksder iOS-App enthalten sein. - Ein Framework darf keinen Nicht-Bibliotheksinhalt enthalten.
Dies schränkt die Funktionsweise von CPython ein. Es ist nicht möglich, Binärmodule in den Ordnern lib-dynload und/oder site-packages zu speichern; sie müssen im Frameworks-Ordner der App gespeichert werden, wobei jedes Modul in einem Framework verpackt ist. Dies bedeutet auch, dass die gängige Annahme, dass ein Python-Modul den Speicherort eines Binärmoduls mithilfe des __file__-Attributs des Python-Moduls konstruieren kann, nicht mehr gilt.
Wie bei macOS erfordert die Kompilierung eines Binärmoduls, das von einem statisch verknüpften Python-Build aus zugänglich ist, die Verwendung der Option --undefined dynamic_lookup, um libpython3.x in jedes Binärmodul zu verknüpfen. Unter iOS löst diese Compiler-Flagge jedoch eine Deprecation-Warnung aus, wenn sie verwendet wird. Eine Warnung dieser Flagge wurde auch unter macOS beobachtet – jedoch deuten Antworten von Apple-Mitarbeitern darauf hin, dass sie nicht beabsichtigen, das CPython-Ökosystem durch Entfernen dieser Option zu beeinträchtigen. Da Python derzeit keine nennenswerte Präsenz unter iOS hat, ist es schwierig zu beurteilen, ob die iOS-Nutzung dieser Flagge unter dieselbe Kategorie fällt.
Konsolen- und interaktive Nutzung
Die Verteilung einer traditionellen CPython REPL oder eines interaktiven „python.exe“ sollte nicht als Ziel dieser Arbeit betrachtet werden.
Mobile Geräte (einschließlich iOS) bieten keine TTY-artige Konsole. Sie bieten keine stdin, stdout oder stderr. iOS bietet ein Systemprotokoll, und es ist möglich, eine Umleitung zu installieren, sodass alle stdout- und stderr-Inhalte an das Systemprotokoll umgeleitet werden; es gibt jedoch kein Analogon für stdin.
Darüber hinaus schränkt iOS das Herunterladen von zusätzlichem Code zur Laufzeit ein (da dieses Verhalten funktional nicht von dem Versuch, die App Store-Überprüfung zu umgehen, zu unterscheiden wäre). Infolgedessen wird eine traditionelle Entwicklungserfahrung mit „virtueller Umgebung erstellen und pip installieren“ unter iOS nicht praktikabel sein.
Es ist *möglich*, eine native iOS-Anwendung zu erstellen, die eine REPL-Schnittstelle bereitstellt. Dies wäre näher an einer IDLE-ähnlichen Benutzererfahrung; Tkinter kann jedoch unter iOS nicht verwendet werden, sodass jede App eine Neuentwicklung von Grund auf erfordern würde. Der iOS App Store enthält bereits mehrere Beispiele für Apps in dieser Kategorie (z. B. Pythonista und Pyto). Der Schwerpunkt dieser Arbeit wäre die Bereitstellung einer eingebetteten Distribution, die IDE-ähnliche native Schnittstellen nutzen könnten, und nicht eine benutzerorientierte „App“-Schnittstelle zu iOS unter Python.
Spezifikation
Plattformerfassung
sys
sys.platform wird sowohl auf Simulatoren als auch auf physischen Geräten als "ios" identifiziert.
sys.implementation._multiarch beschreibt die ABI und die CPU-Architektur
"arm64-iphoneos"für ARM64-Geräte"arm64-iphonesimulator"für ARM64-Simulatoren"x86_64-iphonesimulator"für x86_64-Simulatoren
platform
platform wird so modifiziert, dass iOS-spezifische Details zurückgegeben werden. Die meisten Werte, die vom platform-Modul zurückgegeben werden, entsprechen denen von os.uname(), mit Ausnahme von
platform.system()-"iOS"oderiPadOS(abhängig von der verwendeten Hardware) anstelle von"Darwin"platform.release()- die iOS-Versionsnummer als Zeichenkette (z. B."16.6.1") anstelle der Darwin-Kernel-Version.
Zusätzlich wird eine Methode platform.ios_ver() hinzugefügt. Diese spiegelt platform.mac_ver() wider, die verwendet werden kann, um macOS-Versionsinformationen bereitzustellen. ios_ver() gibt ein benanntes Tupel zurück, das Folgendes enthält:
system- der Name des Betriebssystems (iOSoderiPadOS, abhängig von der Hardware)release- die iOS-Version als Zeichenkette (z. B."16.6.1").model- die Modellkennung des Geräts als Zeichenkette (z. B."iPhone13,2"). Auf Simulatoren gibt dies"iPhone"oder"iPad"zurück, je nach Simulatorgerät.is_simulator- ein boolescher Wert, der angibt, ob es sich um einen Simulator handelt.
os
os.uname() gibt das Rohresultat eines POSIX uname()-Aufrufs zurück. Dies führt zu folgenden Werten:
sysname-"Darwin"release- Die Darwin-Kernel-Version (z. B."22.6.0")
Dieser Ansatz behandelt das os-Modul als „Roh“-Schnittstelle zu System-APIs und platform als höherwertige API, die allgemeinere nützliche Werte liefert.
sysconfig
Das sysconfig-Modul verwendet die minimale iOS-Version als Teil von sysconfig.get_platform() (z. B. "ios-12.0-arm64-iphoneos"). Der sysconfigdata_name und die Config-Makefile folgen denselben Mustern wie bestehende Plattformen (unter Verwendung von sys.platform, sys.implementation._multiarch etc.), um Identifikatoren zu konstruieren.
Subprozessunterstützung
iOS wird das Muster zur Deaktivierung von Subprozessen nutzen, das von WASI/Emscripten etabliert wurde. Das subprocess-Modul löst eine Ausnahme aus, wenn versucht wird, einen Subprozess zu starten, und os.fork- und os.spawn-Aufrufe lösen eine OSError aus.
Dynamisches Laden von Modulen
Um das dynamische Laden unter iOS zu unterstützen, wird der importlib-Bootstrap erweitert, um einen Metapath-Finder hinzuzufügen, der eine Anfrage nach einem Python-Binärmodul in einen Framework-Speicherort umwandeln kann. Dieser Finder wird nur installiert, wenn sys.platform == "ios".
Dieser Finder wandelt einen Python-Modulnamen (z. B. foo.bar._whiz) in einen eindeutigen Framework-Namen um, indem er den vollständigen Modulnamen als Framework-Namen verwendet (d. h. foo.bar._whiz.framework). Ein Framework ist ein Verzeichnis; der Finder sucht in diesem Verzeichnis nach einer Binärdatei namens foo.bar._whiz.
Kompilierung
Das einzige unterstützte Binärformat ist eine dynamisch verknüpfbare libpython3.x.dylib, die in einem iOS-kompatiblen Framework-Format verpackt ist. Während die Compiler-Option --undefined dynamic_lookup derzeit funktioniert, ist die langfristige Machbarkeit der Option nicht garantiert. Anstatt sich auf eine Compiler-Flagge mit ungewisser Zukunft zu verlassen, werden Binärmodule unter iOS mit libpython3.x.dylib verknüpft. Das bedeutet, dass iOS-Binärmodule nicht von einer ausführbaren Datei geladen werden können, die statisch mit libpython3.x.a verknüpft wurde. Daher wird eine statische libpython3.x.a iOS-Bibliothek nicht unterstützt. Dies ist dasselbe Muster, das von CPython unter Windows verwendet wird.
Das Kompilieren von CPython für iOS erfordert die Verwendung der plattformübergreifenden Werkzeuge im configure-Build-System von CPython. Ein einzelner configure/make/make install-Durchlauf erzeugt ein Python.framework-Artefakt, das für eine einzelne ABI und Architektur verwendet werden kann.
Zusätzliche Werkzeuge werden benötigt, um die Python.framework-Builds für mehrere Architekturen zu einem einzigen „Fat“-Bibliothek zusammenzuführen. Werkzeuge werden auch benötigt, um mehrere ABIs in das XCframework-Format zusammenzuführen, das Apple zur Verteilung mehrerer Frameworks für verschiedene ABIs in einem einzigen Bundle verwendet.
Ein Xcode-Projekt wird zur Ausführung der CPython-Testsuite bereitgestellt. Werkzeuge werden bereitgestellt, um den Prozess des Kompilierens des Testsuite-Binärprogramms, des Starts des Simulators, der Installation der Testsuite und ihrer Ausführung zu automatisieren.
Verteilung
Die Aufnahme von iOS als Tier-3-Plattform erfordert lediglich die Unterstützung für die Kompilierung eines iOS-kompatiblen Builds aus einem unveränderten CPython-Code-Checkout. Sie erfordert nicht die Erstellung offiziell verteilter iOS-Artefakte für Endbenutzer.
Wenn/wenn iOS auf Tier-2- oder Tier-1-Unterstützung aktualisiert wird, könnten die Werkzeuge zur Erstellung eines XCframework-Pakets zur Erstellung eines iOS-Verteilungsartefakts verwendet werden. Dieses könnte dann als „embedded distribution“ analog zur Windows-embedded-distribution oder als CocoaPod oder Swift-Paket verteilt werden, das zu einem Xcode-Projekt hinzugefügt werden könnte.
CI-Ressourcen
Anaconda hat angeboten, physische Hardware für die Ausführung von iOS-Buildbots bereitzustellen.
GitHub Actions kann iOS-Simulatoren auf seinen macOS-Maschinen hosten, und der iOS-Simulator kann durch Skripting-Umgebungen gesteuert werden. Die kostenlose Stufe bietet derzeit nur x86_64-macOS-Maschinen; jedoch sind ARM64-Runner kürzlich für kostenpflichtige Pläne verfügbar geworden. Um jedoch die macOS-Runner-Ressourcen nicht zu überlasten, wird kein GitHub Actions-Lauf für iOS als Teil der Standard-CI-Konfiguration hinzugefügt.
Packaging
iOS wird kein „universelles“ Wheel-Format bereitstellen. Stattdessen werden Wheels für jede ABI-Architektur-Kombination bereitgestellt.
iOS-Wheels werden Tags verwenden
ios_12_0_arm64_iphoneosios_12_0_arm64_iphonesimulatorios_12_0_x86_64_iphonesimulator
In diesen Tags ist „12.0“ die minimal unterstützte iOS-Version. Wie bei macOS wird der Tag die minimale iOS-Version enthalten, die bei der Kompilierung des Wheels ausgewählt wird; ein Wheel, das mit einer minimalen iOS-Version von 15.0 kompiliert wurde, würde die ios_15_0_*-Tags verwenden. Zum Zeitpunkt der Erstellung bietet iOS 12.0 die wichtigsten iOS-Funktionen und erreicht fast 100 % der Geräte; dies wird als Untergrenze für die iOS-Versionsübereinstimmung verwendet.
Diese Wheels können Binärmodule vor Ort enthalten (d. h. ko-lokal mit dem Python-Quellcode, genauso wie Wheels für eine Desktop-Plattform); sie müssen jedoch nachbearbeitet werden, da Binärmodule für die Verteilung in den „Frameworks“-Speicherort verschoben werden müssen. Dies kann mit einem Xcode-Build-Schritt automatisiert werden.
PEP 11 Update
PEP 11 wird aktualisiert, um zwei der iOS-ABIs aufzunehmen
arm64-apple-iosarm64-apple-ios-simulator
Ned Deily wird der anfängliche Kernteam-Ansprechpartner für diese ABIs sein.
Das Ziel x86_64-apple-ios-simulator wird nach bestem Bemühen unterstützt, aber nicht als Tier-3-Ziel angestrebt. Dies liegt an der bevorstehenden Deprecation von x86_64 als Simulationsplattform, kombiniert mit der Schwierigkeit, x86_64 macOS-Hardware derzeit zu beauftragen.
Abwärtskompatibilität
Die Aufnahme einer neuen Plattform führt zu keinen Abwärtskompatibilitätsproblemen für CPython selbst.
Es kann einige Abwärtskompatibilitätsprobleme bei den Projekten geben, die historisch CPython-Unterstützung boten (d. h. BeeWare und Kivy), wenn die endgültige Form von CPython-Patches nicht mit den historisch von ihnen verwendeten Patches übereinstimmt.
Obwohl dies keine strikte Abwärtskompatibilitätsproblematik ist, gibt es eine Überlegung zur Plattformannahme. Auch wenn CPython selbst iOS unterstützt, wird die Fähigkeit der Community, Python unter iOS zu nutzen, eingeschränkt sein, wenn unklar ist, wie iOS-kompatible Wheels erstellt werden, und wenn prominente Bibliotheken wie Kryptographie, Pillow und NumPy keine iOS-Wheels anbieten. Daher ist es notwendig, klar zu dokumentieren, wie Projekte iOS-Builds zu ihrer CI- und Release-Toolchain hinzufügen können. Die Aufnahme von iOS-Unterstützung in Tools wie crossenv und cibuildwheel könnte ein Weg sein, dies zu erreichen.
Sicherheitsimplikationen
Die Aufnahme von iOS als neue Plattform führt zu keinen Sicherheitsimplikationen.
Wie man das lehrt
Die Schulungsbedarfe im Zusammenhang mit dieser PEP beziehen sich hauptsächlich darauf, wie Endbenutzer die iOS-Unterstützung zu ihren eigenen Xcode-Projekten hinzufügen können. Dies kann durch Dokumentation und Tutorials zu diesem Prozess erreicht werden. Der Bedarf an dieser Dokumentation wird steigen, wenn/wenn die Unterstützung von Tier 3 auf Tier 2 oder 1 angehoben wird; dieser Übergang sollte jedoch auch mit vereinfachten Bereitstellungsartefakten (wie einem Cocoapod oder Swift-Paket) einhergehen, die in die Xcode-Entwicklung integriert sind.
Referenzimplementierung
Das BeeWare Python-Apple-support Repository enthält einen Referenz-Patch und Build-Werkzeuge zur Kompilierung eines verteilbaren Artefakts.
Briefcase bietet eine Referenzimplementierung von Code zur Ausführung von Testsuiten auf iOS-Simulatoren. Das Toga Testbed ist ein Beispiel für eine Testsuite, die auf dem iOS-Simulator mithilfe von GitHub Actions ausgeführt wird.
Abgelehnte Ideen
Simulatorerkennung
Frühere Versionen dieser PEP schlugen die Aufnahme des Attributs sys.implementation._simulator vor, um zu identifizieren, wann Code auf einem Gerät oder auf einem Simulator läuft. Dies wurde aufgrund der Verwendung eines geschützten Namens für eine öffentliche API sowie der Verunreinigung des sys-Namespace mit einem iOS-spezifischen Detail abgelehnt.
Ein weiterer Vorschlag während der Diskussion war die Aufnahme einer generischen platform.is_emulator()-API, die von jeder Plattform implementiert werden könnte – beispielsweise um die Ausführung von x86_64-Code auf ARM64-Hardware zu unterscheiden oder wenn in QEMU oder anderen Virtualisierungsmethoden ausgeführt wird. Dies wurde mit der Begründung abgelehnt, dass nicht klar war, was eine konsistente Interpretation von „Emulator“ wäre oder wie ein Emulator außerhalb des iOS-Falls erkannt werden würde.
Die Entscheidung wurde getroffen, dieses Detail iOS-spezifisch zu halten und es in die platform.ios_ver()-API aufzunehmen.
GNU-Compiler-Triples
autoconf erfordert die Verwendung eines GNU-Compiler-Triples zur Identifizierung von Build- und Host-Plattformen. Die autoconf-Toolchain bietet jedoch keine native Unterstützung für iOS-Simulatoren, sodass wir uns mit der Frage auseinandersetzen müssen, wie iOS-Hardware in das Namensschema von GNU gezwängt werden kann.
Dies kann geschehen (mit einigen Patches von config.sub), führt aber zu 2 Hauptquellen für Namensinkonsistenzen
arm64vsaarch64als Identifikator für 64-Bit-ARM-Hardware; und- Welcher Identifikator für Simulatoren verwendet wird.
Apples eigene Tools verwenden arm64 als Architektur, scheinen aber in einigen Fällen tolerant gegenüber aarch64 zu sein. Die Geräteplattform wird als iphoneos und iphonesimulator identifiziert.
Rust-Toolchains verwenden aarch64 als Architektur und verwenden aarch64-apple-ios und aarch64-apple-ios-sim zur Identifizierung der Geräteplattform; sie verwenden jedoch x86_64-apple-ios, um iOS- *Simulatoren* auf x86_64-Hardware darzustellen.
Die Entscheidung fiel zugunsten von arm64-apple-ios und arm64-apple-ios-simulator, weil
- Die
autoconf-Toolchain bereits Unterstützung füriosals Plattform inconfig.subenthält; nur der Simulator hat keine Darstellung. - Der dritte Teil des Host-Triples wird als
sys.platformverwendet. - Wenn Apples eigene Tools die CPU-Architektur referenzieren, verwenden sie
arm64, und die Verwendung der Architektur durch die GNU-Tools ist außerhalb des Build-Prozesses nicht sichtbar. - Wenn Apples eigene Tools den Simulatorstatus unabhängig vom Betriebssystem referenzieren (z. B. bei der Benennung von Swift-Submodulen), verwenden sie einen Suffix
-simulator. - Während *einige* iOS-Pakete Rust verwenden werden, werden *alle* iOS-Pakete Apples Werkzeuge verwenden.
Die anfänglich angenommene Version dieses Dokuments verwendete die aarch64-Form als PEP 11-Identifikator; dies wurde während der Finalisierung korrigiert.
“Universelles” Wheel-Format
macOS unterstützt derzeit 2 CPU-Architekturen. Um die Benutzererfahrung zu verbessern, definiert Python ein „universal2“-Wheel-Format, das sowohl x86_64- als auch ARM64-Binärdateien enthält.
Es wäre konzeptionell möglich, ein analoges „universelles“ iOS-Wheel-Format anzubieten. Diese PEP verwendet diesen Ansatz jedoch aus 2 Gründen nicht.
Erstens hat sich die Erfahrung unter macOS, insbesondere im numerischen Python-Ökosystem, gezeigt, dass universelle Wheels äußerst schwierig zu handhaben sind. Während native macOS-Bibliotheken eine starke plattformübergreifende Unterstützung aufrechterhalten und Python selbst aktualisiert wurde, bietet die überwiegende Mehrheit der Upstream-Nicht-Python-Bibliotheken keine Multi-Architektur-Build-Unterstützung. Infolgedessen erfordert die Kompilierung universeller Wheels zwangsläufig mehrere Kompilierungsdurchläufe und komplexe Entscheidungen darüber, wie Header-Dateien für verschiedene Architekturen verteilt werden. Aufgrund dieser Komplexität bieten viele beliebte Projekte (einschließlich NumPy und Pillow) keine universellen Wheels an und stellen stattdessen separate ARM64- und x86_64-Wheels bereit.
Zweitens zeigt die historische Erfahrung, dass iOS eine flüssigere „universelle“ Definition erfordern würde. In den letzten 10 Jahren gab es *mindestens* 5 verschiedene Interpretationen von „universell“, die auf iOS zutreffen würden, darunter verschiedene Kombinationen von armv6, armv7, armv7s, arm64, x86 und x86_64 Architekturen, auf Geräten und Simulatoren. Wenn „Universal-iOS“ jetzt definiert würde, würde es wahrscheinlich x86_64 und arm64 auf Simulatoren sowie arm64 auf Geräten umfassen; die bevorstehende Deprecation von x86_64-Hardware würde jedoch eine weitere Interpretation hinzufügen; und es könnte in Zukunft notwendig werden, arm64e als neue Gerätearchitektur hinzuzufügen. Die Spezifizierung von iOS-Wheels als Single-Platform-Only bedeutet, dass das Python-Kernteam eine fortlaufende Standardisierungsdiskussion über die aktualisierten „universellen“ Formate vermeiden kann.
Es bedeutet auch, dass Wheel-Publisher individuelle Entscheidungen darüber treffen können, welche Plattformen unterstützt werden können. Ein Projekt kann sich beispielsweise entscheiden, die x86_64-Unterstützung einzustellen oder eine neue Architektur früher als andere Teile des Python-Ökosystems zu übernehmen. Die Verwendung von plattformspezifischen Wheels bedeutet, dass diese Entscheidung einzelnen Paketveröffentlichern überlassen werden kann.
Diese Entscheidung geht auf Kosten einer komplizierteren Bereitstellung. Die Bereitstellung unter iOS ist jedoch bereits ein komplizierter Prozess, der am besten durch Tools unterstützt wird. Derzeit ist keine Binärzusammenführung erforderlich, da es nur eine On-Device-Architektur gibt und Simulator-Binärdateien nicht als verteilbare Artefakte betrachtet werden, sodass nur eine Architektur zum Erstellen einer App für einen Simulator benötigt wird.
Unterstützung statischer Builds
Während die langfristige Machbarkeit der Option --undefined dynamic_lookup nicht garantiert ist, existiert die Option und funktioniert. Eine Option wäre, die Deprecation-Warnung zu ignorieren und zu hoffen, dass Apple entweder die Deprecation-Entscheidung rückgängig macht oder die Deprecation nie abschließt.
Da Apples Entscheidungsprozess völlig undurchsichtig ist, wäre dies im besten Fall eine riskante Option. In Kombination mit der Tatsache, dass das breitere iOS-Entwicklungsökosystem die Verwendung von Frameworks fördert, es keine Legacy-Verwendungen von statischen Bibliotheken gibt, die berücksichtigt werden müssen, und der einzige Vorteil einer statisch verknüpften iOS libpython3.x.a eine sehr geringfügig verkürzte App-Startzeit ist, erscheint das Weglassen der Unterstützung für statische Builds von libpython3.x als ein vernünftiger Kompromiss.
Es ist erwähnenswert, dass es einige Diskussionen über einen alternativen Ansatz zum Verknüpfen unter macOS gab, der die Notwendigkeit der Option --undefined dynamic_lookup beseitigen würde, obwohl die Diskussion über diesen Ansatz aufgrund von Implementierungskomplikationen ins Stocken geraten zu sein scheint. Wenn diese Komplikationen überwunden würden, ist es sehr wahrscheinlich, dass derselbe Ansatz unter iOS verwendet werden *könnte*, was eine statisch verknüpfte libpython3.x.a plausibel machen *würde*.
Die Entscheidung, Binärmodule gegen libpython3.x.dylib zu verknüpfen, würde die Einführung von statischen libpython3.x.a-Builds in Zukunft erschweren, da der Prozess der Umstellung auf einen anderen Ansatz zur Verknüpfung von Binärmodulen eine klare Möglichkeit erfordern würde, „dynamisch verknüpfte“ iOS-Binärmodule von „statisch kompatiblen“ iOS-Binärmodulen zu unterscheiden. Angesichts des Mangels an greifbaren Vorteilen einer statischen libpython3.x.a ist es jedoch unwahrscheinlich, dass eine solche Änderung erforderlich sein wird.
Interaktiver/REPL-Modus
Eine traditionelle python.exe-Kommandozeilen-Erfahrung ist auf Mobilgeräten nicht wirklich praktikabel, da Mobilgeräte keine Kommandozeile haben. iOS-Apps haben kein stdout, stderr oder stdin; und während stdout und stderr an das Systemprotokoll umgeleitet werden können, gibt es keine Quelle für stdin, die nicht auch die Erstellung einer sehr spezifischen benutzerorientierten App erfordert, die eher einer IDLE-ähnlichen IDE-Erfahrung ähneln würde. Daher wurde die Entscheidung getroffen, sich nur auf den „Embedded Mode“ als Ziel für die mobile Verteilung zu konzentrieren.
Unterstützung für x86_64-Simulatoren
Apple verkauft keine x86_64-Hardware mehr. Daher kann die Beauftragung eines x86_64-Buildbots schwierig sein. Es ist möglich, macOS-Binärdateien im x86_64-Kompatibilitätsmodus auf ARM64-Hardware auszuführen; dies ist jedoch für Testzwecke nicht ideal. Daher wird der x86_64-Simulator (x86_64-apple-ios-simulator) nicht als Tier-3-Ziel hinzugefügt. Es ist sehr wahrscheinlich, dass die iOS-Unterstützung ohne Änderungen auf x86_64 funktionieren wird; dies betrifft nur den *offiziellen* Tier-3-Status.
Tests auf Geräten
CI-Tests auf Simulatoren lassen sich relativ einfach unterbringen. Tests auf Geräten sind viel schwieriger, da die Verfügbarkeit von Gerätefarmen, die zur Bereitstellung von Buildbots oder Github Actions-Runnern konfiguriert werden könnten, begrenzt ist.
Tests auf Geräten sind jedoch möglicherweise nicht erforderlich. Als Datenpunkt – Apples Xcode Cloud-Lösung bietet keine Tests auf Geräten. Sie verlassen sich darauf, dass die API zwischen Gerät und Simulator konsistent ist und ARM64-Simulator-Tests ausreichen, um CPU-spezifische Probleme aufzudecken.
Von platform.ios_ver() zurückgegebene Werte
Die anfänglich akzeptierte Version dieses Dokuments enthielt keine system-Kennung. Diese wurde während der Implementierungsphase hinzugefügt, um die Implementierung von platform.system() zu unterstützen.
Die anfänglich akzeptierte Version dieses Dokuments beschrieb auch, dass min_release im Ergebnis von ios_ver() zurückgegeben würde. Die endgültige Version lässt den Wert min_release weg, da er zur Laufzeit nicht signifikant ist; er beeinflusst nur die binäre Kompatibilität. Die Mindestversion *ist* im von sysconfig.get_platform() zurückgegebenen Wert enthalten, da dieser zur Definition der Kompatibilität von Wheels (und anderen Binärdateien) verwendet wird.
Urheberrecht
Dieses Dokument wird in die Public Domain oder unter die CC0-1.0-Universal-Lizenz gestellt, je nachdem, welche Lizenz permissiver ist.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0730.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT