本文詳細說明設計原則,以及與 Fuchsia 建構作業運作方式相關的特定技術決策。這些原則適用於所有 Fuchsia 建構版本的使用模式,例如透過互動式工程工作流程或 CI/CQ 等自動化系統。
建構目標和優先事項
與任何系統一樣,建構作業通常會受到多項衝突需求影響。發生衝突時,我們一般會依重要性順序滿足下列優先事項:
- 滿足 Fuchsia 技術領導團隊所決定的客戶需求。
- 確保正確性:生成所需輸出內容。
- 提升可維護性:說明文件、健全的工程程序。
- 提升效能:以更低的成本執行相同的建構作業。
建構的所需屬性
以下是建構時的良好屬性:
- 密封性 - 建構作業是獨立作業,不會影響外部軟體和設定,也不會受到外部軟體和設定影響。
- 可重複性和可重現性:來自相同來源樹狀結構的兩個建構作業,會確定性地產生相同輸出內容或結果。可重現性有助於提升安全性、稽核,並簡化疑難排解程序。
- 效率高:建構作業應只花時間處理與建構相關的工作,並盡量減少對人力和基礎架構成本的影響。
- 可攜性 - 建構作業應在所有支援的主機平台產生一致的結果。
這些都是理想。 我們致力於達成這些理想,並根據這些措施評估進展。
以 Python 指令碼做為建構動作
Python 指令碼可用於建構動作。
請遵循 Python 的 Google 樣式指南。
Fuchsia 目前使用 Python 3.8。所有 Python 來源都必須以以下內容開頭:
#!/usr/bin/env fuchsia-vendored-python
以建構動作形式執行的殼層指令碼
殼層指令碼可用於建構動作。
如果工作可以透過幾個簡單的殼層指令表示,建議使用殼層指令碼。如需複雜作業,建議使用其他語言。
請遵循 Google 的 Shell 指令碼編寫風格指南。 請使用 shellcheck 找出並修正常見的 Shell 程式設計錯誤。
我們偏好使用 POSIX (又稱 Bourne) 殼層指令碼,因為這類指令碼可移植到各種主機平台。如果您要維護現有的 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++ 隱含轉換,瞭解正向範例。
簡化及自動化許可清單維護作業
許可清單很容易表示為 GN 目標的 visibility 清單。這項功能可自動執行分析,並讓違反許可清單的變更快速建構失敗。
將目標加入許可清單,以使用您要遷移的舊版行為時,請將基本目錄加入許可清單,而非個別目標,方便這些目標的擁有者進行簡單的重構,例如重新命名目錄中的個別目標。
記錄重新產生及修剪任何許可清單的步驟,確保任何人都能執行。
請參考以下範例:
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/*",
...
]
}
視變更性質和相關第三方程式碼而定,您或許可以進行上游變更。請根據您的最佳判斷做出決定。