澳门新葡萄京官网首页 3

澳门新葡萄京官网首页如何将 iOS 项目的编译速度提高 5 倍

前言

贝聊这两天开销的五款App分别是贝聊家长版和贝聊老师版,方今因为在高速迭代开拓新功效,项目范围小幅拉长,单个端业务代码约23万行,私有库约6万行,第三方库代码约15万行,单个客户端的代码行数约60万。今后打包贰遍耗费时间供给11~12分钟。即使还远远不比Instagram的40分钟,不过大家在公测的时候,平时一天要宣布公测版两到一遍。打包时CPU占用基本上是100%的,因为从没特意的
CI
机器,对担任打包的同事(其实便是自己要好)的劳作时间占有相当多,所以近些日子直接在搜寻加速打包速度的方案。

脚下的品种布局

大家的系列利用 CocoaPods
来保管第三方库和私有库的正视性,对大许多品种以来应该是标配了。如今依旧纯
Objective-C 的类型,未有引进 斯威夫特。

调研过的方案

上面列出自己钻探过的一些主流方案以致小编最后未有应用的原因,那几个方案有些的局限性,不过也给了本身无数启迪,思谋进度跟最后方案同样有价值。

cocoapods-packager

cocoapods-packager 能够将轻巧的
pod 打包成 Static
Library,省去重复编写翻译的年月,一定程度上得以增加速度编写翻译时间,可是也会有自个儿的毛病:

  1. 优化不干净,只可以优化第三方和私家 Pod
    的编写翻译速度,对于其余改造频仍的事体代码心有余而力不足
  2. 私有库和第三方库的世袭更新很劳累,当有源码改正后,需求再行打包上传到内部的
    Git 饭馆
  3. 过多的二进制文件会拖慢 Git 的操作速度(最近还未有布署 Git 的 LFS)
  4. 麻烦调节和测量检验源码

Carthage

那些方案跟 cocoapods-packager 比较像样,优劣势都差不离,但 Carthage
能够相比较实惠地调节和测量试验源码。因为大家脚下一度广泛利用 CocoaPods,转用
Carthage 来做包管理供给做多量的转换工作,所以不考虑那个方案了。

Buck

Buck 是一套通用的构建系统,由
Instagram开源。最大的性状是智能的增量编写翻译能够不小地升高创设速度。最先听别人讲 巴克的时候,它还只好用在安卓上,今后曾经适配了 iOS。

它能增快创设速度的关键原因是缓存了编写翻译结果,通过不断监视项目目录的文件变化,每一回编写翻译时只编写翻译有变动的文书。其它多个让自己异常受启迪的成效是
HTTP Cache
Server,通过一台缓存文件服务器来保存大家的编译结果,那样只要协会里内部一个人编写翻译过的文书,其余人就无须再编译了,直接下载就能够。

Buck 是个特别齐备的应用方案,超级多外国的大商店例如 Uber
都早已用上。作者也花了好多时日来琢磨,最后照旧感到对我们的类型和团协会来说,前段时间并非很相符,重要缘由是:

  1. 巴克 抛弃了 Xcode
    的品类文件,需求手工业编写制定配置文件来内定编写翻译准绳,那要对现成项目作出小幅的调度。我们当下还在全速迭代新成效,没有空闲和人口来推行。
  2. 开采和调和的流程都得做出比十分的大的更动。因为 巴克接管了花色编译的经过,想调节和测量试验项目不可能差不离地在 Xcode 里面 ?+奔驰CLK级了,得先反过来让 Buck 生成 Xcode 的花色文件。Uber
    的技术员甚至推荐使用 Nuclide 来取代 Xcode
    作为支出条件。即便原理上是卓有成效的,不过团队须求花好些个年华来适应,长期内功用下跌无可防止。
  3. 用 Xcode 调节和测验代码享受不到加快编写翻译速度的益处。尽管能够用 buck
    命令运行 App,然后在指令行里运维 lldb 来调解,但那就不能使用 Xcode
    的调护治疗工具 比方 View Debugging 和 Memory Graph Debugger。

Bazel

Bazel 跟 巴克 很平常,是 Google 开源的,优短处跟
巴克 都大约,不再详细说了。

distcc 分布式编写翻译

规律是把部分亟待编译的文件发送到服务器上,服务器编写翻译完结后把编写翻译产品传回到。我尝试了眨眼间间相比闻明的
distcc,搭建进程比较轻便,最后也能打响地把编写翻译职分分派到内网的多台服务器上。可是任何编写翻译服务器的
CPU 占用总是比非常的低,独有 十分六左右;也正是说分派职责的进程依旧还赶不上服务器编写翻译的速度,分派义务然后回传编写翻译付加物这一个进度所消耗的光阴超越了本地一贯编写翻译。不停调节参数一再试验了无数次,最终开采编写翻译时间完全未有变快,以致还应该有个别变慢了。大概以大家近来项指标范围并不切合利用遍及式编写翻译。

谈起底方案:CCache

