随着越来越多的业务量,以及添加的各种第三方库,礼物说这个项目的编译时间也飙升到了五分钟以上。虽说和微博、美团、滴滴他们的三十分钟不是一个数量级,但每天好几个五分钟也会浪费不少人参。于是,加速编译就会被拉上日程。
项目组件化后用 Pod 管理,然后 Pod 里面维护的不是源代码,而是静态链接库。这样最终编译的时候,只需要进行部分编译加链接签名,完成打包。
据说,美团使用这项技术之后,编译时间从原来优化到二百秒。然而,具体实现过程没有任何教程和文档。完全要投石问路。
这件事肯定要有 CI,也就是持续集成。但抛开这件事不谈,我们可以先把问题简化成,一个能正常使用的Pod,执行一个 WorkFlow,即可生成一个预编译好的 Pod。
于是就对这件事进行子任务拆分,可以得到这么个流程:
听起来很简单,事实上各种坑。
问题来了,如何才能创建呢。Google 了一下,没有什么解决方案。看起来只有 AppleScript 可以,真的要学一下 AppleScript 么?
我们来换个思路想这个问题,创建工程的目的是什么,是为了给 Pod 一个编译环境。那么只要是个空的静态项目就行了啊,没必要每次都创建。
于是我们可以创建一个模板工程,丢到 Git 或者 七牛上去。
这里需要注意一个问题,工程里面一定要有个类,否则他不会编译的。
这个直接 echo 一下就好了,对于想要修改的 Pod 应该算是直接按照这个模板 echo 一下就好了
target 'Template' # 可替换内容end
而可替换内容,应该是脚本的传入参数。例如 AFNetworking ~> 2.4
这里我们选择用 xcodebuild 来打包,为了省掉配置 fastlane 的过程,但这里需要注意个问题。我们目标是生成静态链接库,所以我们要保证 i386
、x86_64
、armv7
、arm64
四个平台都要有。然而这是没法一次性编译出来的。
xcodebuild -workspace Template.xcworkspace \
-scheme Template \
-configuration Release \
build \
CONFIGURATION_BUILD_DIR=~/Desktop/workspace/Template/build
注意 CONFIGURATION_BUILD_DIR
需要绝对路径,相对路径会报找不到文件的错误。
xcodebuild -workspace Template.xcworkspace \
-scheme Template \
-configuration Release \
clean build \
CONFIGURATION_BUILD_DIR=~/Desktop/workspace/Template/build \
ARCHS='i386 x86_64' \
VALID_ARCHS='i386 x86_64'\
-sdk iphonesimulator
相对于 arm 平台,这个版本多了 clean
, ARCHS
, VALID_ARCHS
, -sdk
这几个参数来保证编译顺利通过。
lipo -create libSignatureLibary_armv7.a libSignatureLibary_i368.a -output libSignatureLibary.a
想解析原 PodSpec,我们就要找到它在哪。 Pod 提供了一个方法
pod spec which AFNetworking --show-all
可以打印本地所有版本的 AFN 的 Spec。毕竟 ~> 以及 platform 多种因素导致,我们不知道确切安装的版本。
然后配合 Podfile.lock
文件,就能找到我们想要的那个 spec 了。
然而 SPEC 有两种写法: ruby
/ json
,解析起来蛮蛋疼的,我们可以通过 Pod 的工具转换成 json。
pod ipc spec xxx.podspec > xxx.podespec.json
终于可以解析了。
解析主要是把原来的 source_files
字段,改成 *.h。
以及添加 vendored_library
字段。这一块坑还是蛮多的,我们也还在持续踩着。比如 dependencies
、subspecs
有各种复杂的情况,只能发现的时候再处理了。
生成了一坨东西之后,怎么管理就成了问题。我难道用一个第三方库就要给他创建一个 git 么?通过阅读文档,发现 Podfile 有这么一种写法:
pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
于是我把我上一步修改的 spec 填入后面就可以了。如果想要源代码就在 :podspec
前面加一个 #
注释掉。
然后再说内容托管在哪。 Spec 支持多种方式:
其中的 http 可以做到往里面关联一个 zip,例如友盟的 Pod 就是这么做的。
我们把之前生成的 .a 和代码中的 .h 打成包,丢到万能的免费云七牛上就可以了。
这篇文章来源于昨晚骑车回家时的一点灵感,晚上实现了一下。今天又和同事讨论细化了一下做出来的。可能很多地方做的不够细致,欢迎大家指正。若有更好的方案,也欢迎大家告诉给我。