建構系統政策

本文詳細說明設計原則和相關的具體技術決策,這些決策與 Fuchsia 建構作業的運作方式有關。這些原則適用於所有 Fuchsia 建構版本的使用模式,例如透過互動式工程工作流程或 CI/CQ 等自動化系統。

建構目標和優先事項

與任何系統一樣,建構過程通常會受到多項衝突需求影響。如果發生衝突,我們通常會依重要性順序,優先滿足以下需求:

  1. 滿足 Fuchsia 技術領導團隊所決定的客戶需求。
  2. 確保正確性:生成所需輸出內容。
  3. 提升可維護性:說明文件、健全的工程程序。
  4. 提升效能:以更低的成本執行相同的建構作業。

建構的所需屬性

以下是建構時的良好屬性:

  • 密封性 - 建構作業是獨立性質,不會影響外部軟體和設定,也不會受到外部軟體和設定影響。
  • 可重複性和可重現性:來自相同來源樹狀結構的兩個建構作業,會確定性地產生相同輸出內容或結果。可重現性有助於提升安全性、稽核,並簡化疑難排解程序。
  • 效率高:建構作業應只花時間處理與建構相關的工作,並盡量減少對人力和基礎架構成本的影響。
  • 可攜性 - 建構作業應在所有支援的主機平台產生一致的結果。

這些都是理想。 我們致力於達成這些理想,並根據這些措施評估進展。

以 Python 指令碼做為建構動作

Python 指令碼可用於建構動作。

請遵循 Python 的 Google 樣式指南

Fuchsia 使用供應商提供的 Python 解譯器 (fuchsia-vendored-python, 目前為 Python 3.11 以上版本)。Python 來源檔案開頭必須是:

#!/usr/bin/env fuchsia-vendored-python

以建構動作形式執行的殼層指令碼

Shell 指令碼可用做建構動作。

如果工作可以透過幾個簡單的殼層指令表示,建議使用殼層指令碼。如需複雜作業,建議使用其他語言。

請遵循 Google 殼層指令碼樣式指南。 請使用 shellcheck 找出並修正常見的 Shell 程式設計錯誤。

我們偏好使用 POSIX (又稱 Bourne) Shell 指令碼,以便在各種主機平台之間移植。如果您要維護現有的 Bash 指令碼,請將使用的功能限制為 3.2 版,或考慮將指令碼重寫為 POSIX 殼層指令碼。如要檢查指令碼是否符合 POSIX 標準,可以使用:

shellcheck --shell=sh

在 POSIX 殼層執行的指令碼應以以下內容開頭:

#!/bin/sh

如果指令碼必須使用 Bash,開頭應為:

#!/bin/bash

遷移

建構系統可協助您執行遷移作業,例如編譯器功能、新工具或各種最佳做法的擴散。通常可以根據套用此行為的 config() 依附元件,表示舊版的不良行為。如果依附於 group() 目標,即可擷取要取代的舊版工具或範本。

簽訂方案

我們一向歡迎您改善程式碼健康狀態,但開始前,請先擬定明確的計畫,確保能完成您著手進行的工作。如果遷移作業只完成一半,且後繼無力,可能比完全不遷移還糟。

建立迴歸停止點

假設程式碼集每 8 個月就會增加一倍,請盡早採取行動,避免導入舊版行為的新執行個體。建立迴歸停止點後,您會「被動」清理程式碼集,因為程式碼集會受到倍增率的控管,也就是每經過一個倍增週期,您就會被動清理一半的程式碼集。

請確保許可清單受到 OWNERS 檔案保護,且遷移作業的聯絡窗口列為擁有者。由於擁有者是依檔案定義,因此建議將允許清單細分成不同的 BUILD.gn 檔案。舉例來說,與 Rust 相關的 config() 目標已移至 //build/config/rust,以便更妥善地管理 OWNERS 指派作業。

文件遷移 / 清除步驟

發布清楚的文件,說明遷移的性質、參與方式,以及如何執行相關維護工作。這樣一來,您就能擴大規模進行遷移作業,且不會因為個別人員無法處理支援要求或回答問題,而導致遷移作業受阻。

請查看 C++ 隱含轉換這個正向範例。

簡化及自動化許可清單維護作業

許可清單很容易以 visibility 清單的形式表示,供 GN 目標使用。這有助於自動化分析,並讓違反許可清單的變更快速建構失敗。

將目標加入許可清單,以使用您要遷移的舊版行為時,請將基本目錄加入許可清單,而非個別目標,方便這些目標的擁有者進行簡單的重構,例如重新命名目錄中的個別目標。

記錄重新產生及修剪任何許可清單的步驟,確保任何人都能執行。

請參考以下範例:

group("foo_allowlist") {
  #  ________  _________  ________  ________
  # |\   ____\|\___   ___\\   __  \|\   __  \
  # \ \  \___|\|___ \  \_\ \  \|\  \ \  \|\  \
  #  \ \_____  \   \ \  \ \ \  \\\  \ \   ____\
  #   \|____|\  \   \ \  \ \ \  \\\  \ \  \___|
  #     ____\_\  \   \ \__\ \ \_______\ \__\
  #    |\_________\   \|__|  \|_______|\|__|
  #    \|_________|
  # This is an allowlist of targets that use the deprecated "foo" tool.
  # As of April 2021 we no longer use "foo". Users should migrate to the new
  # "bar" tool as described in this guide:
  # https://fuchsia.dev/...
  #
  # To regenerate:
  # fx gn refs $(fx get-build-dir) //path/to:foo_allowlist | sed 's|\(.*\):.*|"\1/*",|' | sort | uniq
  #
  # To trim:
  # scripts/gn/trim_visibility.py --target="//path/to:foo_allowlist"
  visibility = [
    "//src/project1/*",
    "//src/project2/*",
    ...
  ]
}

然後在其他位置,自動新增允許清單中目標的依附元件。

# Invoke the legacy foo tool.
# For new usage, please consider using the new bar tool instead!
# See:
# https://fuchsia.dev/...
# ...
template("foo") {
  action(target_name) {
    ...
    deps += [ "//build/foo:foo_allowlist" ]
  }
}

第三方可能超出範圍

Fuchsia 使用許多第三方程式碼,也就是 Fuchsia 專案範圍外的程式碼。一般而言,針對有主觀意見的變更或政策決策,通常可以為所有第三方程式碼輸入全面性的許可清單。

group("bar_allowlist") {
  ...
  visibility = [
    "//third_party/*",
    ...
  ]
}

視變更性質和有問題的第三方程式碼而定,您或許可以在上游進行變更。請依據自身經驗,盡可能作答。