先来看看自个儿对于解决方案的央求:

  1. 能大幅度地晋级编写翻译速度,起码要裁减掉 五成 的编译时间
  2. 不供给对品种作出重大调度
  3. 无需转移开荒工具链

CCache 是贰个能够把编写翻译的中档产品缓存起来的工具,在别的领域已经有数不完用到,只是在
iOS
界的试行少之甚少。经过自家的执行,它能够满意自己眼下的三点要求。作者最先意识到它是搜到了那篇小说:Using
ccache for Fun and Profit | Inside
PSPDFKit

若果您不使用 CocoaPods,参照上边的小说就可以。因为针对 CocoaPods
供给作出一些附加的调动,所以依旧印证一下。上边就来讲说要怎样把 CCache
应用在用 CocoaPods 作为包管理工科具的 iOS 项目中。

安装步骤:

留意:项目路径不可能有普通话,不然会耳闻则诵 CCache 的例行职业

安装 CCache

首先你须求在计算机上设置 Homebrew,对接受 macOS 的程序员来讲应该是标配,略过。

透过 Homebrew 安装 CCache, 在指令行中施行

$ brew install ccache

一声令下跑完后即安装成功。

创建 CCache 编写翻译脚本

为了能让 CCache 加入到全数编写翻译的经过,大家要把 CCache 作为项目标 C
编译器,当 CCache 找不到编写翻译缓存时,它会再把编写翻译指令传递给真正的编写翻译器
clang。

新建二个文书命名字为ccache-clang, 内容为上边这段脚本,放到你的品类里

ccache-clang

#!/bin/sh
if type -p ccache >/dev/null 2>&1; then
export CCACHE_MAXSIZE=10G
export CCACHE_CPP2=true
export CCACHE_HARDLINK=true
export CCACHE_SLOPPINESS=file_macro,time_macros,include_file_mtime,include_file_ctime,file_stat_matches
# 指定日志文件路径到桌面,等下排查集成问题有用,集成成功后删除,否则很占磁盘空间
export CCACHE_LOGFILE='~/Desktop/CCache.log'
exec ccache /usr/bin/clang "$@"
else
exec clang "$@"
fi

在指令行中,cd 到 ccache-clang 文件的目录,把它的权力改成可施行文件

$ chmod 777 ccache-clang

比方你的代码也许是第三方库的代码应用了C++,则把ccache-clang那几个文件复制一份,重命名成ccache-clang++。相应的对clang的调用也要改成clang++,否则CCache 不会选拔在 C++ 的代码上。

ccache-clang++

#!/bin/sh
if type -p ccache >/dev/null 2>&1; then
export CCACHE_MAXSIZE=10G
export CCACHE_CPP2=true
export CCACHE_HARDLINK=true
export CCACHE_SLOPPINESS=file_macro,time_macros,include_file_mtime,include_file_ctime,file_stat_matches
# 指定日志文件路径到桌面,等下排查集成问题有用,集成成功后删除,否则很占磁盘空间
export CCACHE_LOGFILE='~/Desktop/CCache.log'
exec ccache /usr/bin/clang++ "$@"
else
exec clang++ "$@"
fi

成就后项目中应该有那三个文件

Xcode 项指标调节

定义CC常量

