上次更新時間:2025-02-21
本頁面提供重要的 Bazel 相關指南,供樹狀結構內工作的 Fuchsia 開發人員 (即使用 fuchsia.git 檢出的開發人員) 參考。由於 Bazel 遷移作業是不斷變動的目標,我們會經常更新這個頁面,反映重要的變更。
摘要
自 2025 年第 1 季起,請遵守下列規範:
如果您不執行產品組合作業,也不撰寫驅動程式庫套件,請不要在 Fuchsia 樹狀結構中編寫 Bazel 檔案,或開始編寫這些檔案。
如果您要定義新的產品主控台或輸入套件,請使用 Bazel 目標和專屬的 Bazel SDK 規則,如這個範例所示。
如果您撰寫的 Bazel 驅動程式庫套件只供 Bazel 定義的板卡使用,請只在 Bazel 中定義這些套件,並使用專屬的 Bazel SDK 規則,如這個其他範例所示。
所有新的電路板開發作業都應在 Bazel 中進行。如果您的電路板恰好依附現有的 GN 驅動程式庫套件,請使用 bazel_driver_package() 範本將其公開至 Bazel 圖表 (請參閱此處的範例)。
以 Bazel 為基礎的驅動程式庫套件只能依附透過
@fuchsia_sdk
和@internal_sdk
存放區公開的平台程式庫。@fuchsia_sdk
包含一組程式庫,這些程式庫是分發的 OOT,但確實包含「不穩定」的平台程式庫,供驅動程式庫開發人員使用 (請在前一個連結的各行中尋找(unstable)
標記)。例如,
@fuchsia_sdk//pkg:driver_power_cpp
會從 GN//sdk/lib/driver/power/cpp
程式庫定義公開程式庫。@internal_sdk
包含類似的定義,但僅適用於僅在樹狀結構內 Fuchsia 版本中提供的 SDK 原子,因此可能更加不穩定。不過,我們已計劃移除這個類別,並將所有不穩定的原子移至@fuchsia_sdk
,因此不應在該類別中新增原子。請勿為內部平台程式庫編寫 BUILD.bazel 檔案。
目前,應避免為相同的非 SDK 程式庫重複建立 BUILD.gn / BUILD.bazel 定義。
如果驅動程式需要使用尚未以不穩定 IDK 原子形式公開的平台內部程式庫,請與 fuchsia-build-discuss@google.com 聯絡,說明您的用途。
理想情況下,只要新增一個不穩定的 IDK 原子即可,但也可能有例外狀況,請參閱下文專屬章節。
所有 Bazel 目標都必須由 GN 目標包裝,才能供建構後的用戶端查看。
具體來說,一或多個 Bazel 測試套件必須由 GN
bazel_test_package_group()
目標定義包裝,以確保fx test
和botanist
(我們的基礎架構 CI 測試執行元件工具) 可以瞭解這些套件,並視需要建構及執行這些套件。從 GN/Ninja 動作叫用 Bazel 會非常緩慢:即使 Bazel 決定不執行任何動作,也需要幾秒鐘的時間。而且一次只能執行一個。
這些動作是由 GN 範本定義,例如
bazel_action
或其中一個包裝函式,而這些動作的例項則是使用//build/bazel:bazel_action_allowlist
目標進行控制。範本 (例如
bazel_build_group()
或bazel_test_package_group()
) 只會呼叫 Bazel 一次,以便同時建構多個 Bazel 目標。這可提供更優異的平行處理功能。避免依附 Bazel 構件非終端 GN 目標
由於跨越 GN/Bazel 邊界會造成高成本,因此類似
GN -> Bazel -> GN -> Bazel -> GN
的依附元件鏈結會導致增量建構作業速度大幅降低,因此必須避免。詳情請參閱下方的專屬章節。
雙重 BUILD.bazel
和 BUILD.gn
定義
在遷移作業的其餘部分中,許多目標都會在等同的 BUILD.gn
和 BUILD.bazel
檔案中需要雙重定義。
非常重要:如果有這類雙重建構檔案,請務必隨時保持同步。另外,請務必追蹤兩個圖表中是否有雙重定義的目標。
初步且簡單的方法是手動編寫,並在兩個檔案中使用相符的 LINT
If-This-Then-That 區塊,在 CL 審查期間偵測偏差。
更好的方法是使用最近推出的 bazel2gn
等工具,自動將 BUILD.bazel
轉換為等效的 BUILD.gn
。
bazel2gn
目前只是原型,只會處理 Go 目標。隨著時間推移,這個工具會持續改善,以支援更多用途,但 Fuchsia 開發人員不應使用這個工具,因為其使用權限僅限於 Fuchsia 建構團隊。
無論是哪種情況,我們都會引入註解標記和相關工具,以追蹤兩個圖表中定義兩次的目標。
GN 和 Bazel 圖表之間的相依性
由於跨越 GN/Bazel 邊界成本高昂,因此類似 GN -> Bazel -> GN -> Bazel -> GN
的依附元件鏈會導致增量建構作業速度大幅降低。開發人員在查看實際依附元件時,由於缺乏明確資訊,因此建構作業失敗的情況也變得更難理解及修正。
目前,最小鏈結會顯示為 GN -> Bazel -> GN
,因為整個建構作業都由 GN 控制,而建構後的用戶端只會查看 GN 專屬的目標定義,因此任何 Bazel 構件都必須透過 GN 專屬目標包裝。
建構團隊正積極努力讓 Bazel 目標能夠原生顯示,以避免最後的 Bazel -> GN
邊緣。
這需要修改建構後工具和指令碼 (例如 fx test
和其他許多指令碼),才能直接查看 Bazel 輸出內容,並能夠視需要重新建構,而無需叫用 Ninja。
將平台程式庫公開為 SDK 原子
如要讓目標在 @fuchsia_sdk
中顯示,必須符合下列條件:
其類型必須與我們支援的 IDK 原子結構定義之一相符,也就是:
- 沒有 Rust 原始程式庫。
- 沒有 Go 原始碼程式庫。
必須在 GN 圖表中定義 (目前不支援在 Bazel 中定義 SDK/IDK 原子)。
由於 GN / Bazel 邊界有限制,因此無法使用
testonly = true
。且不得含有條件式依附元件。我們的 IDK 架構不支援這些項目,而且有充分理由。
來源程式庫無法依附非 SDK 程式庫。所有傳遞依附元件都必須是 SDK 的一部分。
必須使用與 SDK 相容的 GN 範本定義這些值,例如:
sdk_source_set()
:適用於 C++ 來源程式庫。sdk_static_library()
:適用於預先建構的靜態 C++ 程式庫。sdk_shared_library()
:適用於預先建構的共用 C++ 程式庫。fidl()
(已設定sdk_category
):適用於 FIDL 定義檔案。zx_library()
與sdk_publishable = true
:適用於需要連結至核心、Bootloader 或userboot
程式的 C++ 來源程式庫。sdk_fuchsia_package()
:適用於預先建構的 Fuchsia 套件。
如果您的平台程式庫無法遵守這些限制,請與 fuchsia-build-discuss@google.com 聯絡,討論其他做法。替代方案可能包括雙圖表目標定義,需要在遷移作業的其餘部分中追蹤。
文件記錄
2025-02-21:初始版本