Fuchsia 建構系統

Fuchsia 建構系統的目標是為各種裝置建構開機映像檔和可更新的套件。Fuchsia 建構系統使用 GN,這是一種元建構系統,可產生 Ninja 執行的建構檔案,並執行實際建構作業。

概念

如果您不熟悉 Fuchsia 的建構系統和 GN,請參閱「使用 GN 建構」,瞭解 GN 建構系統的基本原則。

以下各節將介紹 Fuchsia 建構系統的幾個概念。

主面板和產品

生成的 Fuchsia 映像檔內容是由主機板和產品的組合控管。主機板和產品是建構目標,可定義映像檔中包含的套件和依附元件。如要進一步瞭解這些建構設定的結構和用途,請參閱「開發板和產品」。

建立目標

建構目標是在整個來源樹狀結構中存在的 BUILD.gn 檔案中定義。這些檔案使用類似 Python 的語法宣告可建構的物件。 例如:

import("//build/some/template.gni")

my_template("foo") {
  name = "foo"
  extra_options = "//my/foo/options"
  deps = [
    "//some/random/framework",
    "//some/other/random/framework",
  ]
}

可用的指令 (透過 gn CLI 工具叫用) 和內建目標宣告類型建構體,定義於 GN 參考資料.gni 檔案中也有一些自訂範本,位於 //build 專案

Fuchsia 定義了許多自訂範本,可支援定義及建構 Fuchsia 專屬構件。

建構最佳化旗標

使用 fx set 建構 Fuchsia 時,您可以指定建構最佳化標記,控制編譯時間、執行階段效能和可偵錯性之間的取捨。建構最佳化旗標為 --debug--balanced--release

選擇合適的標記會大幅影響開發工作流程、建構時間,以及產生的映像檔效能特徵。

快速比較

--debug --balanced --release
主要焦點 偵錯斷言,經過最佳化調整,可搭配偵錯工具使用 編譯速度快,且執行階段效能良好。 盡可能提升執行階段效能並縮小大小
編譯時間 較快 (增量) 中 (部分目標的速度比發布版本快 2 到 4 倍) 慢一點
執行階段效能 慢一點 良好 (適用於大多數開發作業) 快一點
二進位檔大小 較大 比偵錯版本小得多,比發布版本略大 小一點
最佳化 極簡 部分 完整
偵錯體驗 完整 介於 debugrelease 之間 (可偵錯程度略低於偵錯) 極簡
推薦學習對象 積極編碼和偵錯 每日開發和加快疊代速度 製作、基準化、效能分析、最終驗證

設定編譯模式

將所需旗標附加至 fx set 指令:

fx set PRODUCT.BOARD [--debug | --balanced | --release]

例如:

  • fx set core.x64 --debug
  • fx set core.x64 --balanced

建議使用 --balanced 的原因

導入 --balanced 旗標是為瞭解決 --release 建構作業的編譯時間負擔過大的問題,尤其是大型 Rust 和 C++ 目標。透過選擇性啟用最佳化功能,並使用 ThinLTO (而非 Full LTO) 等更快速的替代方案處理 C++,以及使用更多程式碼產生單元 (即編譯時的執行緒) 處理 Rust,--balanced 可為需要優於偵錯效能的作業提供更優質的開發人員體驗。

隨著 Fuchsia 的發展,--release建構作業可能會納入更積極的 (且編譯速度可能較慢) 最佳化項目,例如 Rust Full LTO、PGO,以及效能關鍵二進位檔的更高最佳化層級。另一方面,如果您使用 --balanced,就能進行效能感知開發,從持續的編譯時間改善中獲益,同時維持良好的執行階段特性。

建構最佳化旗標的完整比較

本節會完整比較建構最佳化旗標:

--debug
  • 主要目標:加快漸進式編譯速度,並提供完整的偵錯功能。
  • 最佳化:幾乎不需要。編譯的程式碼會盡量接近來源。
  • 偵錯體驗:包含完整偵錯符號。
  • 執行階段效能:較慢。不適合用於效能測試或正式環境。
  • 編譯時間 (完整重建):由於缺少最佳化傳遞,因此初始建構通常比 --release--balanced 快。通常增量建構的速度最快。
  • 使用時機:
    • 積極開發及偵錯程式碼。
    • 您需要使用偵錯工具逐步執行程式碼,並準確檢查變數。
    • 快速疊代比執行階段效能更重要。
