Xcode 11 kompiliert (fast?) Mein gesamtes Projekt neu, selbst wenn ich nur eine lokale private Variable oder einen Wert einer Konstanten im lokalen Bereich ändere, manchmal sogar im lokalen privaten Funktionsbereich. Ich kann manchmal 2 oder 3 Änderungen mit schnellen Builds wie erwartet erhalten, aber bald genug entscheidet es sich, alles erneut zu kompilieren (was zu lange dauert).
Irgendwelche Ideen, was los sein könnte? Kann Xcode nicht feststellen, was geändert wurde, warum werden so viele andere Dinge (sogar andere Module) neu kompiliert?
Jeder Rat wird sehr geschätzt, danke!
Antworten:
Wir hatten das gleiche Problem und haben es behoben. Zweimal.
Inkrementeller Build (gleiche Build-Maschine):
vor: ~ 10m nach: ~ 35s
WIE?
Beginnen wir zuerst mit unserer Erfahrung. Wir hatten ein riesiges Swift / Obj-C-Projekt und das war das Hauptanliegen: Die Erstellungszeiten waren langsam und Sie mussten ein neues Projekt erstellen, um eine neue Funktion zu implementieren (im wahrsten Sinne des Wortes). Bonuspunkte für nie funktionierende Syntaxhervorhebung.
Theorie
Um dies wirklich zu beheben, müssen Sie wirklich verstehen, wie das Build-System funktioniert. Versuchen wir zum Beispiel dieses Code-Snippet:
und stellen Sie sich vor, Sie verwenden alle diese Importe in Ihrer Datei. Und auch diese Datei hängt von einer anderen Datei ab, die von anderen Bibliotheken abhängt, die wiederum andere Bibliotheken usw. verwendet.
Um Ihre Datei zu kompilieren, muss Xcode jede Bibliothek kompilieren, die Sie erwähnt haben, und jede Datei, von der es abhängt. Wenn Sie also eine der "Kern" -Dateien ändern, muss Xcode buchstäblich das gesamte Projekt neu erstellen.
Der Xcode-Build ist ein Multithread-Baum , besteht jedoch aus vielen Single-Thread- Bäumen .
Im ersten Schritt jedes inkrementellen Builds entscheidet Xcode, welche Dateien neu kompiliert werden müssen, und erstellt einen AST-Baum . Wenn Sie eine Datei ändern, die von anderen Dateien als " zuverlässig " fungiert, muss jede andere Datei, die als " abhängig " fungiert, neu kompiliert werden.
Der erste Rat ist also, die Kupplung zu senken . Ihre Projektteile müssen unabhängig voneinander sein.
Obj-C / Swift Brücke
Problem mit diesen Bäumen Wenn Sie eine Obj-C / Swift-Brücke verwenden, muss Xcode mehr Phasen als gewöhnlich durchlaufen:
Perfekte Welt:
Obj-C / Swift-Brücke:
Wenn Sie also etwas von Schritt 1 oder 2 ändern, sind Sie im Grunde in Schwierigkeiten. Die beste Lösung besteht darin, Obj-C / Swift Bridge zu minimieren (und aus Ihrem Projekt zu entfernen).
Wenn Sie keine Obj-C / Swift-Brücke haben, ist das großartig und Sie können mit dem nächsten Schritt fortfahren:
Schneller Paketmanager
Zeit, zu SwiftPM zu wechseln (oder zumindest Ihre Cocoapods besser zu konfigurieren).
Die meisten Frameworks mit der Standardkonfiguration von Cocoapods ziehen eine Menge Dinge mit sich, die Sie nicht benötigen.
Um dies zu testen, erstellen Sie ein leeres Projekt mit nur einer Abhängigkeit wie beispielsweise PinLayout und versuchen Sie, diesen Code mit Cocoapods (Standardkonfiguration) und SwiftPM zu schreiben.
Spoiler: Cocoapods kompilieren diesen Code, da Cocoapods JEDEN IMPORT von PinLayout (einschließlich UIKit) importieren und SwiftPM nicht, weil SwiftPM Frameworks atomar importiert.
Schmutziger Hack
Erinnerst du dich, dass Xcode Build Multithreaded ist?
Nun, Sie können es missbrauchen, wenn Sie Ihr Projekt in viele unabhängige Teile aufteilen und alle als unabhängige Frameworks in Ihr Projekt importieren können. Es verringert zwar die Kopplung und das war tatsächlich die erste Lösung, die wir verwendeten, aber es war tatsächlich nicht sehr effektiv, da wir die inkrementelle Bauzeit nur auf ~ 4-5 m reduzieren konnten, was im Vergleich zur ersten Methode NICHTS ist.
quelle
Hier gibt es keine goldene Kugel, aber es gibt viele Dinge zu überprüfen:
Stellen Sie sicher, dass Sie tatsächlich die Debug- Konfiguration in Ihrem Schema verwenden
Im Folgenden erfahren Sie, wie Sie sicherstellen können, dass Sie inkrementelle Builds im Vergleich zum gesamten Modul gemäß den Empfehlungen von matt verwenden. Stellen Sie außerdem sicher, dass Ihre Optimierungsstufe für Debug-Builds keine ist.
Wenn Sie typabhängige Frameworks wie RxSwift verwenden, kann das Hinzufügen expliziter Typanmerkungen die Erstellungszeiten verkürzen.
Wenn das Projekt sehr groß ist, können Sie logische Gruppen von Quelldateien in Frameworks umgestalten. Dies kann jedoch zu drastisch sein, als Sie es bevorzugen
Es könnte hilfreich sein, wenn Sie weitere Einzelheiten zum Projekt angeben: Verknüpfen Sie statisch Bibliotheken? Ist es ein Framework oder ein App-Ziel? Wie groß und welche schnelle Version verwenden Sie? Haben Sie benutzerdefinierte Build-Phasen wie Linters oder Codegenerierung, die manchmal übersprungen werden können?
quelle