拋棄Xcode依賴管理鳖谈,單倉多組件下編譯加速(小作坊向)

前言

本方案適合于單倉庫(Monorepo)方式管理的項目秩命,通過二進(jìn)制化的想法減少編譯工作量军俊,并通過拋棄Xcode的自帶的依賴管理機制侥加,建立自定義的依賴管理去實現(xiàn)開發(fā)時的編譯加速。本方案可做到對原項目無侵入性粪躬,兼容兩套依賴管理機制担败,既可用Xcode進(jìn)行依賴管理昔穴,也可以使用自定義的方式進(jìn)行依賴管理,任何項目均可放心使用提前。
(本方案基于項目已經(jīng)組件化吗货,未組件化項目可先進(jìn)行組件化再實施,整體改造難點在于依賴管理改造)
項目改進(jìn)后岖研,會有飛一半的質(zhì)感卿操,讓大項目的編譯速度回歸到小項目一樣。


image.png

如圖孙援,修改了組件A害淤、組件C情況下,原Xcode依賴管理方案進(jìn)行管理時拓售,執(zhí)行build clean后會重新編譯所有代碼編譯窥摄。依賴管理改進(jìn)方案只需要執(zhí)行編譯主工程、組件A础淤、組件C崭放,即完成編譯工作,大大縮短了編譯時間鸽凶。

對Xcode熟悉以及對自身項目熟悉的開發(fā)者兩天內(nèi)可以完成改造币砂,最長不超過一周時間,可以說成本很低玻侥,而且不影響原有項目的構(gòu)建方式决摧。

思路與原理

  1. 二進(jìn)制組件化與多倉庫管理陷阱
    通過對組件預(yù)先編譯得到二進(jìn)制文件,那么在開發(fā)時主工程只需要執(zhí)行鏈接的過程就可以完成構(gòu)建工作凑兰。


    圖1
圖2

如圖2所示掌桩,通過將主工程拆分為組件后,通過對組件預(yù)先編譯得到二進(jìn)制文件姑食,主工程構(gòu)建時只需要對組件進(jìn)行鏈接則可完成構(gòu)建波岛,時間可以大大縮短。理論上音半,主工程拆分出來越多则拷,構(gòu)建時編譯時間就會越少。
通過以上的思路曹鸠,很容易就會走向多倉庫項目管理煌茬,Cocoapods一上,項目管理得整整齊齊物延。
但是,項目的組件依賴往往不如圖2那么簡單仅父。如圖3叛薯,組件D依賴組件A和B浑吟,修改組件A需要重新編譯和發(fā)布組件A和組件D。(現(xiàn)實狀況會比圖3復(fù)雜的多得多)


圖3

雖然通過二進(jìn)制化組件可以減少編譯時間耗溜,但是一旦使用多倉管理這種重型項目管理方式组力,會使團(tuán)隊陷入了無止境的編譯發(fā)布流程,光是Debug的工作就是噩夢般的存在抖拴。小項目燎字,小團(tuán)隊使用多倉管理,等于把自己推向深淵阿宅。

  1. 單倉多組件全量編譯工作量過大
    單倉多組件沒有組件發(fā)布流程候衍,debug時也像無組件工程一樣來去自如。這種組件化方式卻無法縮短編譯時間洒放,只得到了分層的好處蛉鹿。
    當(dāng)然,還可以做成單多倉結(jié)合往湿,業(yè)務(wù)組件修改頻繁妖异,放在主倉庫,底層穩(wěn)定組件封裝领追,放在分倉庫他膳。這種方式能解決部分問題,但是編譯時間還是冗長绒窑,畢竟業(yè)務(wù)組件基本都是大頭棕孙。
    如圖4,當(dāng)組件A修改后回论,理論上只需要重新編譯A散罕、D和主工程,但是實際操作上傀蓉,一個Clean動作就把組件B欧漱、C的編譯產(chǎn)物也清理了。也就是說葬燎,在單倉情況下误甚,全量編譯的情況是非常普遍的。


    圖4
  2. 單倉多組件二進(jìn)制化
    所以谱净,是否存在一種方案窑邦,在單倉多組件的項目管理方式下,解決如圖4出現(xiàn)的壕探,對組件B和組件C的冗余編譯工作冈钦?
    毫無疑問,理論上李请,這肯定是存在瞧筛,因為構(gòu)建的工作就是這樣執(zhí)行的厉熟。圖4的情況下,保留組件B和組件C的編譯產(chǎn)物就可以做到较幌。
    因此揍瑟,我們需要對工程進(jìn)行改進(jìn),把編譯產(chǎn)物二進(jìn)制文件緩存下來乍炉,并使用它們绢片。(其實整體思路有點像增量編譯那套,只是緩存的顆粒大一些)

如圖5岛琼,通過對二進(jìn)制產(chǎn)物緩存起來底循,并在項目中鏈接使用該產(chǎn)物,則可以實現(xiàn)衷恭。雖然看似簡單此叠,但實際上是需要將原來交由Xcode托管的依賴管理機制重新實現(xiàn)一遍。


圖5

