.a静态库的创建
- 先创建一个XCode工程,选择Static Library。
- 编辑添加静态库代码,示例如下,一个简单的打印:
#import <Foundation/Foundation.h>
@interface PrintStaticLibrary : NSObject
- (void)justPrintSomething;
@end
#import "PrintStaticLibrary.h"
@implementation PrintStaticLibrary
- (void)justPrintSomething {
NSLog(@"im fine, thank you");
}
@end
- 配置
- 注意编译模式选release或者Build Active Architecture Only的debug下改为NO。
- 暴露出去的头文件PrintStaticLibrary.h加到BuildPhases里的CopyFile中。
- 选择any iOS device编译。生成的.a文件在Debug-iphoneos中。同时生成的还有带头文件的include文件夹。架构是armv7和arm64。
注意: 此时生成的静态库只能用于真机,不能用于模拟器。否则会报错:Building for iOS Simulator, but the linked library 'libPrintStaticLibrary.a' was built for iOS
选择任意模拟器编译。生成的.a文件在Debug-iphonesimulator文件夹中,其余相同。架构是i386和x86_64。
如果想使静态库在模拟器和真机都能运行,需要同时支持上述两种架构。使用终端命令来实现:
lipo -create 第一个.a文件的绝对路径 第二个.a文件的绝对路径 -output 最终的.a文件路径
lipo -create /Users/chip/Library/Developer/Xcode/DerivedData/PrintStaticLibrary-erujkeckpqgegjebxxohdkqhxdar/Build/Products/Debug-iphoneos/libPrintStaticLibrary.a /Users/chip/Library/Developer/Xcode/DerivedData/PrintStaticLibrary-erujkeckpqgegjebxxohdkqhxdar/Build/Products/Debug-iphonesimulator/libPrintStaticLibrary.a -output test.a
注意如果报这个错误:have the same architectures (arm64) and can't be in the same fat output file
是因为xcode12开始,模拟器也默认包括arm64,造成了重复,导致命令失败。因此要在target的设置中,将Excluded Architectures中的模拟器里添加arm64,表示模拟器打包不包含arm64架构。
新生成的test.a就是可以同时支持模拟器和真机的目标静态库。
注意,静态库不能单独使用。因此要新建一个文件夹,将.a文件和含有头文件的include文件同时放入,再导入到demo里集成即可。
- 使用
直接#import "PrintStaticLibrary.h",调用:
PrintStaticLibrary *lib = [[PrintStaticLibrary alloc] init];
[lib justPrintSomething];
即可在控制台中看到:
2021-08-03 20:01:02.471544+0800 StaticLibraryDemo[88793:7657667] im fine, thank you
.framework的创建
- 先创建一个XCode工程,选择Framework。
- 编辑添加静态库代码,一个简单的打印。
- 将想暴露的头文件.h在自动生成的类中
import
,并且在buildPhase
->header
中设置为public
。 - 配置。配置同上。
- 默认的framework为动态库,需要手动改为静态库。
buildSetting
->Mach-o Type
中由Dynamic Library
修改为Static Library
。 - 编译同上。如果想同时支持,模拟器和真机都要分别编译一次。然后合并。
合并的命令与上面不同的是:framework静态库合并的不是framework,而是framework下的二进制文件,命令为:
lipo -create 第一个framework下二进制文件的绝对路径 第二个framework下二进制文件的绝对路径 -output 最终的二进制文件路径
然后将任何一个framework中的二进制文件替换成合并后的二进制文件,然后把framework添加到要使用的项目中即可使用。
注意:1. 使用output最终生成的二进制文件名要与framework中的二进制文件名完全一致。2. 制作framework的工程支持最低的iOS版本并不影响集成framework后的demo在真机和模拟器上运行。3.如果静态库中有category类,则在使用静态库的项目配置中Other Linker Flags需要添加参数-ObjC或者-all_load。4.如果创建的framework类中使用了.tbd,则需要在实际项目中导入.tbd动态库。
使用worksapce编译
- 将整个PrintStaticLibrary文件夹复制到想要集成的工程中。
- 将PrintStaticLibrary .project文件,拖入Sample.project工程中。
- sample引用PrintStaticLibrary.framework
- 注意设置PrintStaticLibrary中的frameworksearchpath: $(inherited)。
苹果不推荐framework包含另一个framework。正常的方式是同时引用。
UmbrellaFramework可以实现。具体待学习。
最后
生成的MyFramework.h中
//! Project version number for MyFramework.
FOUNDATION_EXPORT double MyFrameworkVersionNumber;
//! Project version string for MyFramework.
FOUNDATION_EXPORT const unsigned char MyFrameworkVersionString[];
对应
image.png
网友评论