本文件詳細說明與 Fuchsia 建構作業運作方式相關的設計原則和特定技術決策。這些原則適用於所有 Fuchsia 建構模式,例如互動式工程工作流程,或 CI/CQ 等自動化系統。
建構目標和優先順序
與任何系統一樣,建構作業通常會受到多項衝突需求的影響。發生衝突時,我們通常會按照重要性順序,盡可能滿足這些優先事項:
- 符合 Fuchsia 技術主管判定的客戶需求。
- 確保正確性:生成所需輸出內容。
- 提升可維護性:說明文件、完善的工程程序。
- 提升效能:以較低的費用執行相同的建構作業。
建構作業的理想屬性
以下是建構作業的良好屬性:
- 密封性:建構作業是獨立的,不會影響外部軟體和設定,也不會受到外部軟體和設定的影響。
- 可重複性和可重現性:從相同來源樹狀結構進行兩次建構,會產生相同的輸出內容或相同的結果。可重現性可提升安全性和稽核,並簡化疑難排解。
- 有效率:建構作業應只花時間執行與建構相關的工作,且必須盡可能降低對人力和基礎架構成本的影響。
- 可攜性:建構作業應在所有支援的主機平台上產生一致的結果。
這些是理想。我們致力於實現這些理想,並根據這些指標評估進展。
將 Python 指令碼做為建構動作
Python 指令碼可用做建構動作。
請遵循 Google 的 Python 樣式指南。
Fuchsia 使用供應商提供的 Python 直譯器 (fuchsia-vendored-python,目前為 Python 3.11 以上版本)。Python 來源檔案的開頭必須是:
#!/usr/bin/env fuchsia-vendored-python
殼層指令碼做為建構動作
殼層指令碼可做為建構動作。
如果工作可以透過幾個簡單的殼層指令表示,建議使用殼層指令碼。如要執行複雜作業,建議使用其他語言。
請遵循 Google 殼層指令碼樣式指南。請使用 shellcheck 找出並修正常見的殼層程式設計錯誤。
我們偏好使用 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:
# build/bazel/scripts/trim_visibility.py --target="//path/to:foo_allowlist"
visibility = [
"//src/project1/*",
"//src/project2/*",
...
]
}
build/bazel/scripts/trim_visibility.py 會使用 fx gn refs 和 fx bazel query 尋找目標的消費者,並以檔案的語法列印經過修剪的清單。如果許可清單目標是在 BUILD.bazel 中定義,包括 bazel2gn 同步至 BUILD.gn 的目標,請以 Bazel 語法編寫許可清單;指令碼會根據 Bazel 和 GN 圖表中的消費者檢查許可清單。詳情請參閱 bazel2gn 說明文件。
然後在其他地方,自動新增對許可清單目標的依附元件。
# 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/*",
...
]
}
視變更性質和有問題的第三方程式碼而定,您可能可以在上游進行變更。請自行判斷。