构建包含静态链接库.a文件的framework项目的步骤和注意事项
创建framework项目
-
创建framework项目,此处命名为:testCppframework,这里语言选择使用Objective-C;
-
将Build Settings->Linking->Mach-O Type改成static;
-
选中 Target ,选择 Build Phases - Headers ,可以看出有三个选项,分别是 Public 、Private 、Project ,把需要公开给别人的 .h 文件拖到 Public 中,把不想公开的,即为隐藏的 .h 文件拖到 Project 中。
-
在Build Settings->Linking->Other Linker Flag 中添加
-ObjC
:注意: 1. -ObjC:加了这个参数后,链接器就会把静态库中所有的 Objective-C 类和分类都加载到最后的可执行文件中。 2. -all_load:会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到 ld: duplicate symbol 错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到 -ObjC 失效的情况下使用 -force_load 参数。 3. -force_load:所做的事情跟 -all_load 其实是一样的,但是 -force_load 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。
-
将Build Settings->Build Active Architecture Only下的release设置为NO,否则生成的静态库就只支持当前选择设备的架构。
添加静态链接库
-
在framework项目中新建一个Group,这里以新建cpp为例;
-
添加静态链接库.a文件和头文件
如果静态链接库来自第三方,则直接将头文件和.a文件放入到这个cpp文件夹即可;如果是自己开发的,为了方便后续开发,可以将头文件所在的文件夹和.a文件以链接的方式添加到cpp文件夹中。
-
配置.a文件和头文件
- 在Build Settings->Header Search Paths中添加
${PROJECT_DIR}/cpp/include
; - 在Build Settings->Library Search Paths中添加
${PROJECT_DIR}/cpp/
; - 在Build Phases-> Link Binary With Libraries中添加对.a文件的引用;
- 在Build Settings->Header Search Paths中添加
-
如果.a文件由C++编写,则要将framework项目中的.m文件后缀名改为.mm;
编译framework项目
在Product->Show Build Folder in Finder下可以找到编译后的.framework文件;
这里使用脚本将多个架构的.framework进行合并,参考代码:
rm -r ./build
mkdir build
cp -r {项目编译文件夹}/Build/Products/Debug-iphoneos/testCppframework.framework ./build/testCppframework.framework
lipo -create {项目编译文件夹}/Build/Products/Debug-iphonesimulator/testCppframework.framework/testCppframework {项目编译文件夹}/Build/Products/Debug-iphoneos/testCppframework.framework/testCppframework -output ./build/testCppframework.framework/testCppframework
上述脚本会将x86_64和arm64编译的testCppframework.framework文件合并后放到build文件夹下。
在其他项目中引用此framework项目
- 假设这里有一个现成的项目:testcppObjectiveC,为了方便管理,我在项目里新建一个Group,命名为framework;
- 在上面编译生成的testCppframework.framework文件拖到这个framework Group中;
- 使用Show in Finder 打开framework文件夹,将testCppframework.framework文件复制到framework文件夹下,或创建一个testCppframework.framework的链接到此文件夹下(推荐此方式);
- 在Build Setings->Search Paths->Framework Search Paths中添加
$(PROJECT_DIR)/framework
,否则编译时将提示找不到头文件;
调用framework中的代码
添加#import "testCppframework/testCppframework.h"
后即可正常使用testCppframework.framework中的代码
注意
- 如果包含不支持bitcode的库,则所有的项目都应将Build Setings->Build Options->Enable Bitcode设为NO;
- 在Swift项目中使用包含C/C++的库时,可能会报
Undefined symbols for architecture x86_64: "___gxx_personality_v0", referenced from:...... ld: symbol(s) not found for architecture x86_64
,在项目中Build Phases->Link Binary With Libraries添加libc++.1.tbd即可;
参考文献
- 原文作者:岁寒
- 原文链接:http://www.suihanime.com/post/%E5%8E%9F%E7%94%9F%E5%BC%80%E5%8F%91%E6%8A%80%E6%9C%AF/%E6%9E%84%E5%BB%BA%E5%8C%85%E5%90%AB%E9%9D%99%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93.a%E6%96%87%E4%BB%B6%E7%9A%84framework%E9%A1%B9%E7%9B%AE%E7%9A%84%E6%AD%A5%E9%AA%A4%E5%92%8C%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。