公司級別的項目在發展過程,不可避免會遇到項目過大,致使的編譯和開發效率的下降。在如何提升編譯速度,加快生產效率,各大廠都有各類嘗試,惋惜在業內沒有一個成本低、效果好的開源方案。而做者所在的公司,因爲業務線聚合,原有兩條徹底不一樣的交易線業務以組件的形式合併到主App,加重了編譯的問題。項目的完整編譯時間從原有的5分鐘,直接 double 到25分鐘左右,同時 CI 的打包也不斷的往30分鐘的趨勢奔去。git
CocoaPods-Binar 是針對二進制化的一個總體的實踐,而非像 CocoaPods-Packager 僅僅針對單個私有庫的。所謂的二進制化,簡單說來能夠經過 podSpec 將 source 指向事先打包好的 binary 來提升編譯效率,這個是目前的主流作法。固然也能夠經過更改編譯緩存如 CCache 或者換個編譯器 Buck (FB) / Bazel (Google) 來實現分佈式編譯。微信團隊的這篇 微信編譯速度優化 有進行了比較完整的闡述。而本文的主角 CocoaPods-Binary 是經過將 dependencies 預編譯成 binary 後緩存至本地,而後將原有的 Source Code link 到 binary 以幾乎零成本的方式實現編譯效率的提升。惟一缺點就是沒法實現服務端緩存(這是咱們須要改造的地方,不過這個能夠經過定製化實現),所謂的分佈式的二進制編譯。xcode
最先發現這個 plugin 是在瀏覽官方 blog 時發現的,並且做者仍是國內 developer 。該插件發佈也有兩年多,目前支持到 Pods 版本 1.6.x。咱們先來看看類圖構成:緩存
CocoaPods 自己提供了比較不錯的插件模版,如須要的話能夠看這篇文章。CocoaPods-Binary 的核心代碼都在 lib/cocoapods-binary 文件夾下。咱們來看看整個插件的主要部件,及其對應的做用。ruby
做爲整個插件的執行的入口,經過 CocoaPods 提供的 pre_install hook 在 pod install 的 prepare 階段攔截到當前的 pod install context,進而 fork 出一份獨立的 installer 以完成將預編譯源碼 clone 至 Pod/_Prebuild 目錄下。微信
主要對 Sandbox、Installer、Pod、Podfile Options 相關的類添加各類 attribute 狀態來知足邏輯須要。例如,子類化 Sandbox > PrebuildSandbox 來指定 generate frameworks 的地址、prebuild Pods 的地址,以及是否存在編譯好的 framework 等;對 Podfile DSL 添加 binary、all_bianry 關鍵字來控制 binary 和源碼的切換。markdown
核心類,經過 xcodebuild 將全部 :binary => true 的 dependencies 編譯成 binary 和 dSYM,並輸出到指定目錄。這裏針對 iOS 平臺輸出的 framework 多作了一步處理,當檢測到是 platform 是 iOS 會分別對模擬器和真機設備單獨編譯,最後再利用 libo 將各自的 binary 和 dSYM 合併成一份輸出。分佈式
利用 ruby 語言的動態性,重載 Installer 的 run_plugins_post_install_hooks 以實現 pre_install 結束後觸發 build framework 將 dependencies 打包成二進制包。對於 dependencies 是否須要進行預編譯是經過檢查生成的 framework 中是否存在 xxx_name 文件做爲標識該 lib 是否已經完成編譯過(xxx 爲對應 lib 名稱。oop
在插件源碼同步完預編譯結束後,會將 install context 交還,進入 install 最後階段。在這裏將完成對 binary frameworks 的 symbol link 以替換原有 Pods 源碼和 Embed 操做則會修改各個 pod.xcproject 配置,最後生成 project。post
基本的模塊介紹完,咱們來看看,引入 CocoaPods-Binary 插件後 Pods 的文件構成:優化
_Prebuild 目錄下則完整保存了一份 Pods 源代碼,同時多出來的 GeneratedFrameworks 則緩存了預編譯後的 binary 文件以及 dSYM 符號表。在最後的 integration 階段 symbol link 替換完後源碼則會被刪除同時指向binary。
至此,整個 pod install 就算完成了,那 CocoaPods有哪些限制呢?
無圖無真相,簡單的流程圖但願能幫助各位理解 CocoaPods-Binary 做者的基本思路;