创建framework项目

  1. 创建framework项目,此处命名为:testCppframework,这里语言选择使用Objective-C;

  2. 将Build Settings->Linking->Mach-O Type改成static;

  3. 选中 Target ,选择 Build Phases - Headers ,可以看出有三个选项,分别是 Public 、Private 、Project ,把需要公开给别人的 .h 文件拖到 Public 中,把不想公开的,即为隐藏的 .h 文件拖到 Project 中。

  4. 在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 需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载。
    
  5. 将Build Settings->Build Active Architecture Only下的release设置为NO,否则生成的静态库就只支持当前选择设备的架构。

添加静态链接库

  1. 在framework项目中新建一个Group,这里以新建cpp为例;

  2. 添加静态链接库.a文件和头文件

    如果静态链接库来自第三方,则直接将头文件和.a文件放入到这个cpp文件夹即可;如果是自己开发的,为了方便后续开发,可以将头文件所在的文件夹和.a文件以链接的方式添加到cpp文件夹中。

  3. 配置.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文件的引用;
  4. 如果.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项目

  1. 假设这里有一个现成的项目:testcppObjectiveC,为了方便管理,我在项目里新建一个Group,命名为framework;
  2. 在上面编译生成的testCppframework.framework文件拖到这个framework Group中;
  3. 使用Show in Finder 打开framework文件夹,将testCppframework.framework文件复制到framework文件夹下,或创建一个testCppframework.framework的链接到此文件夹下(推荐此方式);
  4. 在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即可;

参考文献

iOS 打包.framework(包括第三方、图片、xib、plist文件)详细步骤及需要注意的地方