在你项目标创设设置(Build Settings卡塔尔国中,增多一个常量CC,那些值会让 Xcode
在编写翻译时把履行路线的可试行文件当作 C 编写翻译器。

澳门新葡萄京官网首页 1

澳门新葡萄京官网首页 2

CC常量的值为
$(SRCROOT卡塔尔/ccache-clang,假使您的台本不是身处项目根目录,则自动调节路径。若是二十六日转品种就报错,检查下路线是否填错了。

关闭 Clang Modules

因为 CCache 不帮助 Clang Modules,所以需求把 Enable Modules
的选项关掉。那一个主题材料在 CocoaPods 上哪些处理,前面会讲。

澳门新葡萄京官网首页 3

关门了 Enable Modules 后需求作出的调动

因为关闭了 Enable Modules,所以必得删除全部的
@import语句,替换为#import的语法

例如将 @import UIKit 替换为
#import。之后,假令你用到了任何的体系框架举个例子AVFoundation、CoreLocation等,今后 Xcode
不会再帮你活动引入了,你得要在项目 Target 的 Build 粉几内亚湾滩se -> Link
Binary With Libraries 里面本身手动引进。

测量试验效果

尝试编写翻译一回,然后在指令行里输入 cache -s 就能够瞥见相近上边的 ccache
运维情状总结:

cache directory                     /Users/mac/.ccache

primary config                      /Users/mac/.ccache/ccache.conf

secondary config      (readonly)  
 /usr/local/Cellar/ccache/3.3.4_1/etc/ccache.conf

cache hit (direct)                 14378

cache hit (preprocessed)            1029

cache miss                          7875

cache hit rate                     66.18 %

called for link                       61

called for preprocessing              48

compile failed                         2

preprocessor error                     4

can’t use precompiled header          70

unsupported compiler option         2332

no input file                         11

cleanups performed                     0

files in cache                     35495

cache size                           1.3 GB

max cache size                       5.0 GB

假设成功联网,就会瞥见 cache miss
不为0。因为第三回编写翻译没有缓存,确定是全 miss
的。接着编写翻译第壹回,就算能瞥见 cache hit
的数字早前大涨,恭喜你,接入成功了。

CocoaPods 的处理

若是你的门类决不 CocoaPods
来做包管理,那您早已完全接入成功了,不用执行上边包车型大巴操作。

因为 CocoaPods 会单独把第三方库打包成一个 Static Library(恐怕是Dynamic
Framework,就算用了 use_frameworks!选项),所以 CocoaPods 生成的 Static
Library 也亟需把 Enable Modules 选项给关掉。不过因为 CocoaPods 每回试行pod update 的时候都会把 Pods 项目重复生成二遍,借使直接在 Xcode 里面校勘Pods 项目里面包车型大巴 Enable Modules 选项,下一次奉行pod
update的时候又会被改回来。我们要求在 Podfile
里面参与上边包车型大巴代码,让变化的花色关闭 Enable Modules 选项,同期进入 CC
参数,否则 pod 在编写翻译的时候就无法利用 CCache 加快:

post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
#关闭 Enable Modules
config.build_settings['CLANG_ENABLE_MODULES'] = 'NO'
# 在生成的 Pods 项目文件中加入 CC 参数,路径的值根据你自己的项目来修改
config.build_settings['CC'] = '$(PODS_ROOT)/../ccache-clang'
end
end
end

亟需小心的是,若是你使用的某部 Pod
援用了系统框架,举例AFNetworking引用了System
Configuration,你供给在你自身项指标Build 布Leighton俱乐部海滩se -> Link Binary With
Libraries里面代为引进,不然你编写翻译时恐怕会收下 Undefined symbols xxx for
architecture
yyy一类的失实。有一些回到了原始时期的认为,但思忖到编写翻译速度的庞大进步,那或多或少代价能够承担。

购并难点各个审核

最主要关怀日志文件的出口和ccache -s 命令的计算,若是在日记中观望了
unsupported compiler option -fmodules 那样的字眼,便是您的 Enable
Modules
未有关闭了,依照前面包车型大巴步子留意检查。其余主题材料,参照他事他说加以考察官方文书档案的 Troubleshooting。

更是的优化

移除 Precompiled Header File

PCH 的剧情会被增大在各个文件前面,而 CCache 是基于文件内容的 MD4
摘要来研究缓存的,由此当你改改了 PCH 只怕 PCH
引用到的头文件的从头到尾的经过时,会招致任何缓存失效,只好全部重新编写翻译。CCache
在第三遍编写翻译的时候因为急需校正缓存,会造成编写翻译时间变长,对贝聊的品类来讲变长了许多一倍。因而若是PCH 或然 PCH 引入的文本被频仍矫正的话,缓存就能够再三地
miss,这种状态下还不比不用 CCache。

为了防止上述这种场所,小编提议在 PCH
里面尽量少引入头文件,只保留超少校正的系统框架和第三方类库的头文件。最佳是把
PCH 深透删除,反正苹果现在也不建议利用 PCH 了,Xcode
新建的体系暗中认可都以不带 PCH 的。

在团队内部分享缓存文件夹

其一优化措施自己尝试过,最后效果不是很好,由此并未有采取。CCache
的向往大利语档中有一段关于分享缓存文件夹的注明,描述了怎么样改善CCache
的配置,让编写翻译缓存能够在多台计算机之间公用,理论上一旦当中一位编译过的公文其余人就会直接下载到了,节约了百分百团队的光阴。因为
Buck也有肖似的编写制定,笔者认为值得尝试一下,便在同盟社局域网内搭建了一个 OwnCloud 网盘,让我们把自身计算机上的
CCache
缓存目录放上去分享。固然试验是大功告成了,然则实效并倒霉。因为协同在多台计算机上海南大学学小达到多少个G的缓存目录,须求在后台实行过多文件的相比较和传导的做事,在编写翻译的还要拓宽那几个操作会开支不胜枚举寻思财富,反而会拖慢编写翻译速度。加上移除掉
PCH
后,其实缓存的命中率已经非常可观了,不太要求通过分享缓存来进一层升高缓存命中率,所以笔者最终遗弃了分享缓存那么些主见。要是您对缓存命中率依旧不及意的话,能够虚构往那一个趋势尝试一下。

总结

透过集成 CCache,咱们的门类在 Xcode 里面包车型客车卷入(在菜单里面选取 Product
-> Archive)时间从 11~12分钟压缩到了 130
秒,差不离有五倍的晋升,成果喜人。集成的经超过实际际上很简短,作者从伊始尝试到集成成功总共就花了五个钟头。假诺您也被过长的编写翻译时间忧虑,提出尝试一下。

发表评论

电子邮件地址不会被公开。 必填项已用*标注