從 Xcode 遷移至 Bazel

回報問題 查看來源

本頁說明如何使用 Bazel 建構或測試 Xcode 專案。本文會說明 Xcode 和 Bazel 之間的差異,並提供將 Xcode 專案轉換成 Bazel 專案的步驟。同時也提供排解常見錯誤的疑難排解解決方案。

Xcode 和 Bazel 的差異

  • Bazel 要求您明確指定每個建構目標及其依附元件,以及透過建構規則對應的建構設定。

  • Bazel 要求專案所需的所有檔案必須存在於工作區目錄中,或是在 WORKSPACE 檔案中指定為匯入項目。

  • 使用 Bazel 建構 Xcode 專案時,BUILD 檔案會成為可靠資料來源。如果您在 Xcode 中處理專案,則必須在每次更新 BUILD 檔案時,使用 rules_xcodeproj 產生符合 BUILD 檔案的新版 Xcode 專案。對 BUILD 檔案進行特定變更 (例如新增依附元件至目標) 不需要重新產生能加快開發速度的專案。如果您不是使用 Xcode,bazel buildbazel test 指令會提供建構和測試功能,但有本指南稍後中所述的特定限制。

事前準備

開始前,請先完成下列步驟:

  1. 如果您尚未安裝 Bazel,請先完成安裝。

  2. 如果您不熟悉 Bazel 及其概念,請參閱 iOS 應用程式教學課程。您應該瞭解 Bazel 工作區,包括 WORKSPACEBUILD 檔案,以及目標、建構規則和 Bazel 套件的概念。

  3. 分析及瞭解專案的依附元件。

分析專案依附元件

與 Xcode 不同的是,Bazel 要求您為 BUILD 檔案中的每個目標明確宣告所有依附元件。

如要進一步瞭解外部依附元件,請參閱「使用外部依附元件」。

使用 Bazel 建構或測試 Xcode 專案

如要使用 Bazel 建構或測試 Xcode 專案,請按照下列步驟操作:

  1. 建立 WORKSPACE 檔案

  2. (實驗功能) 整合 SwiftPM 依附元件

  3. 建立 BUILD 檔案:

    a. 新增應用程式目標

    b. (選用) 新增測試目標

    c. 新增程式庫目標

  4. (選用) 對建構進行精細處理

  5. 執行建構

  6. 使用 Rules_xcodeproj 產生 Xcode 專案

步驟 1:建立 WORKSPACE 檔案

在新目錄中建立 WORKSPACE 檔案。這個目錄會成為 Bazel 工作區根目錄。如果專案沒有使用外部依附元件,這個檔案可以空白。如果專案依附的檔案或套件不在專案的任何目錄中,請在 WORKSPACE 檔案中指定這些外部依附元件。

步驟 2:(實驗功能) 整合 SwiftPM 依附元件

如要使用 swift_bazel 將 SwiftPM 依附元件整合至 Bazel 工作區,您必須按照下列教學課程的說明,將 SwiftPM 依附元件轉換為 Bazel 套件。

步驟 3:建立 BUILD 檔案

定義工作區和外部依附元件後,您必須建立 BUILD 檔案,告知 Bazel 專案結構。在 Bazel 工作區的根目錄建立 BUILD 檔案,並將其設定為執行專案的初始建構,如下所示:

提示:如要進一步瞭解套件和其他 Bazel 概念,請參閱「工作區、套件和目標」一文。

步驟 3a:新增應用程式目標

新增 macos_applicationios_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 建構規則支援在所有 Apple 平台上執行單元和 UI 測試。新增測試目標,如下所示:

請至少指定 minimum_os_version 屬性的值。雖然 bundle_identifierinfoplists 等其他封裝屬性預設為最常使用的值,但請確保這些預設值與專案相容,並視需要進行調整。如果是需要 iOS 模擬器的測試,請一併將 ios_application 目標名稱指定為 test_host 屬性的值。

步驟 3c:新增程式庫目標

為每個 Objective-C 程式庫新增 objc_library 目標,並為應用程式和/或測試依附的每個 Swift 程式庫新增 swift_library 目標。

新增程式庫目標,如下所示:

  • 將應用程式程式庫目標新增為應用程式目標的依附元件。

  • 將測試程式庫目標新增為測試目標的依附元件。

  • srcs 屬性中列出實作來源。

  • hdrs 屬性中列出標頭。

您可以直接在 rules_apple 範例目錄中瀏覽各種應用程式類型的現有範例。例如:

如要進一步瞭解建構規則,請參閱 Bazel 的 Apple 規則

此時,建議您測試版本:

bazel build //:<application_target>

步驟 4:(選用) 劃分建構作業

如果專案較大或隨著規模成長,請考慮將其分割為多個 Bazel 套件。提高精細程度的好處如下:

  • 提高建構成效增幅

  • 增加建構工作的平行處理

  • 提高日後使用者的可維護性

  • 進一步控管目標和套件的原始碼瀏覽權限。這樣可以避免發生問題,例如含有實作詳細資料外洩到公用 API 的程式庫。

更精細的專案規模提示:

  • 將每個程式庫放在專屬的 Bazel 套件中。從需要最少依附元件的項目開始,然後逐步執行依附元件樹狀結構。

  • 當您新增 BUILD 檔案並指定目標時,請將這些新目標新增至依附於目標的 deps 屬性。

  • glob() 函式不會跨套件邊界,因此,隨著 glob() 比對的檔案數量增加,則會縮減。

  • main 目錄中新增 BUILD 檔案時,請一併將 BUILD 檔案新增至對應的 test 目錄。

  • 對各個套件強制執行健康瀏覽權限限制。

  • 請在每次對 BUILD 檔案有重大變更後建構專案,並在遇到建構錯誤時修正建構錯誤。

步驟 5:執行版本

執行完整遷移的版本,確認建構作業已完成,且沒有出現錯誤或警告。執行每個應用程式並個別測試目標,可更輕鬆地找出任何發生錯誤的來源。

例如:

bazel build //:my-target

步驟 6:使用 Rules_xcodeproj 產生 Xcode 專案

使用 Bazel 進行建構時,WORKSPACEBUILD 檔案會成為建構相關可靠資訊的來源。如要確保 Xcode 能瞭解這一點,您必須使用 rules_xcodeproj 產生與 Bazel 相容的 Xcode 專案。

疑難排解

當 Bazel 版本與所選 Xcode 版本不同步時 (例如套用更新時),就會發生 Bazel 錯誤。如果您在使用 Xcode 時遇到錯誤,請嘗試以下做法,例如「必須指定 Xcode 版本才能使用 Apple CROSSTOOL」。

  • 手動執行 Xcode 並接受任何條款及細則。

  • 使用 Xcode Select 來指出正確的版本、接受授權並清除 Bazel 的狀態。

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • 如果問題仍無法解決,您也可以嘗試執行 bazel clean --expunge