TL; DR;
Setzen Sie "Nur aktive Architektur erstellen ( ONLY_ACTIVE_ARCH
)" für Ihre Bibliotheken / Apps auf " Ja " , auch für den Release- Modus.
Beim Versuch, die Hauptursache des Problems zu identifizieren, wurden mir einige interessante Fakten über Xcode 12 klar.
Xcode 12 ist eigentlich das Sprungbrett für Apple Silicon, das leider noch nicht verfügbar ist. Aber mit dieser Plattform werden wir arm64-basiertes MacOS bekommen, wo Simulatoren im Gegensatz zur gegenwärtigen Intel-basierten x86_64-Architektur auch auf arm64-Architektur laufen.
Xcode hängt normalerweise vom "Ausführungsziel" ab, um seine Bibliotheken / Apps zu erstellen. Wenn also ein Simulator als "Ausführungsziel" ausgewählt wird, wird die App für verfügbare Simulatorarchitekturen erstellt, und wenn ein Gerät als "Ausführungsziel" ausgewählt wird, wird die für das Gerät unterstützte Architektur erstellt ( arm*
).
xcodebuild
wird im Xcode 12+ Build-System arm64
als gültige Architektur für den Simulator betrachtet. Wenn also ein Simulator als Ausführungsziel ausgewählt wird, kann er möglicherweise versuchen, Ihre Bibliotheken / Apps auch mit arm64
basierten Simulatoren zu kompilieren / zu verknüpfen (noch nicht verfügbar). Es sendet clang(++)
also ein Zielflag wie arm64-apple-ios13.0-simulator
im Format <Architektur> - <os> - <sdk> - <Plattform> und Clang versucht, einen arm64-basierten Simulator zu erstellen / zu verknüpfen, der schließlich auf einem Intel-basierten Mac fehlschlägt.
Aber xcodebuild
versucht , dies nur für Veröffentlichung baut. Warum? Da die Build- ONLY_ACTIVE_ARCH
Einstellungen für " Nur aktive Architektur erstellen ( )" normalerweise nur für die Konfiguration "Release" auf "Nein" gesetzt sind. Das bedeutet, xcodebuild
dass versucht wird, alle Architekturvarianten Ihrer Bibliotheken / Apps für das ausgewählte Ausführungsziel für Release-Builds zu erstellen. Und für das Simulator-Ausführungsziel wird es beides enthalten x86_64
und arm64
jetzt, da arm64
in Xcode 12+ auch eine Architektur für Simulatoren zur Unterstützung von Apple Silicon unterstützt wird.
Einfach ausgedrückt, Xcode kann Ihre App nicht jedes Mal erstellen, wenn es die Befehlszeile versucht xcodebuild
(standardmäßig wird Build veröffentlicht, siehe die allgemeine Registerkarte Ihrer Projekteinstellung) oder auf andere Weise im Release- Modus. Eine einfache Problemumgehung für dieses Problem besteht darin, "Nur aktive Architektur erstellen ( ONLY_ACTIVE_ARCH
)" in Ihren Bibliotheken / Apps auf " Ja " zu setzen , auch für den Release-Modus.
Wenn die Bibliotheken als Pods enthalten sind und Sie Zugriff darauf haben .podspec
, können Sie einfach Folgendes festlegen:
spec.pod_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'}
spec.user_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'} # nicht empfohlen
Ich persönlich mag die zweite Zeile nicht, da Pods das Zielprojekt nicht verschmutzen sollten und es in den Zieleinstellungen selbst überschrieben werden könnte. Es sollte also in der Verantwortung des Verbraucherprojekts liegen, die Einstellung auf irgendeine Weise außer Kraft zu setzen. Dies kann jedoch für ein erfolgreiches Flusen von Podspecs erforderlich sein.
Wenn Sie jedoch keinen Zugriff auf die haben .podspec
, können Sie die Einstellungen während der Installation der Pods jederzeit aktualisieren:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
end
end
end
Ich war besorgt darüber, welche Auswirkungen dies haben wird, wenn wir die Bibliotheken / Apps tatsächlich archivieren. Während der Archivierung nehmen Apps normalerweise die "Release" -Konfiguration an. Da hierdurch ein Release-Build erstellt wird, der nur die aktive Architektur des aktuellen Ausführungsziels berücksichtigt, verlieren wir bei diesem Ansatz möglicherweise die Slices für armv7, armv7s usw. aus dem Ziel-Build. Ich habe jedoch festgestellt, dass in der Dokumentation (im beigefügten Bild hervorgehoben) angegeben ist, dass diese Einstellung ignoriert wird, wenn "Generisches iOS-Gerät / Beliebiges Gerät" als Ausführungsziel ausgewählt wird, da keine bestimmte Architektur definiert wird. Ich denke, wir sollten gut sein, wenn wir unsere App archivieren und dies als Laufziel auswählen.