建構系統政策

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

建構作業的目標和優先度

和任何系統一樣,建構作業通常會需要多個衝突的要求。發生衝突時,我們通常會依重要性順序滿足這些優先順序:

  1. 根據 Fuchsia 技術主管判斷,滿足客戶需求。
  2. 確保正確性:產生所需的輸出內容。
  3. 提倡可維護性:說明文件、聲音工程程序。
  4. 提升效能:以較低的費用執行相同的版本。

建構作業的所需屬性

下列為適合建構作業的屬性:

  • 密封設計:建構為獨立項目,既不會影響外部軟體和設定,也不受外部軟體和設定的影響。
  • 可重複性和可重現性:來自相同來源樹狀結構的兩個建構作業,會以確定性方式產生相同的輸出內容或產生相同結果。可重現性能促進安全性與稽核,並簡化疑難排解程序。
  • 有效率:建構應僅將時間花在與建構作業相關的工作上,且必須盡可能降低對人員與基礎架構成本的影響。
  • 可攜性 - 建構作業應在所有支援的主機平台中產生一致的結果。

此為理想選擇。我們的目標是達到這些理想目標,並透過這些措施評估進度。

做為建構動作的 Python 指令碼

Python 指令碼可能會做為建構動作使用。

請遵循 Python 適用的 Google 樣式指南

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/*",
    ...
  ]
}

視變更的性質和相關第三方程式碼而定,您或許可以在上游進行變更。請善用自己的判斷。