常見樣式和最佳做法

總覽

下列樣式和最佳做法適用於 Fuchsia 中的所有 Bazel 檔案。

本頁面是 Bazel 樣式指南和最佳做法的一部分,其中包含特定情境的其他指引。

來源檔案和依附元件清單的本機變數

雖然官方指南不建議使用依附元件變數,但 Fuchsia 允許使用這些變數,以便管理大型共用來源檔案或依附元件清單。請判斷清單是否大致相似,或只是有幾個共同項目。

不減去:一律不從清單變數中移除項目。

請勿使用 glob()

請勿使用 glob() [SHAC error]。請改為明確列出檔案。

fx build 會透過 Ninja 動作執行 Bazel,而 Ninja 只會追蹤 glob() 上次執行時比對的檔案。如果您新增了 glob() 現在會比對的檔案,Ninja 不會注意到。漸進式建構作業和 fx test 執行作業會繼續使用舊的檔案清單。明確列出檔案時,新增檔案代表編輯 BUILD.bazel 檔案,Ninja 會追蹤這項操作。

這項規則僅適用於 Fuchsia。官方 Bazel 樣式指南允許非遞迴 glob,且一旦 Bazel 不再在 Ninja 內執行,可能就會再次允許。

glob() 的現有用途會列在執行檢查的每個存放區根目錄中的 build/bazel/shac/glob_allowlist.json (例如 //build/bazel/shac/glob_allowlist.json 和 //vendor/google/build/bazel/shac/glob_allowlist.json)。未經建構團隊核准,請勿新增項目。系統不會檢查 third_party/ 目錄下的上游程式碼。

一律不使用遞迴 glob

無論是否涉及 Ninja,請勿在任何 Bazel 程式碼中使用遞迴 glob (**) [SHAC 錯誤]。官方 Bazel 樣式指南禁止對來源檔案使用遞迴 glob。這類工具會略過含有專屬 BUILD.bazel 檔案的子目錄,因此很難判斷哪些檔案符合條件。此外,與每個目錄中的 BUILD.bazel 檔案相比,快取和平行處理效果也較差。

唯一的例外狀況是第三方資料庫和其他存放區 (例如 //vendor/... 存放區) 的特定情況,在這些情況下,列出每個路徑並不實際。在 third_party/ 目錄之外,這些檔案仍需要在 build/bazel/shac/recursive_glob_allowlist.json 中建立項目,這與 glob() 許可清單不同。

瀏覽權限

以下是適用於 BUILD.bazel 和 .bzl 檔案的一般指南。各項目的頁面會提供更具體的詳細資料。

盡可能在 BUILD.bazel 和 .bzl 檔案中指定瀏覽權限

唯一支援該屬性且不需指定的情況,是套件 (目錄) 專屬的巨集。

請勿使用公開瀏覽權限

請勿在 //build/bazel_sdk/*rules*/... 目錄外使用公開瀏覽權限 ("//visibility:public" 或 visibility("public")) [SHAC 錯誤]。只有在程式碼由外部存放區使用時,才適合採用這個存取層級,這不適用於 fuchsia.git 中的非 SDK 程式碼。

請勿參照供應商子路徑

請勿在可見度宣告中加入供應商子路徑或合作夥伴名稱 [SHAC 錯誤]。只有 //vendor:__pkg__、//vendor:__subpackages__、//vendor/google:__pkg__ 和 //vendor/google:__subpackages__ (或 .bzl 載入瀏覽權限宣告中的 //vendor/... 和 //vendor/google/...) 可以在公開 Fuchsia 程式碼中參照。

可見度應盡可能縮小範圍,同時仍允許測試和反向依附元件存取

可見度應僅限於需要和/或應允許使用的目標。保守但務實。舉例來說,如果目標用於 //src 的五個直接子目錄中,建議使用 //src:__subpackages__,以免在新增用途時需要修改可見度。不過,舉例來說,如果目標只能由驅動程式使用,請將其限制為實作驅動程式的套件。

使用套件群組定義常見的非一般瀏覽權限

如果多個目標的 visibility 應限制為同一組標籤,建議使用 package_group 表示該組標籤。package_group 與目標搭配使用時,也支援負值可見度,但與載入可見度搭配使用時則不支援。

請勿混用 SDK 和平台符號及目標

平台目標 (即 AIB 或 IDK 中的所有內容) 不得使用 Fuchsia Bazel SDK 中定義的符號、該 SDK 提供的目標,或使用該 SDK 建構的目標。

反之亦然,使用 Fuchsia Bazel SDK 建構的目標不應依賴平台目標,或從平台 .bzl 檔案載入符號。

請勿使用 Fuchsia Bazel SDK 路徑

平台程式碼不應存取包含 bazel_sdk 的檔案路徑,或 Fuchsia Bazel SDK 存放區路徑,例如:

  • @fuchsia_sdk//

  • @internal_sdk//

  • @rules_fuchsia//fuchsia

唯一允許的路徑開頭為 @fuchsia_rules_common/,但只有建構團隊可以直接使用這些路徑。

平台程式碼也應避免 bazel_sdk/ 路徑,除非是與 Fuchsia Bazel SDK 共用實作的特定建構規則。

目標和 .bzl 檔案的標籤

參照目標

參照目標時 (例如在 deps 中),只要不使用禁止的標籤模式,即可使用開頭為下列任一項的標籤:

從 .bzl 檔案載入

Fuchsia 平台的大多數一般用途巨集和規則,都可以在 //build/bazel/rules/ 中找到。

只要不使用禁止的標籤模式,即可安全地從標籤開頭為下列內容的 .bzl 檔案中 load():

下列項目也允許使用,但可能只有建構團隊的開發人員會使用:

  • @fuchsia_build_config//:defs.bzl

  • @fuchsia_build_info//:args.bzl

  • @fuchsia_rules_common//

禁止的標籤模式

請勿使用 [SHAC error]:

  • 工作區根套件標籤 (開頭為 //:)

    • 只有在非常特定且罕見的情況下,才需要執行這項操作 (請參閱問題 560343570),但一般來說,這項操作應由建構團隊執行。
  • 套件名稱 (標籤中冒號 (:) 後方的部分) 含有斜線 (/) 的標籤。

    • 整合第三方程式庫時,極少數情況下可能會有例外。

fuchsia_... 檔案和符號位於 Fuchsia Bazel SDK 中

請避免定義名稱開頭為 fuchsia_ 的檔案、巨集和規則。開頭為 fuchsia_ 的現有名稱可能屬於 Fuchsia Bazel SDK (請參閱「請勿使用 Fuchsia Bazel SDK 路徑」),避免使用這類名稱有助於維持區隔。

如需區分 Fuchsia 平台與一般 Bazel 識別碼時使用的模式,請參閱「包裝內建和常見規則、巨集和函式」。

使用 Fuchsia 專屬包裝函式

如果存在 Fuchsia 專屬包裝函式,請使用這些包裝函式,而非外部存放區、巨集等。這有助於確保 Fuchsia 建構設定套用一致。

具體來說,以下語言有包裝函式:

  • C/C++:使用 //build/bazel/rules/cc/... 的 fx_cc_...(),而非 @rules_cc// 的 cc_...。

  • Rust:使用 //build/bazel/rules/rust/... 的 rustc_...(),而非 @rules_rust// 的 rust_...。

Fuchsia 沒有下列語言的包裝函式。請從下列路徑載入,確保一致性:

  • Go:@io_bazel_rules_go//go...

  • Python:@rules_python//python...

字串

字串使用雙引號,除非是為了避免逸出

根據預設,請使用雙引號表示字串。不過,如果列印雙引號較為合適,且這樣做會涉及逸出雙引號 (\"),請使用單引號來避免逸出。