本頁說明如何使用 Bazel 建構或測試 Xcode 專案。本文說明 Xcode 和 Bazel 的差異,並提供將 Xcode 專案轉換為 Bazel 專案的步驟。並針對常見錯誤提供疑難排解解決方案。
Xcode 和 Bazel 的差異
Bazel 要求您明確指定每個建構目標及其依附元件,以及透過建構規則指定的對應建構設定。
Bazel 要求專案所依附的所有檔案都必須位於工作區目錄中,或在
WORKSPACE
檔案中指定為匯入項目。使用 Bazel 建構 Xcode 專案時,
BUILD
檔案會成為事實來源。如果您在 Xcode 中處理專案,每次更新BUILD
檔案時,都必須使用 Tulsi 產生與BUILD
檔案相符的新版 Xcode 專案。如果您未使用 Xcode,bazel build
和bazel test
指令會提供建構和測試功能,但有某些限制,詳情請參閱本指南後續內容。由於建構設定結構定義 (例如目錄版面配置或建構標記) 的差異,Xcode 可能無法全面瞭解建構作業,因此部分 Xcode 功能可能無法運作。具體來說:
視您在 Tulsi 中選取的轉換目標而定,Xcode 可能無法正確為專案來源建立索引。這會影響 Xcode 中的程式碼自動完成和導覽功能,因為 Xcode 無法查看專案的所有原始碼。
由於 Bazel 不會產生 Xcode 預期用於這些功能的輸出內容,因此靜態分析、位址清除器和執行緒清除器可能無法運作。
如果您使用 Tulsi 產生 Xcode 專案,並使用該專案從 Xcode 內執行測試,Xcode 會執行測試,而不是 Bazel。如要使用 Bazel 執行測試,請手動執行
bazel test
指令。
事前準備
開始之前,請先執行下列操作:
如果尚未安裝,請安裝 Bazel。
如果您不熟悉 Bazel 及其概念,請完成 iOS 應用程式教學課程。您應瞭解 Bazel 工作區,包括
WORKSPACE
和BUILD
檔案,以及目標、建構規則和 Bazel 套件的概念。分析及瞭解專案的依附元件。
分析專案依附元件
與 Xcode 不同,Bazel 要求您在 BUILD
檔案中,明確宣告每個目標的所有依附元件。
如要進一步瞭解外部依附元件,請參閱「處理外部依附元件」。
使用 Bazel 建構或測試 Xcode 專案
如要使用 Bazel 建構或測試 Xcode 專案,請按照下列步驟操作:
-
a. 新增應用程式目標
b. (選用) 新增測試目標
c. 新增程式庫目標
步驟 1:建立 WORKSPACE
檔案
在新目錄中建立 WORKSPACE
檔案。這個目錄會成為 Bazel 工作區根目錄。如果專案未使用任何外部依附元件,這個檔案可以空白。如果專案依附於專案目錄以外的檔案或套件,請在 WORKSPACE
檔案中指定這些外部依附元件。
步驟 2:(實驗功能) 整合 CocoaPods 依附元件
如要將 CocoaPods 依附元件整合至 Bazel 工作區,請按照「轉換 CocoaPods 依附元件」一文的說明,將依附元件轉換為 Bazel 套件。
步驟 3:建立 BUILD
檔案
定義工作區和外部依附元件後,您需要建立 BUILD
檔案,告知 Bazel 專案結構。在 Bazel 工作區的根目錄建立 BUILD
檔案,並設定該檔案,以便對專案進行初始建構,如下所示:
提示:如要進一步瞭解套件和其他 Bazel 概念,請參閱「工作區、套件和目標」。
步驟 3a:新增應用程式目標
新增 macos_application
或 ios_application
規則目標。這個目標會分別建構 macOS 或 iOS 應用程式套件。在目標中,至少要指定下列項目:
bundle_id
- 二進位檔的軟體包 ID (反向 DNS 路徑,後接應用程式名稱)。provisioning_profile
- Apple Developer 帳戶的佈建設定檔 (如要為 iOS 裝置建構)。families
(僅限 iOS) - 是否要為 iPhone、iPad 或兩者建構應用程式。infoplists
- 要合併到最終 Info.plist 檔案的 .plist 檔案清單。minimum_os_version
- 應用程式支援的 macOS 或 iOS 最低版本。這可確保 Bazel 以正確的 API 級別建構應用程式。
步驟 3b:(選用) 新增測試目標
Bazel 的 Apple 建構規則支援在 iOS 和 macOS 上執行以程式庫為基礎的單元測試,以及在 macOS 上執行以應用程式為基礎的測試。如要在 iOS 上執行以應用程式為基礎的測試,或在任一平台上執行 UI 測試,Bazel 會建構測試輸出內容,但測試必須在 Xcode 中透過以 Tulsi 產生的專案執行。請按照下列方式新增測試目標:
macos_unit_test
,在 macOS 上執行以程式庫和應用程式為基礎的單元測試。ios_unit_test
在 iOS 上執行以程式庫為基礎的單元測試。如果測試需要 iOS 模擬器,Bazel 會建構測試輸出內容,但不會執行測試。您必須使用 Tulsi 產生 Xcode 專案,並從 Xcode 內執行測試。ios_ui_test
使用 Xcode 建構在 iOS 模擬器中執行使用者介面測試所需的輸出內容。您必須使用 Tulsi 產生 Xcode 專案,並從 Xcode 內執行測試。Bazel 無法在本機執行 UI 測試。
至少要為 minimum_os_version
屬性指定值。雖然其他封裝屬性 (例如 bundle_identifier
和 infoplists
) 預設為最常用的值,但請確保這些預設值與專案相容,並視需要調整。如要進行需要 iOS 模擬器的測試,請一併指定 ios_application
目標名稱做為 test_host
屬性的值。
步驟 3c:新增媒體庫目標
為每個 Objective C 程式庫新增 objc_library
目標,並為應用程式和/或測試所依附的每個 Swift 程式庫新增 swift_library
目標。
請按照下列步驟新增程式庫目標:
將應用程式程式庫目標新增為應用程式目標的依附元件。
將測試程式庫目標新增為測試目標的依附元件。
在
srcs
屬性中列出實作來源。列出
hdrs
屬性中的標題。
如要進一步瞭解建構規則,請參閱「適用於 Bazel 的 Apple 規則」。
此時建議測試建構作業:
bazel build //:<application_target>
步驟 4:(選用) 細分建構作業
如果專案很大或持續成長,建議將專案分成多個 Bazel 套件。更精細的資料可提供:
建構的增量性提高,
建構工作平行處理的程度提高,
方便日後使用者維護,
進一步控管目標和套件的原始碼可見度。這可避免程式庫含有實作詳細資料等問題,導致資訊洩漏到公開 API。
細分專案的訣竅:
將每個程式庫放入自己的 Bazel 套件。請從依附元件最少的項目開始,逐步處理依附元件樹狀結構中的項目。
新增
BUILD
檔案並指定目標時,請將這些新目標新增至依附於這些目標的目標deps
屬性。glob()
函式不會跨越套件界線,因此隨著套件數量增加,glob()
比對的檔案會減少。將
BUILD
檔案新增至main
目錄時,也請將BUILD
檔案新增至對應的test
目錄。在所有套件中強制執行合理的曝光度限制。
每次對
BUILD
檔案進行重大變更後,請建構專案,並修正遇到的建構錯誤。
步驟 5:執行建構作業
執行完整遷移的建構作業,確保作業完成時不會發生錯誤或警告。 個別執行每個應用程式和測試目標,以便更輕鬆地找出任何錯誤的來源。
例如:
bazel build //:my-target
步驟 6:使用 Tulsi 生成 Xcode 專案
使用 Bazel 建構時,WORKSPACE
和 BUILD
檔案會成為建構作業的真值來源。如要讓 Xcode 瞭解這點,您必須使用 Tulsi 產生與 Bazel 相容的 Xcode 專案。
疑難排解
如果 Bazel 與所選 Xcode 版本不同步 (例如更新時),可能會發生錯誤。如果 Xcode 發生錯誤 (例如「Xcode version must be specified to use an Apple CROSSTOOL」),請嘗試下列做法。
手動執行 Xcode,並接受所有條款及細則。
使用 Xcode 選取工具指出正確版本、接受授權,並清除 Bazel 的狀態。
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
bazel sync --configure
- 如果這個方法無效,也可以嘗試執行
bazel clean --expunge
。