本文詳細說明設計原則和相關的具體技術決策,這些決策與 Fuchsia 建構作業的運作方式有關。這些原則適用於所有 Fuchsia 建構版本的使用模式,例如透過互動式工程工作流程或 CI/CQ 等自動化系統。
建構目標和優先事項
與任何系統一樣,建構過程通常會受到多項衝突需求影響。如果發生衝突,我們通常會依重要性順序,優先滿足以下需求:
- 滿足 Fuchsia 技術領導團隊所決定的客戶需求。
- 確保正確性:生成所需輸出內容。
- 提升可維護性:說明文件、健全的工程程序。
- 提升效能:以更低的成本執行相同的建構作業。
建構的所需屬性
以下是建構時的良好屬性:
- 密封性 - 建構作業是獨立性質,不會影響外部軟體和設定,也不會受到外部軟體和設定影響。
- 可重複性和可重現性:來自相同來源樹狀結構的兩個建構作業,會確定性地產生相同輸出內容或結果。可重現性有助於提升安全性、稽核,並簡化疑難排解程序。
- 效率高:建構作業應只花時間處理與建構相關的工作,並盡量減少對人力和基礎架構成本的影響。
- 可攜性 - 建構作業應在所有支援的主機平台產生一致的結果。
這些都是理想。 我們致力於達成這些理想,並根據這些措施評估進展。
以 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/*",
...
]
}
視變更性質和有問題的第三方程式碼而定,您或許可以在上游進行變更。請依據自身經驗,盡可能作答。