TL; DR;
Ustaw opcję „Build Active Architecture Only ( ONLY_ACTIVE_ARCH
)” na Yes dla swoich bibliotek / aplikacji, nawet w trybie wydania .
Próbując zidentyfikować główną przyczynę problemu, zdałem sobie sprawę z kilku zabawnych faktów na temat Xcode 12.
Xcode 12 jest tak naprawdę odskocznią dla Apple Silicon, który niestety nie jest jeszcze dostępny. Ale dzięki tej platformie otrzymamy macOS oparty na arm64, w którym symulatory będą również działać na architekturze arm64, w przeciwieństwie do obecnej architektury x86_64 opartej na Intelu.
Xcode zwykle opiera się na „Run Destination”, aby zbudować swoje biblioteki / aplikacje. Tak więc, gdy symulator jest wybrany jako „miejsce docelowe uruchamiania”, tworzy aplikację dla dostępnych architektur symulatora, a gdy urządzenie jest wybrane jako „miejsce docelowe uruchamiania”, buduje je dla architektury obsługiwanej przez urządzenie ( arm*
).
xcodebuild
, w systemie kompilacji Xcode 12+ uważa się arm64
za prawidłową architekturę symulatora. Więc kiedy symulator zostanie wybrany jako miejsce docelowe uruchomienia, może potencjalnie spróbować skompilować / połączyć twoje biblioteki / aplikacje również z arm64
bazującymi na nich symulatorami (jeszcze niedostępne). Więc wysyła clang(++)
jakąś flagę -target, jak arm64-apple-ios13.0-simulator
w formacie <architecture> - <os> - <sdk> - <platform> i clang próbuje zbudować / połączyć się z symulatorem opartym na arm64, który ostatecznie zawodzi na Macu opartym na Intelu.
Ale xcodebuild
próbuje tego tylko w przypadku kompilacji wydania . Czemu? Ponieważ ustawienia kompilacji „Build Active Architecture Only ( ONLY_ACTIVE_ARCH
)” są zwykle ustawione na „No” (Nie) tylko dla konfiguracji „Release”. A to oznacza, xcodebuild
że spróbujemy zbudować wszystkie warianty architektoniczne twoich bibliotek / aplikacji dla wybranego miejsca docelowego uruchamiania dla kompilacji wydania. A jeśli chodzi o miejsce docelowe uruchomienia symulatora, będzie zawierało oba x86_64
i arm64
teraz włączone, ponieważ arm64
w Xcode 12+ jest również obsługiwana architektura dla symulatorów obsługujących Apple Silicon.
Mówiąc najprościej, Xcode nie zbuduje Twojej aplikacji za każdym razem, gdy spróbuje użyć wiersza polecenia xcodebuild
(co domyślnie powoduje wydanie kompilacji, zobacz kartę ogólną ustawień projektu) lub w inny sposób i spróbuje zbudować wszystkie warianty architektoniczne obsługiwane przez miejsce docelowe uruchamiania . Dlatego prostym obejściem tego problemu jest ustawienie „Build Active Architecture Only ( ONLY_ACTIVE_ARCH
)” na Yes w swoich bibliotekach / aplikacjach, nawet w trybie wydania.
Jeśli biblioteki są uwzględnione jako pody i masz do nich dostęp .podspec
, możesz po prostu ustawić:
spec.pod_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'TAK'}
spec.user_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'} # niezalecane
Osobiście nie podoba mi się druga linia, ponieważ pody nie powinny zanieczyszczać projektu docelowego i mogą zostać zastąpione w samych ustawieniach docelowych. Tak więc projekt konsumencki powinien w jakiś sposób odpowiadać za nadpisanie ustawienia. Jednak może to być konieczne do pomyślnego kłaczkowania podspecs.
Jeśli jednak nie masz dostępu do .podspec
, zawsze możesz zaktualizować ustawienia podczas instalacji podów:
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
Martwiłem się o to, jaki będzie to wpływ, kiedy faktycznie zarchiwizujemy biblioteki / aplikacje. Podczas archiwizacji aplikacje zwykle przyjmują konfigurację „Release”, a ponieważ będzie to tworzenie kompilacji wydania uwzględniającej tylko aktywną architekturę bieżącego miejsca docelowego uruchomienia, przy takim podejściu możemy utracić wycinki dla armv7, armv7s itp. Z docelowej kompilacji. Jednak zauważyłem, że dokumentacja mówi (zaznaczona na załączonym obrazku), że to ustawienie zostanie zignorowane, gdy wybierzemy „Generic iOS Device / Any Device” jako miejsce docelowe uruchomienia, ponieważ nie definiuje ono żadnej konkretnej architektury. Więc myślę, że powinniśmy być dobrzy, jeśli zarchiwizujemy naszą aplikację, wybierając ją jako miejsce docelowe.