- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章iOS编译速度如何稳定提高10倍以上之一由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、概述 。
经过多年的发展,美柚iOS项目代码已经达到40W行+的规模,所使用的 Pod 库的数量达到了110+,App Store 安装包210M+,在这么大的项目规模下(CI机器 MAC配置:3 GHz 8-Core Intel Xeon E5;时间:发布20min+),(开发机器iMac :Retina 5K, 27-inch, 2017 融合硬盘;时间:build30min+)打包、编译问题逐步成为我们团队一个躲不过的痛,严重影响了我们的研发效率与其他团队之间的协作.
我们一台13年的ci机器同时需要承接七八个项目、多个分支的打包任务,在有多个项目同时打包的情况,显得尤其地力不从心.
在硬件资源有限的情况下,并且在无侵入、无影响现有的业务的前提下,如何解决这些摆在团队面前的难题,便成了我们迫在眉睫的迫切需求,最近半年多来一直在寻找加快打包速度的方案.
2、编译提速探索与尝试 。
1、CCache 。
CCache 是一个编译缓存器,一个能够把编译的中间产物缓存起来的工具 。
其原理是通过把项目的源文件用ccache编译器编译,然后缓存编译生成的信息,从而在下一次编译时,利用这个缓存加快编译的速度,目前支持的语言有:C、C++、Objective-C、Objective-C++ 。
下面这张图基本就阐述了CCache的工作原理.
在项目中的实际编译流程 。
Ccache我们经过在工程的一番尝试、确实在某些方面上极大的提升了我们出包的速度。美柚iOS Ci打包从之前的最快20min+出包到最快10min,确实能够给我们带来比较不错的提升,大大加快了我们项目的出包速度。在我们项目运行了几个月后,对于我们项目的情况,也发现了一些问题,现在总结了以下几点:
优点:
对我们项目中有存在些问题点:
2、静态库二进制方案的探索 。
虽然我们已经在Ci的在应用了Ccache已经有提升近一倍的出包速度了,但是存在的问题也比较明显.
在去年的某次技术周会上,我们的大佬提出了使用二进制编译的自研任务,可以更进一步提高研发效率。得到了大佬的启发后,就一直在实践与探索二进制之路上.
我们的项目使用 CocoaPods 来管理第三方库和私有库的依赖,对大部分项目来说应该是标配了。目前还是纯 Objective-C 的项目,有少量C++,暂没有引入 Swift.
3、 调研过的二进制组件方案 。
下面列出研究过的一些主流方案以及最后没有采用的原因,这些方案有各自的局限性,但是也给了我不少启发,思考过程跟最终方案一样有价值.
3.1、Carthage 。
Carthage可以将一部分不常变的库打包成framework,再引如到主工程,这样可以减少开发过程中的编译时间。Carthage 可以比较方便地调试源码。因为我们目前已经大规模使用 CocoaPods,转用 Carthage 来做包管理需要做大量的转换工作,变动太大,不满足我们的无侵入、无影响现有的业务,所以不考虑这个方案了.
3.2、cocoapods-packager 。
cocoapods-packager 可以将任意的 pod 打包成 Static Library,省去重复编译的时间,一定程度上可以加快编译时间,但是也有自身的问题:
3.3、cocoapods-binary 。
Cocoapods-Binary(Cocoapods 官方推荐的二进制插件), 是一个即时生成二进制包并缓存,而非像 CocoaPods-Packager 仅仅针对单个私有库的。原理是通过 CocoaPods 提供的 pre_install hook 在 pod install 的 prepare 阶段拦截到当前的 pod install context,进而 fork 出一份独立的 installer 以完成将预编译源码 clone 至 Pod/_Prebuild 目录下,同时也存在几个不足之处:
3.4、cocoapods-bin 双私有源 。
该插件进行二进制化的策略是采用双私有源,即2个源地址,一个静态服务器保存预先打好包的framework,一个是我们现在保存源码的服务地址,在install的时候去选择使用下载那个,是个很不错的项目,深受启发.
优点:
对于在我们项目中存在的不足之处:
4、 思考与总结 。
经过一个多月来对业界存在的轮子的分析和思考,并在一定的实践后,最后我们决定自己造一个灵活的、可配置的、简便的、无入侵的、双私有源二进制组件辅助插件.
接下来就撸起袖子,努力干吧~,骚年 。
3、双私有源二进制组件简介 。
在受到cocoapod-bin启发后,在借鉴它的部分框架下,我们实现了自己的二进制辅助插件cocoapods-imy-bin,并新增了几个命令和二进制源码调试能力.
1、能做什么?只要能编译通过,就制作 。
在cocoapods-imy-bin的辅助下,能无侵入式自动化地制作所有符合条件的组件为二进制,且对于频繁的业务组件也能轻松的应用上二进制组件,无需多余操作,一切交给cocoapods-imy-bin自动化运行.
同时对于研发人员,也能提供独立的二进制组件给研发人员使用,解决日常的编译 效率、跑真机效率低下,被墙等各种问题.
我们的口号是: 只要能编译通过,就制作。 一次编译到处使用,无入侵.
即使独立的组件库编译不通过,整体项目能编译通过也制作.
整套环境下来,没有让我们的开发人员改变原来的开发习惯,没有改动业务中相关的代码,基本上做到了使用人员无感知状态.
2、Ci打包效果 。
2.1 单项目 - 编译最快2分钟一次 。
上图是个由我们打了几千个包的经验得出对单个项目编译时间大致的曲线图。这里假设一台机器只一次只有一次job。Y轴编译时间,X轴某次的编译, 红色线条表示的是原生(未使用Ccache和二进制组件),黄色线表示使用了Ccache,蓝色表示使用了二进制组件.
由图可以看出来在无任何辅助下原生的编译时间曲线(红色)是趋于平缓,在20min上下左右。Ccache和二进制第一次在无任何缓存的情况下,在一定程度上是会比原生的耗时,Ccache主要耗时在边编译边缓存项目的编译产物。二进制主要耗时在编译完成后,对.a编译产物的组装和push到私有源仓库的时间上(这个跟所采用有关系,如果没有利用Jenkins 编译后的产物制作二进制就不存在。).
在ccache完全命中、二进制文件完全都存在的情况下,ccache比原生的提高一倍以上, 二进制会比ccache编译时间再提高一倍,且稳定在2分钟左右。二进制在之后的表现更趋于平稳,而ccache在修改了某个被引用较多的文件时、如底层的公共文件后,命中率就会大大地降低,有时会比不用ccache更耗时,如#4位置。在ci有多个job同时并发在跑的情况下,由于ccache 需要对IO频繁地读写操作,耗时表现可能会更糟糕些,我们经常遇到过等了七十几分钟才出包的情况.
二进制的编译时间相对平稳很多(蓝色曲线),在我们架构强有力的支撑下,划分出110多个独立组件,每次的打包基本上是就耗在某个组件的编译+archive。如果是某些变更比较频繁的组件,我们还可以考虑对颗粒较大组件配上ccache,做双层编译缓存。双层编译缓存原理是Pods组件库无二进制组件采用源码编译时,源码编译同时应用ccache缓存支持,加速源码组件的编译.
同时组件库可以配合Gitlab-Ci的runner的应用,每次已提交代码就触发独立组件的制作二进制,让每次的编译速度都达到最快,蓝色二进制曲线将会更接近直线。Gitlab-Ci具体的使用教程参见后文.
如果存在有独立组件无法编译问题和版本依赖问题,也可以再跑个定时Job,或者其他轮询条件Job,及时提供最新二进制组件.
2.2、多项目情况 。
一台机器上多个项目的ccache显得是比较吃力的,且不稳定,超出ccache的缓存最大值就会被清掉.
使用了二进制后,即使是多个项目编译时间都是趋于比较平稳的。这里面的原理估计大家都能想得到为什么.
3、开发使用效果 - 10倍以上的提升 。
在Podfile引入插件后,在pod install/update后,符合条件的情况下,会自动转换为二进制组件.
在我们的开发机器(iMac :Retina 5K, 27-inch, 2017 融合硬盘;)上,全量代码之前Build需要30min+,现在使用全部使用二进制后,编译最快只需要2min+就可以,提高的效率达到10倍以上.
当您在使用独立组件库编译开发的时候,其实不妨试试这个二进制的方案去跑整个项目,说不定二进制的方案比独立组件库跑起来还迅速.
3.1.源码编译 。
Ps:110+个Pods库中,有20+个稳定Pods库已经被制作为二进制库,并非全部源码编译,如何全部转换为源码编译,实际数字会比这多出很多.
3.2. 二进制编译 - 全量最快2分钟 。
Ps:有2个Pods和5个Action Extension使用源码编译,其他全部是二进制Pods.
在二进制Build 127秒中(arm64和armv7),除了源码编译的时间外,约45秒消耗在copy pods Resource.
实际在编译模拟器x86_64架构时只需要90秒不到的时间.
全量编译中,13496个Tasks/727个Tasks,1710秒(28.5分钟)/127秒(2分钟),编译速度提升的速度远远超过10倍.
3.3 演示 。
在环境搭建完后,开发人员在Podfile中,加入以下两句,就能享用到自动切换为二进制组件,体验极速编译.
plugin 'cocoapods-imy-bin' 。
use_binaries! 。
4、功能点 。
目前cocoapods-imy-bin插件支持的功能如下 。
原文地址:https://juejin.cn/post/6903407900006449160 。
最后此篇关于iOS编译速度如何稳定提高10倍以上之一的文章就讲到这里了,如果你想了解更多关于iOS编译速度如何稳定提高10倍以上之一的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
是否有任何库或框架旨在促进从另一种成熟的编程语言中构建项目? 在 C++、java 等编程语言中指定逻辑、集合和复杂规则非常容易,但在 Makefile 中完成这些事情似乎是一场艰苦的战斗。我还没有深
我有这段代码可以用 clang 编译得很好(即使使用 -Weverything),但是 gcc 会发出错误。 #include #include #include using namespace
我有以下 block 头文件 BKE_mesh.h: /* Connectivity data */ typedef struct IndexNode { struct IndexNode *
我在我的一个项目中遇到了一个奇怪的问题。我的代码库依赖于一个外部库,其中包含一个名为 Dataset 的类. Dataset类私有(private)继承自 std::vector (其中 Sample
当使用 gcc、g++ 或 make 在终端中编译一个小型 C 或 C++ 项目时,我收到以下错误: /tmp/ccG1caGi.o: In function `main': main.c:(.tex
我正在尝试从 CVS 为 Windows 上的 Emacs 23.1.50 编译 CEDET,但在“第 6 步:打开 EDE...”时出现错误:“defvar:作为变量的符号值是无效的:cedet-m
我正在(重新)学习编程,我从 C 开始。我的 IDE(如果我可以这么说)是 Windows7 上的 cygwin(32 位)和 Visual-Studio 2010。我总是编译我用 gcc (cygw
我喜欢在模板类中使用本地类来执行类似“static if”的构造。但是我遇到了 gcc 4.8 不想编译我的代码的问题。但是 4.7 可以。 这个例子: #include #include #in
我有一个项目,必须仅使用 java 1.4 进行编译。但我计划使用mockito 编写一些单元测试。我想要一种在 pom 中指定的方法,以便 src/main/java 使用 jdk 1.4 编译,但
我想了解 PHP 编译过程是如何工作的。 假设我有一个名为funcs.php 的文件并且这个文件有三个函数,如果我include 或require 它,所有的在文件加载期间编译三个函数?或者源代码会被
编译工具链 我们写程序的时候用的都是集成开发环境 (IDE: Integrated Development Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来
当我编写一些 Scala 代码时,在尝试编译代码时收到一条奇怪的错误消息。我将代码分解为一个更简单的代码(从语义的角度来看这完全没有意义,但仍然显示了错误)。 scala> :paste // Ent
我正在编译一个 SCSS 文件,它似乎删除了我的评论。我可以使用什么命令来保留所有评论? >SASS input.scss output.css 我在 SCSS 中看到两种类型的注释。 // Comm
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
当您编译 grails war 时,我知道 .groovy 代码被编译为字节码类文件,但我不明白容器(例如 tomcat)如何在请求 GSP 时知道如何编译它们。容器了解 GSP 吗?安装在服务器上的
我正在努力将多个文件编译成一个通用程序。我收到一个错误: undefined reference to 'pi' 这是我的代码和 Makefile 的框架。我做错了什么?谢谢! 文件:calcPi.c
我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果: #define _GNU_SOURCE #include #include int
我正在寻找最简单的方法来自动将 CoffeeScript 重新编译为 JS。 阅读documentation但仍然很难得到我想要的东西。 我需要它来监视文件夹 src/ 中的任何 *.coffee 文
我想使用定制waveformjs 。我发现this on SO但是,我不知道如何编译/安装波形来开始。我从 GitHub 克隆它并进行了更改,但是我不知道如何将其转换为 .js 文件。 最佳答案 为了
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我是一名优秀的程序员,十分优秀!