使用Xcode做更快的構建 Building Faster in Xcode

使用Xcode更快地構建

使用新的Xcode 10,在構建項目時,性能和開發者的效率有了很大提升。對於大型項目,此前Xcode構建過程很漫長,這種情況下開發人員可能會分心並抱怨,但蘋果已經做了一些努力來優化構建時間,尤其是Swift語言。一般來說構建時間與項目代碼行數,依賴性以及用於構建的機器配置等等多個因素相關。這次發佈的Xcode 10和Swift編譯器有多種新功能,使Swift的構建比以往更快。

1.瞭解Xcode的Targets和依賴以及構建過程

Xcode構建過程是一系列使用clang,ld,actool,ibtool等本地命令行工具進行的任務集合。它涉及編譯和鏈接源代碼,拷貝資源(如資源,StoryBoards,代碼)使用構建腳本以及其他方式簽名和定製內容。一般來說,Xcode構建過程能夠以正確的順序有效地自動完成這些任務,以便保證構建過程可靠。在Xcode9~10下,如果可能的話,源文件的編譯可以並行進行,這樣鏈接器可以一次執行所有這些任務來準備應用程序的可執行文件。

使用Xcode做更快的構建 Building Faster in Xcode

Xcode構建系統會自動分析目標之間的依賴關係,並確定哪些任務可以並行進行。

使用Xcode做更快的構建 Building Faster in Xcode

使用Xcode做更快的構建 Building Faster in Xcode

Xcode項目由多個目標組成,構建時一個目標可能依賴另一個或多個目標。

Xcode目標需要指定構建的產品,例如我們可能針對主應用程序、單元測試或UI測試有不同的目標。

當一個目標依賴另一個目標來構建,然後它創建依賴性,例如對iOS應用程序進行單元測試時,我們首先需要構建主應用程序,然後我們可以構建單元測試目標來執行單元測試。

在Xcode構建階段中,我們可以使用目標依賴關係明確指定目標依賴關係,並隱式使用鏈接二進制庫。

另外瞭解增量構建(Incremental Builds)的概念也很重要:如果我們不改變它,我們就不需要構建所有的東西。

通過觀看這段 WWDC Session 408,我們會更多地瞭解Xcode背後的構建過程。為了加快構建過程,我們應該瞭解並嘗試修改構建系統,通過識別和優化應用程序中的依賴關係來更快地完成工作。這就是為什麼瞭解Xcode構建過程在底層如何工作很重要。

2.瞭解並行構建

如上面所述,Xcode構建系統會自動分析目標之間的依賴關係,並確定哪些任務可以並行進行。

一般來說構建的時間如下面所示。

使用Xcode做更快的構建 Building Faster in Xcode

最簡單時順序構建目標需要時間,但沒有完全利用多核系統資源。如果可能的話,構建目標將會非常慢。使用Xcode 10,我們可以並行化構建並分析項目模塊間的依賴關係,從而顯著減少構建時間。我們可以通過編輯Xcode Scheme並在方案的構建操作中檢查並行構建來啟用並行構建。參見如下選項

使用Xcode做更快的構建 Building Faster in Xcode

使用Xcode做更快的構建 Building Faster in Xcode

在項目設置中確保選擇了Parallelize Build和Find Implicit Dependencies,以確保我們獲得最佳的Xcode性能。如果可能,並行化構建將確保構建並行運行,並且Find Implicit依賴性將檢查項目內的所有依賴項,通常在“Link Binary with Library”構建階段。 Xcode 10還引入了“並行化目標構建過程”的特性,這意味著依賴目標可以儘快開始編譯而不必等待第一個完成,但它必須等到第一個目標的“運行腳本”階段!

使用Xcode做更快的構建 Building Faster in Xcode

3.使用新的構建系統

Apple在Xcode 9中推出了新的構建系統,但它並未默認啟用。但在使用Xcode 10時,默認情況下,新的版本設置已被啟用,並從Xcode文件->項目/工作區設置修改

使用Xcode做更快的構建 Building Faster in Xcode

如果我們使用xcodebuild從命令行構建iOS項目,那麼我們必須傳遞額外的參數-UseNewBuildSystem = YES這樣也會使用新的構建系統。新的構建系統稱為xcbuild。

Apple的xcbuild的二進制文件位於路徑下:

/Applications/Xcode.app/Contents/SharedFrameworks/XCBuild.framework/Versions/A/Support/xcbuild

4.改進運行腳本階段

在Xcode中,構建階段中,我們可以添加自定義運行腳本,以根據我們自己的項目需求構建過程。

使用Xcode做更快的構建 Building Faster in Xcode

我們已經指定了輸入文件到運行腳本階段,這對於構建系統來決定是否需要運行腳本來執行依賴目標構建是非常重要的。在適用的地方將輸入文件提供給運行腳本始終是個好主意。當Xcode 10中的輸入文件的數量增長時,給我們指定.xcfilelist格式的所有輸入文件的方式,並且我們可以在構建階段將此文件添加為文件列表輸入。

當沒有輸入文件,更改輸入文件或缺少輸出文件時,Xcode構建系統將始終運行此構建階段。添加這些文件非常重要,以避免在不需要時為所有增量構建運行此階段。在運行腳本階段的Xcode幫助中也有文檔

