本文件詳細說明 Fuchsia 建構的運作方式,而製定的設計原則和具體的技術決策。這些原則適用於 Fuchsia 版本的所有使用模式,例如透過互動式工程工作流程或透過持續整合/CQ 等自動化系統。
建構作業的目標和優先度
和任何系統一樣,建構作業通常會需要多個衝突的要求。發生衝突時,我們通常會依重要性順序滿足這些優先順序:
- 根據 Fuchsia 技術主管判斷,滿足客戶需求。
- 確保正確性:產生所需的輸出內容。
- 提倡可維護性:說明文件、聲音工程程序。
- 提升效能:以較低的費用執行相同的版本。
建構作業的所需屬性
下列為適合建構作業的屬性:
- 密封設計:建構為獨立項目,既不會影響外部軟體和設定,也不受外部軟體和設定的影響。
- 可重複性和可重現性:來自相同來源樹狀結構的兩個建構作業,會以確定性方式產生相同的輸出內容或產生相同結果。可重現性能促進安全性與稽核,並簡化疑難排解程序。
- 有效率:建構應僅將時間花在與建構作業相關的工作上,且必須盡可能降低對人員與基礎架構成本的影響。
- 可攜性 - 建構作業應在所有支援的主機平台中產生一致的結果。
此為理想選擇。我們的目標是達到這些理想目標,並透過這些措施評估進度。
做為建構動作的 Python 指令碼
Python 指令碼可能會做為建構動作使用。
Fuchsia 目前使用 Python 3.8。所有 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++ 隱含轉換,做為正面範例。
簡化並自動執行許可清單維護作業
許可清單可以輕鬆以 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/*",
...
]
}
視變更的性質和相關第三方程式碼而定,您或許可以在上游進行變更。請善用自己的判斷。