4.依賴計算以及編譯順序
如圖5中随珠,修改了組件A灭袁,需要計算出需要重新編譯的組件和順序是:A、D窗看。因此茸歧,若實施方案,則需要先梳理好所有組件的依賴關(guān)系显沈,而不是像原來一樣交個Xcode計算软瞎。確定好需要重新編譯的組件后,安裝依賴關(guān)系對組件按順序重新編譯拉讯。

5.增量編譯兼容
實際工作中涤浇,需要執(zhí)行增量編譯。比如魔慷,上一次編譯中只锭,修改了組件A、D院尔,也編譯了組件A蜻展、D,后續(xù)又修改了D邀摆,則本次只需執(zhí)行編譯組件D纵顾,而不是組件A、D栋盹。而且施逾,組件D執(zhí)行的是增量編譯,秒級的,而不是全量編譯汉额。筆者的方案是通過git diff進(jìn)行hash計算修改沪饺,并使用Xcode的自身的增量編譯。

實踐

·基礎(chǔ)知識
  1. Xcode的依賴管理
    Xcode的依賴管理分為兩種闷愤,第一種是顯式依賴(Dependencies),第二種是隱式依賴(Implicit Dependencies)件余。
  • 顯式依賴(Dependencies)的管理放在了Build Phases下的Dependecis欄讥脐,開發(fā)者可以手動添加依賴,僅限workspace下的target
  • 隱式依賴(Implicit Dependencies)是XCode在構(gòu)建時進(jìn)行計算得出的啼器,具體計算范圍是顯式依賴基礎(chǔ)上旬渠,疊加project下被鏈接的庫(Link Binary With Libraries 以及 手動鏈接的庫)
  1. Scheme、Target
    Scheme是管理各種構(gòu)建等配置的地方端壳,其中有一項是隱式依賴的開關(guān)
    Target是管理構(gòu)建信息的地方告丢,普通項目的target對應(yīng)一個構(gòu)建產(chǎn)物
    Scheme和Target的概念大家可以網(wǎng)上找找,此處不贅敘损谦。
·具體方案

整體構(gòu)建流程:


image.png

Step0. Scheme處理
·為了不影響原構(gòu)建方案岖免,需要額外新建一個主工程的scheme,直接Xcode上new scheme照捡,選擇主工程(todo: 配圖 打碼)
·修改所有project的scheme颅湘,取消所有工程的Find Implicit Dependencies,從而取消Xcode的隱式依賴管理栗精。

Step1. Target處理
·新建一個target闯参,直接對原主工程target duplicate一個,并完善info.plist的指向


image.png

·新建一個target悲立,選擇腳本(本方案通過腳本執(zhí)行組件的依賴管理以及構(gòu)建工作)


image.png

·修改目標(biāo)工程的依賴鹿寨,新增腳本依賴


image.png

Step2. 緩存構(gòu)建產(chǎn)物
·項目中新建文件夾對產(chǎn)物進(jìn)行緩存,修改.gitignore
·主項目和子項目framework的鏈接地址(Link binary with Libraries)全部指向緩存文件夾

·通過腳本完成編譯的組件二進(jìn)制產(chǎn)物放到緩存文件夾(切記使用cp命令薪夕,不要使用mv命令脚草,否則Xcode增量編譯失效)

Step3. 依賴關(guān)系梳理(腳本實現(xiàn))

Step4. 計算出需要編譯的組件(腳本實現(xiàn))
· 緩存文件夾中無的組件需要編譯
· 被修改的組件需要編譯
· 組件中依賴的組件被編譯的需要重新編譯

Step5. 執(zhí)行構(gòu)建(腳本實現(xiàn))

Step6. git diff 文件hash計算
每個git diff的hash值對應(yīng)一個二進(jìn)制文件產(chǎn)物,通過hash值的比對來確定修改是否已經(jīng)編譯過寥殖。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玩讳,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子嚼贡,更是在濱河造成了極大的恐慌熏纯,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粤策,死亡現(xiàn)場離奇詭異樟澜,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門秩贰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霹俺,“玉大人,你說我怎么就攤上這事毒费”螅” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵觅玻,是天一觀的道長想际。 經(jīng)常有香客問我,道長溪厘,這世上最難降的妖魔是什么胡本? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮畸悬,結(jié)果婚禮上侧甫,老公的妹妹穿的比我還像新娘。我一直安慰自己蹋宦,他們只是感情好披粟,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著冷冗,像睡著了一般僻爽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贾惦,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天胸梆,我揣著相機與錄音,去河邊找鬼须板。 笑死碰镜,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的习瑰。 我是一名探鬼主播绪颖,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼甜奄!你這毒婦竟也來了柠横?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤课兄,失蹤者是張志新(化名)和其女友劉穎牍氛,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烟阐,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡搬俊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年紊扬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唉擂。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡餐屎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出玩祟,到底是詐尸還是另有隱情腹缩,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布空扎,位于F島的核電站庆聘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏勺卢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一象对、第九天 我趴在偏房一處隱蔽的房頂上張望黑忱。 院中可真熱鬧,春花似錦勒魔、人聲如沸甫煞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抚吠。三九已至,卻和暖如春抖坪,著一層夾襖步出監(jiān)牢的瞬間须喂,已是汗流浹背滑黔。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留萧朝,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓夏哭,卻偏偏與公主長得像检柬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子竖配,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容