Cocoapods 静态库/动态库相关配置的使用
总结 Cocoapods 静态库/动态库相关配置的使用。
1. 不指定 use_frameworks! 或 use_modular_headers!
默认编译成静态库(.a 格式)。如果依赖没有定义 modules 的库,会报错。
举例如下:
# Podfile
source 'https://github.com/Cocoapods/Specs.git'
platform :ios, '13.0'
workspace 'test.xcworkspace'
inhibit_all_warnings!
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
2. 指定 use_modular_headers!
如 1 所说,解决编译成静态库时依赖没有定义 modules 的库的问题。
注:可以和 use_frameworks! 共存,因为 use_frameworks! 只是指定源码组件编译成什么形式的库;use_modular_headers! 是解决没有定义 modules 的库编译成静态库的问题。
3. 指定 use_frameworks! :linkage => :static 或 use_frameworks! :linkage => :dynamic
如果库没有指定产物形式(库的 podspec 文件中定义的 static_framework),将源码组件打包成静态库或动态库(.framework 或 .xcframework 形式)。
4. 指定 use_frameworks!
将源码组件打包成 framework,根据库指定的产物形式(库的 podspec 文件中定义的 static_framework)打包成静态库或动态库。
s.static_framework = true 则打包成静态库,没有指定或者 false 则打包成动态库。
5. static_framework 和 use_frameworks! :linkage 的优先级
库的 podspec 文件中定义的 static_framework ,会覆盖 use_frameworks! :linkage 指定的产物形式。
6. 查看 .framework 是静态库还是动态库
file 命令:
file [build path]/Kingfisher/Kingfisher.framework/Kingfisher
动态库结果:
Frameworks/Kingfisher.framework/Kingfisher: Mach-O 64-bit dynamically linked shared library arm64
静态库结果:
/Kingfisher.framework/Kingfisher: current ar archive
7. 历史原因
● Xcode 9 之前
不支持 Swift 静态库编译,使用 use_frameworks! 指定。但是引用大量动态库会导致应用程序启动时间变长。
● Xcode 9 之后
开始支持 Swift 静态库编译。但如果一个 Swift Pod 依赖一个 OC Pod,那么要为对应的 OC Pod 开启 modular headers,开启 modular headers 的本质就是将 Pod 转换为 Modular(也就是支持模块)。
好处:
-
简化 Swift 引用 OC 的方式
Modular 是可以直接在 Swift 中 import 的,不需要再经过 bridging-header 进行桥接,从而简化了 Swift 引用 OC 的方式。只有支持了模块的框架,才能支持通过模块化头文件(Modular Header)的方式进行导入。我们可以通过添加 modulemap 文件使框架支持模块。 -
强制使用更优的模块导入方式
CocoaPods 诞生之初,使用较为宽松的头文件搜索路径(Header Search Paths),允许 Pod 之间的相互引用,无需考虑命名空间,不必采用 #import <NameSpace/fileName.h> 的模块导入方式,允许采用 #import "fileName.h" 的导入方式。但是,如果使 Pod 支持模块化,会导致 #import "fileName.h" 无法正常导入。使用 use_modular_headers! 可以强制使用更优的模块导入方式。
参考
https://guides.cocoapods.org/syntax/podspec.html#static_framework
https://guides.cocoapods.org/syntax/podfile.html
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