天天看點

excluded architectures 相關

作者:每周IT

問題現象1:

  1. building for iOS Simulator-arm64 but attempting to link with file built for iOS Simulator-x86_64
  2. building for iOS Simulator, but linking in object file built for iOS, file '/Users///framework/' for architecture arm64

問題分析:

字面意思來看,是說link了不支援模拟器的FrameWork,通常需要檢查三方庫,看看三方庫是不是不支援模拟器,比如支付的早期就不支援模拟器。

Xcode12在編譯模拟器的時候優先使用arm64架構編譯,而過去打包模拟器是沒有arm64的,arm64架構隻适用于真機。是以報錯linking了一個真機的FrameWork。

解決方案大緻是(錯誤的方案):

I've seen quite a bit of weird behavior with frameworks, I think due to changes to the simulators to support Apple silicon. My temporary workaround is, in my app/extension targets, to add "arm64" to the Excluded Architectures build setting when building for the simulator (as your preview appears to be trying to do), and setting "Build Active Architecture Only" to No for all schemes. Might be worth a try.

Check if in your project for compiled target ->build settings -> user defined section (at the very bottom) you have defined VALID_ARCHS=arm64, if yes, delete it.

大緻是說删除VALID_ARCHS=arm64,然後Build Active Architecture Only 設定為NO

excluded architectures 相關

image.png

實際測試,确實可行了。但是帶來了新的問題,這樣沒法編譯真機了……

解決方案(推薦2)

  1. build settings->excluded architectures 中加入arm64架構,代表不編譯arm64架構。但是這種做法會導緻無法編譯真機,因為真機是arm64架構。是以需要勾選Any iOS Simulator SDK,解決。
  2. build settings->build active architecture only 設定為YES,代表僅編譯目前項目中包含的架構。這個設定适用于模拟器和真機。
  3. 如果使用了XCConfig配置檔案,那麼設定EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64,效果同1

問題現象2:

fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: ***.a have the same architectures (arm64) and can't be in the same fat output file

問題分析:

打包的時候設定Build Active Architecture Only為no則代表打适用于所有機型的包,Xcode11 打包的模拟器的.a預設支援i386、x86_64,Xcode12 打包的模拟器.a預設支援i386、x86_64、arm64。比Xcode11多了arm64,而arm64通常用于真機,是以在合并模拟器的.a和真機的.a的時候起了沖突。

解決方案:

打包的時候強制指定${CONFIG} ARCHS="i386 x86_64", Xcode 配置build settings->+user-defined->VALID_ARCHS = i386 x86_64,或者直接設定Architectures = i386 x86_64

問題現象3:

報錯1:DemoApp.xcodeproj The linked framework **framework' is missing one or more architectures required by this target: armv7.

報錯2:ld: in **, building for iOS, but linking in object file (**) built for iOS Simulator, file '*' for architecture arm64

問題分析:

既然Xcode12模拟器預設支援了arm64,那麼我們直接打出一個模拟器的FrameWork,真機是否可以直接使用?

解決方案:

答案是不可以。真機無法使用模拟器的arm64。報錯1是直接使用模拟器的包編譯會提示找不到armv7,改了build active architecture only後報錯2。

Xcode12 提到了Universal APP(通用APP),MacOS11 的Apple晶片支援手機應用在電腦上運作。推測可能是蘋果為新電腦做的适配,假設新電腦支援arm64,那就應該支援編譯arm64的模拟器和真機。開發者大會有提及,但是細節不明。

解決方案:暫時隻能老老實實回退到不包含arm64的模拟器包

解決方法:spec 檔案移除指定cpu ,否則校驗報錯,好像是xcode

spec.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
 spec.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }           

1.錯誤

xcode12更新之後,如果私有庫引入了第三方庫,pod repo push時會出現以下錯誤:

ld: building for iOS Simulator, but linking in dylib built for iOS, file ' XXX ' for architecture arm64
clang: error: linker command failed with exit code 1

           

2.原因

這是因為新xcode為了适配即将釋出arm架構晶片mac,會在編譯的時嘗試生成模拟器版本的arm64架構的可執行檔案。然而引入的第三方SDK還沒來得及更新,老版本的第三方SDK并不包含模拟器版本的arm64架構可執行檔案,是以在連結的時候就會失敗,上面的錯誤提示也能看出端倪。簡單來說就以下兩個原因:

1.新xcode要生成模拟器版本的arm64架構可執行檔案

2.引入的第三方sdk并沒有更新,不存在模拟器版本的arm64架構可執行檔案

3.解決方案:

解決方法分一下幾種情況:

1.使用第三方SDK生成動态動态庫:

這種情況出現在swift項目中,為了解決第三方靜态庫在元件化中出現傳遞依賴等問題,把第三方SDK的靜态庫編譯成一個動态庫,制作方案可以參考元件化-動态庫實戰,這裡就不做詳細介紹了。這種情況需要在項目的target -> BuildSettings->EXCLUDED_ARCHS添加剔除模拟器arm64架構配置:

excluded architectures 相關

image

2.普通私有庫pod repo push時報錯:

這種情況需要在podesc檔案添加一下代碼:

s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

s.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }

參考資料

3. 如果項目使用了cocoapods需要在項目的Podfile裡面添加代碼段,然後執行pod install

post_install do |installer|
  installer.pods_project.build_configurations.each do |config|
    config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
  end
end           

繼續閱讀