Migrieren Sie iOS (ARM) -Anwendungen mithilfe von Bitcode automatisch auf macOS (x86)

Als Apple die Bitcode-Technologie einführte und sie für watchOS und tvOS verbindlich machte, schien das Unternehmen Fragen zu beantworten, warum sie überhaupt benötigt wurde. Sie sagte nur vage, dass es hilft, Binärdateien anzupassen und die neuesten Compiler-Verbesserungen verwendet.

Seitdem spielt Bitcode eine wichtige Rolle beim reibungslosen Übergang von watchOS zu 64 Bit, bei dem Entwickler ihre Anwendungen im Verzeichnis nicht einmal neu kompilieren mussten. Apple selbst hat dies automatisch getan: Alle Anwendungen haben mit der Apple Watch Series 4 begonnen. Sie haben wahrscheinlich nicht einmal bemerkt, dass die Migration stattgefunden hat.

Was ist Bitcode? Nun, Bitcode mit kleinem b ist die von LLVM verwendete architekturspezifische Zwischendarstellung, und Bitcode mit großem B bezieht sich auf eine Reihe von Funktionen, mit denen Sie diese Ansicht in Ihre Mach-O-Binärdatei einbetten können, sowie auf die Mechanismen, mit denen Sie diese Datei rendern können im App Store.

Bitcode ist nicht so flexibel wie der Quellcode, aber viel flexibler als die eingebettete Binärdatei mit Metadaten und Anmerkungen für den Compiler. In der Praxis können Sie (oder Apple) die Bitcode-Blobs einfach aus der Anwendung entnehmen und zu einer voll funktionsfähigen Kopie Ihrer Anwendung neu kompilieren. Der Wechsel von armv7 zu armv7s oder von arm64 zu arm64e ist sehr cool und spart Entwicklern Zeit, die die Binärdatei jedes Mal neu kompilieren mussten, wenn Apple die ARM-Chips wechselt. Bitcode wird seit langem von Apple in OpenGL-Treibern verwendet, sodass der Treiber im laufenden Betrieb für verschiedene GPU-Architekturen optimiert werden kann.

Wir haben gesehen, wie Microsoft die statische Neukompilierung auf der Xbox One effektiv nutzt und Zugriff auf eine ganze Bibliothek von Spielen bietet, die ursprünglich für die Xbox 360 (unter PowerPC) geschrieben wurden, ohne dass Entwickler involviert sind oder auf den Quellcode zugreifen müssen. Und ohne einen Vermittler wie Bitcode, der den Prozess vereinfacht.

Natürlich hängt der Geist von macOS auf ARM seit vielen Jahren herum. Viele fragten sich, ob dies das Portieren von Anwendungen mit Bitcode erleichtern würde. Infolgedessen waren sie sich einig, dass Bitcode nicht für die Übertragung zwischen radikal unterschiedlichen Architekturen wie Intel und ARM geeignet ist.

Das hat mich nicht überzeugt, also habe ich mich entschlossen zu überprüfen!

Zu Beginn benötigen wir eine einfache Testanwendung für Objective-C mit Bitcode. Es ist normalerweise nur beim Erstellen eines Archivs für den App Store enthalten. Sie müssen daher erzwingen, dass es in die reguläre Assembly aufgenommen wird. Sie können das -fembed-bitcode oder eine benutzerdefinierte Build-Option verwenden:

 BITCODE_GENERATION_MODE = bitcode 

Erstellen Sie wie gewohnt eine Binärdatei für das generische iOS-Gerät oder das angeschlossene Gerät. Es scheint, dass Bitcode nicht in arm64e-Assemblys integriert ist (z. B. wenn Sie ein A12-Gerät haben), sodass Sie die Xcode-Einstellung "Nur für aktive Architekturen kompilieren" deaktivieren und direkt für arm64 kompilieren können.

Mit dem ebcutil- Tool können alle Bitcode- Objekte einfach aus einer kompilierten Binärdatei abgerufen werden.

 ebcutil -a arm64 -e path/to/MyApp.app/MyApp 

Kompilieren Sie dann jedes Bitcode-Objekt für Intel neu.

 for f in *; do clang -arch x86_64 -c -Xclang -disable-llvm-passes -emit-llvm -x ir -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk $f -o $fo; done 

Jetzt verknüpfen wir die kompilierten Blobs wieder mit der Binärdatei.

 clang -arch x86_64 -mios-version-min=12.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk *.o -o path/to/MyApp.app/MyApp 

Wenn es funktioniert, haben wir jetzt die x86-Version der ursprünglichen arm64-Anwendung! Theoretisch kann es direkt im iOS-Simulatorfenster platziert, installiert und gestartet werden.

Dies ist eine sehr wichtige Tatsache: Sie können Binärdateien statisch zwischen Intel- und ARM-Plattformen übertragen, wenn diese Bitcode enthalten . Es funktioniert wirklich!


Fallstricke für komplexere Projekte


Es scheint, dass ARC den integrierten Assembler verwendet, sodass Sie für die Übertragung von arm64 auf x86 im Moment ARC deaktivieren müssen.

Einige Arten von Blöcken, z. B. Vervollständigungshandler, starten den Compiler mit nicht akzeptablen Anweisungen. Wenn Sie einen X87-Fehler erhalten, ist dies wahrscheinlich das Problem.

Warum ist Objective-C? Swift wurde speziell für ARC entwickelt. Ich glaube nicht, dass es eine Möglichkeit gibt, den oben genannten Inline-Assembler zu vermeiden, daher schlägt die Neukompilierung jetzt fehl.
Machen wir noch einen Schritt: Wir werden marzipanify verwenden , um diese Intel iOS-Anwendung in ein Mac-Programm zu konvertieren, das mit Marzipan funktioniert.



Es war einfach!

Theoretisch bedeutet dies, dass Apple jede iOS-Anwendung aus dem App Store auf einem Mac ausführen kann, ohne dass Entwickler ihre Anwendungen aktualisieren oder neu kompilieren müssen.


Was ist, wenn der Mac von Intel auf ARM-Chips umschaltet? Wie Sie sehen, können mit Bitcode alle Bitcode-fähigen Anwendungen ohne die Hilfe von Entwicklern in den Mac App Store übertragen werden, sodass der Prozessor vom ersten Tag an geändert werden kann. Dies gibt Apple mehr Freiheit. Jetzt müssen Sie die Umstellung auf neue Prozessoren nicht ein Jahr im Voraus bekannt geben, und Technologien wie Rosetta werden nicht mehr benötigt.

Offensichtlich haben wir diesen Punkt noch nicht erreicht: Heute enthält Apple keinen Bitcode für Anwendungen im Mac App Store, und heute ist Bitcode möglicherweise nicht ideal für eine solche Architekturübertragung. Anstelle von Apple würde ich mich auf diese beiden Faktoren konzentrieren und natürlich Bitcode für alle Marzipan-Apps unter macOS 10.15 aktivieren.

Source: https://habr.com/ru/post/de452734/


All Articles