我們可以在幫助文檔中查閱關於“運行腳本”階段的更多信息。

5.解決循環依賴

Xcode 10,新的構建系統為我們分析了循環依賴,一旦項目裡面有循環依賴的問題,我們需要處理並解決掉依賴的情況

使用Xcode做更快的構建 Building Faster in Xcode

Xcode 10,裡面的幫助系統也為我們解決處理循環依賴的情況提供了幾點思路

使用Xcode做更快的構建 Building Faster in Xcode

使用Xcode做更快的構建 Building Faster in Xcode

通過錯誤提示與選項設置,我們可以快速地找到依賴中的問題並處理解決。

6.分析構建時間

使用Xcode 10,我們可以使用計時摘要來分析構建過程,從而幫助我們確定構建所花費的時間,並採取改進措施來發現問題縮短構建時間。

這個新功能將顯示構建系統執行的每個任務的時間安排,並且可以在Xcode產品 ->執行操作 - >與時序彙總構建選項中找到。

使用Xcode做更快的構建 Building Faster in Xcode

在這個條件下,我們構建所產生的輸出如下面所示:

使用Xcode做更快的構建 Building Faster in Xcode

使用Xcode做更快的構建 Building Faster in Xcode

此功能也可以使用xcodebuild工具使用命令行啟用:

$ xcodebuild -showBuildTimingSummary

使用Xcode做更快的構建 Building Faster in Xcode

這將在日誌中打印構建摘要時間。

這樣我們可以看到每一步構建花費的時間。

通過使用這種技術,我們可以分析出為了使構建更快而需要完成的工作。

7.編譯模式與優化級別

在新的Xcode裡面,Apple分離了編譯設置“編譯模式”和“優化級別”,以便我們可以控制調試版本的編譯機制。

編譯模式是我們的項目如何構建的模式,我們可以設置我們是否需要優化速度或在調試模式下構建。在調試構建的情況下,整個優化並不總是需要的,這樣我們可以將此選項設置為調試的增量構建。

在Xcode 10中,默認編譯模式設置為“增量構建”。

使用Xcode做更快的構建 Building Faster in Xcode

當整個模塊停止執行增量構建並在構建過程中構建所有文件時,這將大大加快構建速度。對於調試版本,“優化級別”版本設置可以設置為“不優化”,對於版本版本,可以設置為“優化速度”。我們可以看到在Xcode 10中引入了一個新的選項,即“優化大小”,可用於檢查代碼大小。這是通過編譯應用程序生成的機器代碼,而不是應用程序或資產的大小。

使用Xcode做更快的構建 Building Faster in Xcode

我們可以看到Xcode 10默認啟用了正確的選項。如果不使用這些選項,那麼應該立即更改這些選項以從新的Xcode功能中受益。

源碼級別的改進要點

(1)在Debug Builds設置選項為Incremental

(2)分解處理複雜的表達式

(3)針對複雜的屬性,使用使用準確的類型

使用Xcode做更快的構建 Building Faster in Xcode

(4)在閉包裡面提供準確的類型

使用Xcode做更快的構建 Building Faster in Xcode

這些都會提高編譯器的處理速度

8.合理地管理依賴關係

每個應用程序都有內部或外部的依賴關係,依賴可能會減慢構建過程。合理地管理依賴關係是一個很好的做法,在項目中檢查依賴關係並正確分類,以幫助Xcode構建系統以更好地執行。依賴關係來自Xcode項目中的各個位置,它們可能是內置的比如頭文件,目標依賴項或隱式依賴關係,在鏈接二進制庫,構建階段依賴項或方案順序依賴項中。我們必須以更好的速度妥善管理它們

選擇正確的依賴管理解決方案。

添加隱式依賴而不是顯式依賴

管理項目和工作區,以便輕鬆訪問所有代碼

確定將依賴源代碼放入存儲庫或動態下載的策略。

使用依賴管理的緩存策略來加速構建

在構建時,針對依賴關係,我們有下列可以優化的要點

增量式構建都是基於文件的

源文件函數功能的簡單改變在構建時不會影響其它文件重新構建

源文件裡面函數體外的改變,會影響導致相關文件的重新編譯

另外編譯器的處理過程都是比較保守的

函數體中的改變不影響文件整體的接口

module內的依賴是基於文件的

targets間的依賴是基於整個target的

9.編譯優化

在編譯優化加速方面,蘋果提到了開發者最好需要限制源文件的接口,具體有下面幾點:

(1)保持生成的頭文件最小化

(2)在Swift中,使用private嘗試減少接口對外暴露

使用Xcode做更快的構建 Building Faster in Xcode

(3)使用基於block的API

(4)使用category減少接口,這樣減少了依賴關係,提高編譯速度

(5)保持橋接的頭文件最小化

使用Xcode做更快的構建 Building Faster in Xcode

總結

通過session 408,我們瞭解到Xcode 10為我們針對構建提供很多輔助功能;這些功能可以幫我們發現問題並解決問題,提高改進構建效率。

我們需要在後續開發中盡力使用相關功能,提高我們的開發效率。


分享到:


相關文章: