iOS | 静态库(.Framework&.a )制作流程&自动打包脚本

前言

最近公司项目要开发一款SDK使用,研究了一下.Framework.a的制作过程以及自动脚本打包,这里记录一下,关于静态库的概念部分这里不做说明,网上很多文章都有介绍,本文主要介绍静态库的制作过程以及自动打包.

.Framework 打包流程

创建项目

1.新建工程选择iOS —> Cocoa Touch Framework
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第1张图片
image.png
2.进入项目,导入自己需要打包SDK的源代码,别忘记并勾选"Copy item needed"选项
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第2张图片
image.png
3.进入 TARGETS —> Build Phases,设置需要对外暴露的都文件,从Project拖到Public中即可,不需要暴露的放在Project中
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第3张图片
image.png

Xcode相关设置

1.TARGETS —> Build Settings 中设置相关项

设置 Build Active Architecture Only选项为NO, NO选项意思:是当前打包的.framework支持所有的设备.否则打包时只能用当前选择版本的模拟器或真机运行.

iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第4张图片
image.png
2.设置 Mach-O Type 为 StaticLibrary(静态库)
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第5张图片
image.png
3. 设置framework最低支持的版本
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第6张图片
image.png
4. 如果静态库需要支持 armv7s,需要在 Architectures 中手动添加armv7s, 默认打包的真机只有 armv7和 arm64
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第7张图片
image.png

编译Framework 文件

1. 不同编译环境下编译会生成不同的静态库,debug模拟器,debug真机,release模拟器,release真机;

我们这里设置是Release, 选择Edit Scheme--> Buid Configuration设置为release

iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第8张图片
image.png
2. Command+B 编译,编译后我们可以看到 framework 文件由红色变为了黑色,通过 show in Finder 即可查看编译后的文件
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第9张图片
image.png
3. 我们的静态库如果要支持模拟器和真机,就需要在真机和模拟器下各自编译一次,打开文件所在位置,我们发现真机和模拟器的静态库都在这里了.
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第10张图片
image.png

合并文件

1.查看静态库所支持的架构
  • 终端->lipo -info 库, 这里需要查看的 framework 内部的库文件,不是 .framework 本体

    lipo -info /Users/liuchuan/Library/Developer/Xcode/DerivedData/TestSDK-hkydpbtrsnfiegdptvmaviikkiuf/Build/Products/Release-iphoneos/TestSDK.framework/TestSDK 
    
    

输出结果如下图:

iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第11张图片
image.png

上图可以看到当前库只能支持真机运行,如果需要支持真机和模拟器都可以运行,需要将2个库文件进行合并

2.文件合并
  • lipo -create 真机文件 模拟器文件 -output 目标文件
lipo -create /Users/liuchuan/Library/Developer/Xcode/DerivedData/TestSDK-hkydpbtrsnfiegdptvmaviikkiuf/Build/Products/Release-iphonesimulator/TestSDK.framework/TestSDK /Users/liuchuan/Library/Developer/Xcode/DerivedData/TestSDK-hkydpbtrsnfiegdptvmaviikkiuf/Build/Products/Release-iphoneos/TestSDK.framework/TestSDK -output TestSDK

合并后查看:


image.png

此时文件可以支持模拟器和真机了;

最后我们将合并后的文件替换掉原有.framework 中的目标文件即可; 然后拖入需要使用的工程即可;


iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第12张图片
image.png

脚本自动打包

上面我们大致知道怎么通过手动合并来进行打包,实际开发中,如果使用手动打包,每次修改了源代码,需要手动编译真机和模拟器,然后合并,浪费很多时间.接下来我们看下如果使用自动脚本来进行编译合并打包的

建立一个Aggregate target
1. 添加一个target
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第13张图片
image.png
2. 选择Aggregate,并添加工程名字,随便写即可
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第14张图片
image.png
3. 新建运行脚本
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第15张图片
image.png
4. 添加脚本语言
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第16张图片
image.png

具体脚本如下:

#
if [ "${ACTION}" = "build" ]
then

#要build的target名
target_Name=${PROJECT_NAME}

#build之后的文件夹路径
build_DIR=${SRCROOT}/build

#真机build生成的framework文件路径
DEVICE_DIR_Framework=${build_DIR}/Release-iphoneos/${PROJECT_NAME}.framework

#模拟器build生成的framework文件路径
SIMULATOR_DIR_Framework=${build_DIR}/Release-iphonesimulator/${PROJECT_NAME}.framework

#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}

#判断build文件夹是否存在,存在则删除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi

#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi

#创建目标文件夹
mkdir -p "${INSTALL_DIR}"

#build之前clean一下
xcodebuild -target ${target_Name} clean

#真机build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos

#模拟器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator

#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_Framework}" "${INSTALL_DIR}"

#合成模拟器和真机包
lipo -create "${DEVICE_DIR_Framework}/${PROJECT_NAME}" "${SIMULATOR_DIR_Framework}/${PROJECT_NAME}" -output "${INSTALL_DIR}/${PROJECT_NAME}.framework/${PROJECT_NAME}"

#打开目标文件夹
open "${INSTALL_DIR}"

fi

5. 运行脚本自动打包
  • 选中我们刚才创建的TestSDK_Script这个target,然后运行
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第17张图片
image.png
  • 运行完毕会自动在根目录创建合并后的.framework 文件,并且会自动打开文件夹所在位置
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第18张图片
image.png

通过上面的脚本,我们可以很方便的实现一键打包功能了,再也不用挨个编译然后合并了;

报错相关:

使用了打包好的静态库, 在项目打包.IPA文件上传到App Store的, 可能会遇到如下错误 ,存在支持bitcode的问题

image.png

ld: bitcode bundle could not be generated because '/Users/liuchuan/Desktop/medeng/Demo/ZYAuthSDKDemo/ZYAuthSDKDemo/ZYAuthSDK/ZYAuthSDK.framework/ZYAuthSDK(ZYAuthSDK.o)' was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)

解决办法,在我们打包静态库的时候添加以下内容

在target->build Setting-> Add User-Defined Setting 添加选项 BITCODE_GENERATION_MODE -> bitcode

iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第19张图片
image.png

.a 打包流程

.a 静态库打包方式基本和.framework 类似,下来主要对一些不同之处进行说明

创建项目

  • 新建工程选择iOS —> Cocoa Touch Static Library
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第20张图片
image.png
  • 需要公开的头文件放在此处
iOS | 静态库(.Framework&.a )制作流程&自动打包脚本_第21张图片
image.png
  • .a 自动打包脚本
if [ "${ACTION}" = "build" ]
then

#要build的target名
target_Name=${PROJECT_NAME}

#build之后的文件夹路径
build_DIR=${SRCROOT}/build

#真机build生成的头文件的文件夹路径
DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}

#真机build生成的.a文件路径
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a

#模拟器build生成的.a文件路径
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a

#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}

#目标头文件文件夹路径
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers

#目标.a路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a

#判断build文件夹是否存在,存在则删除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi

#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
#创建目标文件夹
mkdir -p "${INSTALL_DIR}"

#build之前clean一下
xcodebuild -target ${target_Name} clean

#模拟器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator

#真机build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos

#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"

#合成模拟器和真机.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

#打开目标文件夹
open "${INSTALL_DIR}"

fi

以上就是 .Framework 和.a 静态库.Framework 的全部制程以及自动打包流程了,如果发现有问题欢迎大家指出!

你可能感兴趣的:(iOS | 静态库(.Framework&.a )制作流程&自动打包脚本)