SDK开发-类库嵌套
SDK开发-类库嵌套
此篇文章仅限于SDK
开发中的嵌套场景汇总, 不包含具体问题的解决方案
简要总结:
静态库:
1. framework嵌套framework, 不会被包含, 项目仍需导入被嵌套的framework
2. framework嵌套.a库, 可以, 如果项目也导入了.a库, 会符号表冲突, 处理方案: 加前缀
3. .a嵌套.a, 可以
4. .a嵌套framework, 不会将framework内容link到.a中, 项目仍需导入framework
动态库:
1. framework嵌套.a, 可以, .a的内容会被link到framework中
2. framework嵌套静态framework, 可以, 会将静态的framework内容link到动态framework中
3. framwrokd嵌套动态framework, 不会被包含, 项目仍需导入依赖的framework
准备测试工程
利用
pod lib
快速准备6个SDK
工程.a
静态库1:LibStaticA
.a
静态库2:LibStaticB
Framework
静态库1:LibStaticFrameworkA
Framework
静态库2:LibStaticFrameworkB
Framework
动态库1:LibDynamicFrameworkA
Framework
动态库2:LibDynamicFrameworkB
- 用来继承调试最终
SDK
的Demo
:SDKIntegratedDemo
- 如果是自己新建的工程, 使用
Target
依赖的方式, 编译好类库后, 将生成的类库直接拖入另外的类库Target
下即可- 如果是
pod lib
, 注意.podspec
文件配置的资源路径, 导入后在Example
下执行pod install
完成依赖- 实际开发中如果
.a
支持git
,可以通过subspec
实现,依赖集成会相对简单, 我这里都是本地.a
依赖, 无法执行lint
操作, 也不支持cocoapods-package
1. .a
嵌套.a
准备阶段:
编译生成LibStaticA
库后, 将.h
和.a
二进制文件导入到LibStaticB
静态库内, 为了结构清晰, 存放到文件夹LibStaticA
中
目录结构:
.
├── Example ~> 调试demo
│ ├── LibStaticB
│ │ ├── ...
│ │ ├── LViewController.h
│ │ ├── LViewController.m
│ │ └── ...
│ └── ...
│
├── LibStaticB ~> .a 静态库B
│ ├── Assets
│ └── Classes
│ ├── LibStaticA ~> 嵌套的.a 静态库A
│ │ ├── LibStaticA.h
│ │ └── libLibStaticA.a
│ ├── LibStaticB.h
│ └── LibStaticB.m
├── LibStaticB.podspec
└── _Pods.xcodeproj
结论:
.a
能够嵌套.a
库, 项目集成后不需要重复导入
2. .a
嵌套Framework
静态库
准备阶段:
利用刚刚的firstStaticLib
项目, 再新建一个Framework
静态库项目, 名称firstStaticFramework
目录结构:
.
├── FirstStaticLibDemo -> [Demo Target]
│ ├── 省略不相关文件...
│ ├── ViewController.h
│ └── ViewController.m
├── firstStaticLib -> [.a static library Target]
│ ├── FirstStaticLib.h
│ ├── FirstStaticLib.m
│ └── firstStaticFramework.framework -> [嵌套的framework静态库]
│ ├── Headers
│ │ └── FirstStaticFrameworkLib.h
│ └── firstStaticFramework
└── firstStaticLib.xcodeproj
└── 省略不相关文件...
在firstStaticLib
中使用Framework
的接口
#import "FirstStaticLib.h"
#import <firstStaticFramework/FirstStaticFrameworkLib.h>
@implementation FirstStaticLib
+ (void)firstStaticLib {
NSLog(@"%s", __func__);
// Framework接口
[FirstStaticFrameworkLib firstStaticFrameworkLib];
}
@end
编译报错, 找不到被嵌套的Framework
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_FirstStaticFrameworkLib", referenced from:
objc-class-ref in libfirstStaticLib.a(FirstStaticLib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
firstStaticLib
这个Target
中虽然包含了Framework
静态库, 但在调试项目FirstStaticLibDemo
这个Target
下并没有包含 在项目FirstStaticLibDemo
这个Target
再导入一次Framework
就可以正常运行了
结论:
.a
可以依赖并使用Framework
静态库,但编译后的.a
静态库中不会包含Framework
静态库, 也就是编译期间不会链接Framework
静态库中的内容到.a
中
最终的项目中集成了.a
库后, 还需要导入被依赖的Framework
静态库有点类似于三方库的使用场景, 在使用时要求我们导入那些依赖库(苹果自己的动态库除外)
3. .a
嵌套.Framework
动态库
准备阶段:
生成动态库firstDynamicFramework
, 导入firstStaticLib
这个静态库的Target
中
目录结构:
.
├── FirstStaticLibDemo
│ ├── 省略不相关文件...
│ ├── ViewController.h
│ └── ViewController.m
├── firstStaticLib
│ ├── FirstStaticLib.h
│ ├── FirstStaticLib.m
│ └── firstDynamicFramework.framework
│ ├── Headers
│ │ ├── FirstDynamicFrameworkLib.h
│ │ └── firstDynamicFramework-umbrella.h
│ └── firstDynamicFramework
└── firstStaticLib.xcodeproj
├── project.pbxproj
├── project.xcworkspace
└── 省略不相关文件...
编译报错:
Showing Recent Messages
Ld /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Products/Debug-iphonesimulator/FirstStaticLibDemo.app/FirstStaticLibDemo normal (in target 'FirstStaticLibDemo' from project 'firstStaticLib')
cd /Users/shenyj/Desktop/nestification/firstStaticLib
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -target x86_64-apple-ios14.3-simulator -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.3.sdk -L/Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Products/Debug-iphonesimulator -F/Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Products/Debug-iphonesimulator -F/Users/shenyj/Desktop/nestification/firstStaticLib/FirstStaticLibDemo -filelist /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Intermediates.noindex/firstStaticLib.build/Debug-iphonesimulator/FirstStaticLibDemo.build/Objects-normal/x86_64/FirstStaticLibDemo.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Intermediates.noindex/firstStaticLib.build/Debug-iphonesimulator/FirstStaticLibDemo.build/Objects-normal/x86_64/FirstStaticLibDemo_lto.o -Xlinker -export_dynamic -Xlinker -no_deduplicate -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -Xlinker -sectcreate -Xlinker __TEXT -Xlinker __entitlements -Xlinker /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Intermediates.noindex/firstStaticLib.build/Debug-iphonesimulator/FirstStaticLibDemo.build/FirstStaticLibDemo.app-Simulated.xcent -lfirstStaticLib -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Intermediates.noindex/firstStaticLib.build/Debug-iphonesimulator/FirstStaticLibDemo.build/Objects-normal/x86_64/FirstStaticLibDemo_dependency_info.dat -o /Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Products/Debug-iphonesimulator/FirstStaticLibDemo.app/FirstStaticLibDemo
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_FirstDynamicFrameworkLib", referenced from:
objc-class-ref in libfirstStaticLib.a(FirstStaticLib.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
可见FirstStaticLibDemo
这个Target
下Link
的时候找不到.a
依赖的那个firstDynamicFramework
动态库
此时按照.a
嵌套Framework
静态库那样, 在Demo
的Target
中导入Framework
动态库, 编译会通过, 但是运行后仍然会Crash
dyld: Library not loaded: @rpath/firstDynamicFramework.framework/firstDynamicFramework
Referenced from: /Users/shenyj/Library/Developer/CoreSimulator/Devices/B0EBE6CE-9AE5-4449-8371-143BE02D8EDD/data/Containers/Bundle/Application/7125645D-43C1-499D-B479-8281D0F2C015/FirstStaticLibDemo.app/FirstStaticLibDemo
Reason: image not found
dyld: launch, loading dependent libraries
DYLD_SHARED_CACHE_DIR=/Users/shenyj/Library/Developer/CoreSimulator/Caches/dyld/20C69/com.apple.CoreSimulator.SimRuntime.iOS-14-3.18C61
DYLD_ROOT_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot
DYLD_LIBRARY_PATH=/Users/shenyj/Library/Developer/Xcode/DerivedData/firstStaticLib-ggyjdbctoktoasennbwcjushjdsm/Build/Products/Debug-iphonesimulator:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/libBacktraceRecording.dylib:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/Core
结论:
.a
嵌套Framework
动态库,Framework
不会被Link
到.a
中