--balanced
  • 主要目標:在編譯速度和執行階段效能之間取得平衡。
  • 最佳化:精選的最佳化項目,可提供良好的執行階段效能,且不會像 --release 一樣耗費過多編譯時間。
  • 偵錯體驗:介於 --debug--release 之間,偵錯能力略高於發布版本。部分最佳化項目可能會讓精確偵錯比 --debug 更困難。
  • 執行階段效能:良好。比完整 --release 建構稍慢 (在某些領域可能慢 10 到 20%),但比 --debug 快得多。在大多數開發和測試情境中,效能通常都能接受。
  • 編譯時間:--release 快上許多。如果是大型 Rust 目標,速度可提升 2 到 4 倍
    • 舉例來說,netstack3 的編譯速度快了 4 倍 (70 秒 vs 280 秒)。
    • 舉例來說,component_manager 的編譯速度快了 2.6 倍 (70 秒 vs 180 秒)。
  • 使用時機:
    • 如果您需要比 --debug 更快的速度,但又想避免 --release 的漫長編譯時間,這應該是您的預設編譯模式。
    • 一般開發和疊代,但 --debug 在執行階段過慢。
    • 需要測試功能,且效能合理,不必等待完整發行版本。
    • 持續享有編譯時間改善的優勢,因為這個模式會積極進行速度最佳化。
--release
  • 主要目標:盡可能提升執行階段效能,並縮小二進位檔大小。
  • 最佳化:已啟用完整最佳化功能。包括下列激進手法:
    • 連結時間最佳化 (LTO),通常是完整 LTO。
    • 視情況使用設定檔引導最佳化 (PGO)。
    • 較高的編譯器最佳化層級 (例如 -O3)。
  • 偵錯體驗:最少。除錯可能非常困難。
  • 執行階段效能:最快。這個模式適用於基準測試和正式版部署作業。
  • 編譯時間:最慢,因為需要進行大量最佳化傳遞和 LTO。
  • 使用時機:
    • 為正式版或部署作業建構。
    • 執行效能基準測試。
    • 您需要絕對最小的二進位大小和最高的執行階段速度,且願意接受較長的建構時間。

執行建構作業

執行建構作業最簡單的方法,就是透過 fx 工具使用 fx set 設定建構作業,然後使用 fx build,如 fx 工作流程所述。

設定建構作業

選擇要建構的開發板和產品,設定主要建構構件:

fx set

fx set core.x64

您也可以在這個指令中設定最佳化旗標。請參閱「建立最佳化旗標」。例如:

fx set core.x64 --balanced

fx gn gen

fx gn gen $(fx get-build-dir) --args='import("//boards/x64.gni") import("//products/core.gni")'

如要查看所有 GN 建構引數的清單,請執行:

fx gn args $(fx get-build-dir) --list

這會建立包含 Ninja 和 Bazel 檔案的建構目錄 (通常是 out/default)。

生成版本

使用 fx set 設定建構構件後,即可建構 Fuchsia:

fx build

fx build

這就是 fx build 在幕後執行的內容。

重新建構

如要在修改原始碼後重建樹狀結構,只要重新執行 fx build 即可。如果您修改 BUILD.gn 檔案,GN 也會新增 Ninja 目標,以便在建構檔案變更時更新 Ninja 目標。用於設定建構作業的其他檔案也適用相同規則。

提示與祕訣

這些提示和訣竅僅適用於 fx gn 指令。

檢查 GN 目標的內容

fx gn desc $(fx get-build-dir) //path/to/my:target

尋找 GN 目標的參照

fx gn refs $(fx get-build-dir) //path/to/my:target

參照建構主機的目標

各種主機工具 (有些用於建構本身) 必須與最終映像檔一併建構。

如要從 BUILD.gn 檔案中參照主機工具鍊的建構目標:

//path/to/target($host_toolchain)

僅建構特定目標

如果目標在 GN 建構檔案中定義為 //foo/bar/blah:dash,則可使用下列指令建構該目標 (及其依附元件):

fx build

fx build //foo/bar/blah:dash

fx build --host

fx build --host //foo/bar/blah:dash

偵錯建構時間問題

執行建構作業時,Ninja 會保留記錄,可用於查看建構程序。如要分析特定建構疊代的時序,請按照下列步驟操作:

  1. 照常執行建構作業。這會在輸出目錄中產生 .nina_log 檔案。

  2. 使用 fx ninjatrace2json 工具將 Ninja 記錄轉換為追蹤檔案。 例如:

    fx ninjatrace2json <your_output_directory>/.ninja_log > trace.json
    
  3. 在相容的追蹤記錄檢視器中載入產生的 trace.json 檔案。舉例來說,在 Chrome 中前往 chrome://tracing,然後按一下「載入」。

或者,您也可以使用 fx report-last-build。這個指令會收集完整的建構記錄和時間資訊。