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 參考資料中定義了可用的指令 (透過 gn
命令列工具叫用) 和內建目標宣告類型的建構。//build
專案中的 .gni
檔案中,也包含一些自訂範本。
Fuchsia 定義了許多自訂範本,可支援定義和建構 Fuchsia 專屬的構件。
建構最佳化旗標
使用 fx set
建構 Fuchsia 時,您可以指定建構最佳化標記,藉此控制編譯時間、執行階段效能和可偵錯性之間的權衡。建構最佳化旗標為 --debug
、--balanced
和 --release
。
選擇正確的旗標,可大幅影響開發工作流程、建構時間,以及產生圖像的效能特性。
快速比較
--debug |
--balanced |
--release |
|
---|---|---|---|
主要焦點 | 偵錯斷言,經過最佳化調整,可搭配偵錯工具使用 | 編譯速度和良好的執行階段效能。 | 最高的執行階段效能和最小的大小 |
編譯時間 | 較快 (增量) | 中 (部分目標比發布版快 2 到 4 倍) | 慢一點 |
執行階段效能 | 慢一點 | 良好 (適用於大多數開發作業) | 快一點 |
二進位檔大小 | 較大 | 比偵錯版本小得多,比發布版本大一點 | 小一點 |
最佳化 | 極簡 | 部分 | 已滿 |
偵錯體驗 | 已滿 | 從 debug 到 release (比 debug 稍微不易偵錯) |
極簡 |
推薦學習對象 | 主動編寫程式碼和偵錯 | 每天進行開發作業,加快疊代速度 | 正式環境、基準測試、最終驗證 |
設定編譯模式
將所需旗標附加至 fx set
指令:
fx set PRODUCT.BOARD [--debug | --balanced | --release]
例如:
fx set core.x64 --debug
fx set core.x64 --balanced
為什麼要使用 --balanced
?
--balanced
標記是為瞭解決 --release
建構作業的大量編譯時間額外負擔,特別是針對大型 Rust 和 C++ 目標。--balanced
會針對需要比偵錯更佳效能的作業,選擇性啟用最佳化功能,並使用較快的替代方案,例如針對 C++ 使用 ThinLTO (而非 Full LTO),以及針對 Rust 使用更多 codegen 單位 (即編譯時的執行緒)。
隨著 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 秒與 280 秒)。 - 例如:
component_manager
編譯速度提高 2.6 倍 (70 秒 vs. 180 秒)。
- 例如:
- 使用時機:
- 如果您需要比
--debug
更快的執行速度,但想避免--release
的長時間編譯時間,則應使用預設的編譯模式。 - 一般開發和迭代作業,
--debug
在執行階段速度過慢。 - 當您需要測試功能的合理效能,而不需要等待完整發布版本時。
- 為了讓您能持續享有編譯時改善的效益,我們會積極為這個模式進行速度最佳化。
- 如果您需要比
--release
- 主要目標:盡可能提高執行階段效能,並縮小二進位檔案大小。
- 最佳化:已啟用完整最佳化功能。這包括以下激進的技術:
- 連結時間最佳化 (LTO),通常是全 LTO。
- 在適用情況下使用設定檔引導最佳化 (PGO)。
- 較高的編譯器最佳化層級 (例如
-O3
)。
- 偵錯體驗:最少。偵錯作業可能非常困難。
- 執行階段效能:最快。這是基準測試和實際部署的模式。
- 編譯時間:最慢,因為需要進行大量最佳化階段和 LTO。
- 使用時機:
- 建構正式版或部署項目。
- 執行效能基準測試。
- 您需要絕對最小的二進位檔大小和最高的執行階段速度,且願意接受較長的建構時間。
執行建構作業
執行建構作業最簡單的方法,就是透過 fx
工具,使用 fx set
設定建構作業,然後按照fx 工作流程所述執行 fx build
。
設定建構
選擇要建構的板子和產品,設定主要建構成果:
fx 集
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 會保留記錄,方便您查看建構程序的步驟。如要分析特定建構版本的時間,請按照下列步驟操作:
按照平常的方式執行建構作業。這樣做會在輸出目錄中產生
.nina_log
檔案。使用
fx ninjatrace2json
工具,將 Ninja 記錄轉換為追蹤記錄檔。例如:fx ninjatrace2json <your_output_directory>/.ninja_log > trace.json
在相容的追蹤記錄檢視器中載入產生的
trace.json
檔案。舉例來說,在 Chrome 中前往chrome://tracing
,然後按一下「Load」。
您也可以使用 fx report-last-build
。這個指令會收集完整的建構記錄和時間資訊。