TL; DR;
Đặt "Chỉ xây dựng kiến trúc hoạt động ( ONLY_ACTIVE_ARCH
)" thành Có cho các thư viện / ứng dụng của bạn, ngay cả đối với chế độ phát hành .
Trong khi cố gắng xác định nguyên nhân gốc rễ của vấn đề, tôi đã nhận ra một số sự thật thú vị về Xcode 12.
Xcode 12 thực sự là bước đệm cho Apple Silicon, điều đáng tiếc là vẫn chưa có. Nhưng với nền tảng đó, chúng tôi sẽ nhận được macOS dựa trên arm64, nơi các trình mô phỏng cũng sẽ chạy trên kiến trúc arm64 không giống như kiến trúc x86_64 dựa trên Intel hiện tại.
Xcode thường phụ thuộc vào "Run Destination" để xây dựng các thư viện / ứng dụng của nó. Vì vậy, khi một trình mô phỏng được chọn làm "Đích chạy", nó sẽ xây dựng ứng dụng cho các kiến trúc trình mô phỏng có sẵn và khi một thiết bị được chọn làm "Đích chạy", nó sẽ xây dựng cho kiến trúc mà thiết bị đó hỗ trợ ( arm*
).
xcodebuild
, trong hệ thống xây dựng Xcode 12+ được coi arm64
là kiến trúc hợp lệ cho trình mô phỏng. Vì vậy, khi một trình mô phỏng được chọn làm đích chạy, nó có khả năng cố gắng biên dịch / liên kết các libs / ứng dụng của bạn với các arm64
trình mô phỏng dựa trên (chưa khả dụng). Vì vậy, nó sẽ gửi clang(++)
một số cờ -target như arm64-apple-ios13.0-simulator
ở định dạng <architecture> - <os> - <sdk> - <platform> và clang cố gắng xây dựng / liên kết chống lại trình mô phỏng dựa trên arm64 mà cuối cùng không thành công trên Mac dựa trên Intel.
Nhưng hãy xcodebuild
thử điều này chỉ cho các bản phát hành . Tại sao? Bởi vì, ONLY_ACTIVE_ARCH
cài đặt bản dựng "Build Active Architecture Only ( )" thường được đặt thành "No" chỉ cho cấu hình "Release". Và điều đó có nghĩa là xcodebuild
sẽ cố gắng tạo tất cả các biến thể kiến trúc của libs / ứng dụng của bạn cho đích chạy đã chọn cho các bản phát hành. Và đối với đích chạy Simulator, nó sẽ bao gồm cả hai x86_64
và arm64
bây giờ, vì arm64
trong Xcode 12+ cũng là một kiến trúc được hỗ trợ cho trình mô phỏng để hỗ trợ Apple Silicon.
Nói một cách đơn giản, Xcode sẽ không tạo được ứng dụng của bạn bất cứ khi nào nó thử dòng lệnh xcodebuild
, (mặc định là phát hành bản dựng, hãy xem tab chung của cài đặt dự án của bạn) hoặc nếu không ở chế độ phát hành . Vì vậy, một giải pháp đơn giản cho vấn đề này là đặt "Chỉ xây dựng kiến trúc hoạt động ( ONLY_ACTIVE_ARCH
)" thành Có trong thư viện / ứng dụng của bạn, ngay cả đối với chế độ phát hành.
Nếu các thư viện được bao gồm dưới dạng Pod và bạn có quyền truy cập, .podspec
bạn có thể chỉ cần đặt:
spec.pod_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'CÓ'}
spec.user_target_xcconfig = {'ONLY_ACTIVE_ARCH' => 'YES'} # không được khuyến nghị
Cá nhân tôi không thích dòng thứ hai vì các nhóm không nên gây ô nhiễm cho dự án mục tiêu và nó có thể bị ghi đè trong cài đặt mục tiêu. Vì vậy, dự án người tiêu dùng phải có trách nhiệm ghi đè cài đặt bằng một số phương tiện. Tuy nhiên, điều này có thể cần thiết để in thành công các podspec.
Tuy nhiên, nếu bạn không có quyền truy cập vào .podspec
, bạn luôn có thể cập nhật cài đặt trong quá trình cài đặt các nhóm:
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
Một điều tôi lo ngại về tác động của điều này khi chúng tôi thực sự lưu trữ các libs / ứng dụng. Trong quá trình lưu trữ, các ứng dụng thường lấy cấu hình "Bản phát hành" và vì điều này sẽ tạo một bản phát hành chỉ xem xét kiến trúc đang hoạt động của đích chạy hiện tại, với cách tiếp cận này, chúng tôi có thể mất các lát cho armv7, armv7s, v.v. từ bản dựng đích. Tuy nhiên, tôi nhận thấy tài liệu cho biết (được đánh dấu trong hình đính kèm) rằng cài đặt này sẽ bị bỏ qua khi chúng tôi chọn "Thiết bị iOS chung / Thiết bị bất kỳ" làm đích chạy, vì nó không xác định bất kỳ kiến trúc cụ thể nào. Vì vậy, tôi đoán chúng ta sẽ tốt nếu chúng ta lưu trữ ứng dụng của mình chọn đó làm điểm đến chạy.