Xcode创建静态库

2019-07-11  本文已影响0人  少东_SH
前言

随着项目功能的扩展,开发人员增多,代码越来越庞大,导致代码混乱、编译变慢等一系列问题。可以尝试采用静态库的方式,每个人负责的模块独立编译成静态库,最后再引入到项目中去。当然如果写的代码需要保密,不想给其他人看到,或者自己写的工具类不同的项目中都需要用的话,静态库也是不错的办法。

基本概念
  1. 静态库
    存在.a和.framework两种形式。
    .a是一个纯二进制文件,.framework中除了有二进制文件之外还有资源文件。
    简单可以这么说,.a + .h + sourceFile = .framework,所以创建静态库最好还是用.framework的形式。
  2. 动态库
    存在.framework和.tbd两种形式。
  3. 静态库和动态库的区别
    静态库在编译链接时, 会被完整的赋值到可执行文件中;动态库在程序运行时动态加载到内存中, 系统只会加载一次。
  4. 架构
    查看静态库对应的构架: lipo -info Xxx.a
    模拟器架构有i386、x86_64
    真机架构有armv7、armv7s、arm64
创建静态库项目
  1. Xcode -> File -> New -> Project... -> 选择Cocoa Touch Framework


    创建静态库工程.png

    Cocoa Touch Framework编译生成.framework文件。
    Cocoa Touch Static Library编译生成.a文件。

  2. 修改Target的Build Settings
    Build Active Architecture Only改成No


    image.png

    Dead Code stripping改成No
    Link With Standard Libraries改成No
    Mach-O Type改成Static Library


    image.png
  3. 在Build Phases的Headers中公开.h文件


    image.png

    4.编译


    image.png
    编译生成的.framework文件可以用lipo -info xxxSDK.framework/xxxSDK查看支持的架构,可以用lipo -create 命令合并.framework。用lipo命令不是很方便,下面通过添加一个target运行脚本的方式导出静态库。
    5.导出静态库

    选中TARGETS下面的xxxSDK,Editor -> Add Target...


    image.png
    选择Cross-platform,选择Other下面的Aggregate -> Next
    image.png
    选中TARGETS下面新生成的xxxSDKRun,切换到Build Phases面板,点击 + ,点击弹出的New Run Script Phase
    image.png
    在新生成的Run Script的Shell下加入以下运行脚本
    image.png
    运行脚本
#!/bin/sh
#要build的target名
TARGET_NAME=${PROJECT_NAME}
if [[ $1 ]]
then
TARGET_NAME=$1
fi
UNIVERSAL_OUTPUT_FOLDER="${SRCROOT}/${PROJECT_NAME}_Products/"

#创建输出目录,并删除之前的framework文件
mkdir -p "${UNIVERSAL_OUTPUT_FOLDER}"
rm -rf "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework"

#分别编译模拟器和真机的Framework
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

#拷贝framework到univer目录
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework" "${UNIVERSAL_OUTPUT_FOLDER}"

#合并framework,输出最终的framework到build目录
lipo -create -output "${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}"

#删除编译之后生成的无关的配置文件
dir_path="${UNIVERSAL_OUTPUT_FOLDER}/${TARGET_NAME}.framework/"
for file in ls $dir_path
do
if [[ ${file} =~ ".xcconfig" ]]
then
rm -f "${dir_path}/${file}"
fi
done

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

rm -rf "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" "${BUILD_DIR}/${CONFIGURATION}-iphoneos"

#打开合并后的文件夹
open "${UNIVERSAL_OUTPUT_FOLDER}"

Scheme选择xxxSDKRun,Build即可生成最终使用的.framework文件。(一定要先选中xxxSDK,Build成功之后才行)


image.png
后记
  1. 在要使用.framework的项目中拖入.framework文件即可,import .h文件时,需要以#import <xxxSDK/Utils.h>这样的形式导入。
  2. 如果静态库需要引入第三方库,可以使用pod的形式,第三方库不会打包进.framework中,避免重复引用。
    3.如果静态库需要用到图片等资源文件,可以导入bundle。
  3. .h文件比较多的时候,可以把.h文件统一引入到一个.h文件中,在项目中只引入这个.h文件即可。
上一篇下一篇

猜你喜欢

热点阅读