總結(jié) Cocoapods 靜態(tài)庫/動態(tài)庫相關配置的使用先舷。
知識背景介紹
iOS 靜態(tài)庫和動態(tài)庫產(chǎn)物有兩種形式悲敷,.a 和 .xcframework/.framework昼钻。
.a 是靜態(tài)庫溃论,.xcframework/.framework 可能是靜態(tài)庫,也可能是動態(tài)庫霉涨。
.xcframework 包含不同 CPU 架構(gòu)下的 .framework。
配置總結(jié)
列舉各種配置的情況惭适。
不指定 use_frameworks! 或 use_modular_headers!
默認編譯成靜態(tài)庫(.a 格式)嵌纲。
如果依賴沒有定義 modules 的庫,會報錯腥沽。舉例如下:
'https://github.com/Cocoapods/Specs.git'
platform :ios, '13.0'
workspace 'test.xcworkspace'
target 'test' do
pod 'KingfisherWebP'
end
報錯:
[!] The following Swift pods cannot yet be integrated as static libraries:
The Swift pod KingfisherWebP depends upon libwebp, which does not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers! globally in your Podfile, or specify :modular_headers => true for particular dependencies.
可以通過在 Podfile 中全局指定或指定對應的庫來解決:
use_modular_headers!
或者
pod 'libwebp', :modular_headers => true
僅指定 use_frameworks!
根據(jù)庫指定的產(chǎn)物形式(庫的 podspec 文件中定義的 static_framework)逮走,將源碼組件打包成 .xcframework 形式的靜態(tài)庫或動態(tài)庫。 s.static_framework = true 則打包成靜態(tài)庫今阳,沒有指定或者 false 則打包成動態(tài)庫师溅。
s.static_framework = true
僅對源碼組件有效。
僅指定 use_frameworks! :linkage => :static
如果庫沒有指定產(chǎn)物形式(庫的 podspec 文件中定義的 static_framework)盾舌,則將源碼組件打包成 .xcframework 形式的靜態(tài)庫墓臭。
僅對源碼組件有效。
僅指定 use_frameworks! :linkage => :dynamic
如果庫沒有指定產(chǎn)物形式(庫的 podspec 文件中定義的 static_framework)妖谴,則將源碼組件打包成 .xcframework 形式的動態(tài)庫窿锉。
僅對源碼組件有效。
static_framework 和 use_frameworks! :linkage 的優(yōu)先級
庫的 podspec 文件中定義的 static_framework 膝舅,會覆蓋 use_frameworks! :linkage 指定的產(chǎn)物形式嗡载。
僅指定 use_modular_headers!
如第一種情況所說,解決編譯成靜態(tài)庫時依賴沒有定義 modules 的庫的問題仍稀。
可以和 use_frameworks! 共存洼滚,因為 use_frameworks! 只是指定源碼組件編譯成動態(tài)庫還是靜態(tài)庫,而 use_modular_headers! 是解決沒有定義 modules 的庫編譯成靜態(tài)庫的問題技潘。
查看 .framework 是靜態(tài)庫還是動態(tài)庫
file 命令:
file [build path]/Kingfisher/Kingfisher.framework/Kingfisher
動態(tài)庫結(jié)果:
Frameworks/Kingfisher.framework/Kingfisher: Mach-O 64-bit dynamically linked shared library arm64
靜態(tài)庫結(jié)果:
/Kingfisher.framework/Kingfisher: current ar archive
歷史原因
● Xcode 9 之前 不支持 Swift 靜態(tài)庫編譯遥巴,使用 use_frameworks! 指定千康。但是引用大量動態(tài)庫會導致應用程序啟動時間變長。
● Xcode 9 之后 開始支持 Swift 靜態(tài)庫編譯铲掐。但如果一個 Swift Pod 依賴一個 OC Pod拾弃,那么要為對應的 OC Pod 開啟 modular headers,開啟 modular headers 的本質(zhì)就是將 Pod 轉(zhuǎn)換為 Modular(也就是支持模塊)摆霉。
好處:
- 簡化 Swift 引用 OC 的方式 Modular 是可以直接在 Swift 中 import 的砸彬,不需要再經(jīng)過 bridging-header 進行橋接,從而簡化了 Swift 引用 OC 的方式斯入。只有支持了模塊的框架砂碉,才能支持通過模塊化頭文件(Modular Header)的方式進行導入。我們可以通過添加 modulemap 文件使框架支持模塊刻两。
- 強制使用更優(yōu)的模塊導入方式 CocoaPods 誕生之初增蹭,使用較為寬松的頭文件搜索路徑(Header Search Paths),允許 Pod 之間的相互引用磅摹,無需考慮命名空間滋迈,不必采用 #import <NameSpace/fileName.h> 的模塊導入方式,允許采用 #import "fileName.h" 的導入方式户誓。但是饼灿,如果使 Pod 支持模塊化,會導致 #import "fileName.h" 無法正常導入帝美。使用 use_modular_headers! 可以強制使用更優(yōu)的模塊導入方式碍彭。
參考
https://guides.cocoapods.org/syntax/podfile.html
https://guides.cocoapods.org/syntax/podspec.html#static_framework http://blog.cocoapods.org/CocoaPods-1.5.0/ http://clang.llvm.org/docs/Modules.html https://andelf.github.io/blog/2014/06/19/modules-for-swift/ https://stackoverflow.com/questions/52855780/sub-project-does-not-find-swift-modules-installed-via-pods