本頁說明如何使用 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。
如果您不熟悉 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 工作區,您必須將依附元件轉換為 Bazel 套件,如「轉換 CocoaPods 依附元件」一文所述。
步驟 3:建立 BUILD
檔案
定義工作區和外部依附元件後,您需要建立 BUILD
檔案,告訴 Bazel 專案的結構。在 Bazel 工作區的根目錄中建立 BUILD
檔案,並將其設為執行專案的初始建構作業,如下所示:
提示:如要進一步瞭解套件和其他 Bazel 概念,請參閱「工作區、套件和目標」一文。
步驟 3a:新增應用程式目標
新增 macos_application
或 ios_application
規則目標。這個目標會分別建構 macOS 或 iOS 應用程式套件。在目標中,至少指定下列項目:
bundle_id
:二進位檔的軟體包 ID (反向 DNS 路徑,後面接著應用程式名稱)。provisioning_profile
:Apple 開發人員帳戶中的佈建設定檔 (如果是為 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 會建構測試輸出內容,但測試必須透過使用 Tulsi 產生的專案,在 Xcode 中執行。新增測試目標,如下所示:
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 版本才能使用 Apple CROSSTOOL」,請嘗試以下幾種方法。
手動執行 Xcode,並接受所有條款及細則。
使用 Xcode 選取功能來指出正確的版本、接受授權,並清除 Bazel 的狀態。
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license
bazel sync --configure
- 如果這個方法無效,您也可以嘗試執行
bazel clean --expunge
。