Fuchsia 建構系統使用自訂 Ninja 二進位檔,可為開發人員體驗帶來多項改善。本頁面將說明這些項目。
提振精神
如要瞭解自訂 Fuchsia 專用 Ninja 的動機,請參閱 RFC-0153。
簡而言之,上游版本難以提供許多功能,但這些功能對 Fuchsia 開發人員來說卻非常實用。
所有 Fuchsia 專屬變更都會在fuchsia-rfc-0153
本機 Ninja Git 鏡像的分支版本上執行,並定期重新設定基準,方便以 GitHub 提取要求的形式傳送至上游專案,如 RFC 的「策略」一節所述。
功能:正在執行的指令狀態
將環境中的 NINJA_STATUS_MAX_COMMANDS
設為嚴格正整數,讓 Ninja 在智慧終端機中執行時,在狀態列下方列印執行時間最長的指令表格,以及這些指令的經過時間。舉例來說,使用 export NINJA_STATUS_MAX_COMMANDS=4
時,狀態可能如下所示:
[0/28477](260) STAMP host_x64/obj/tools/configc/configc_sdk_meta_generated_file.stamp
0.4s | STAMP obj/sdk/zircon_sysroot_meta_verify.stamp
0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...chsia.media/cpp/fuchsia.media_cpp_common.common_types.cc.o
0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...fuchsia.media/cpp/fuchsia.media_cpp.natural_messaging.cc.o
0.4s | CXX obj/BUILD_DIR/fidling/gen/sdk/fidl/fuchsia.me...dia/cpp/fuchsia.media_cpp_natural_types.natural_types.cc.o
以下動畫圖片顯示實際情況:
請注意:
在 Ninja 的試執行或詳細叫用中 (也就是使用
-n
或--verbose
標記),這項功能會自動停用。如果 Ninja 未在互動式 / 智慧終端機中執行,這項功能就會自動停用。
執行控制台指令時,這項功能也會暫停 (如上例所示,執行 Bazel 動作時會暫停)。
這項功能可讓您輕鬆找出建構作業的瓶頸,也就是長時間執行的指令,導致其他指令無法平行執行。
預設情況下,指令表每秒會更新 10 次,這有助於瞭解哪些長時間執行的指令會拖慢建構速度。您可以將 NINJA_STATUS_REFRESH_MILLIS
設為毫秒的十進位值,變更重新整理週期 (請注意,系統會忽略低於 100 的值,因為經過的時間只會列印到單一十進位分數位數)。
功能:支援 GNU Make Jobserver
GNU Make Jobserver 通訊協定可讓建構系統在任何時間點限制並行工作 (即執行緒或程序) 的總數,即使存在遞迴建構工具叫用也是如此。
這需要頂層 server 設定 job slots 集區,供參與的用戶端共用 (例如編譯器、連結器,甚至是建構工具)。
Fuchsia 專屬的 Ninja 二進位檔可做為通訊協定的用戶端或伺服器。
啟動 Ninja 時,您可以透過 --jobserver
指令列標記啟用伺服器模式,或在環境中設定 NINJA_JOBSERVER=1
。
啟動 Ninja 時,系統會查看 MAKEFLAGS
環境變數的值,自動啟用用戶端模式。如果 Ninja 是從做為伺服器的其他建構作業呼叫,這項功能就相當實用。
在 Fuchsia 建構作業中,於 args.gn
中設定 enable_jobserver = true
,可讓頂層 Ninja 呼叫以伺服器模式啟動。
舉例來說,這項設定適用於核心 IDK 和核心 SDK 建構工具設定,可節省 6 到 12 分鐘的建構時間。因為這些作業需要從頂層建構作業啟動 24 個以上的 Ninja 子建構作業,而這些作業可運用通訊協定,更妥善地協調各自產生多個平行指令的方式。
功能:以 Chrome Trace JSON 陣列格式產生建構追蹤記錄
--chrome_trace FILENAME
選項可用於告知 Ninja 在建構作業完成後 (即使失敗也一樣),產生建構事件的追蹤記錄。
建議在輸出 FILENAME
中使用 .gz
後置字元,直接產生經過 gzip 壓縮的追蹤記錄檔,因為這類檔案通常會小 20 倍。
這個檔案採用 Chrome 追蹤 JSON 陣列格式,可直接載入任何 Chromium 架構瀏覽器的 chrome://tracing
分頁,更有趣的是,https://ui.perfetto.dev
也支援讀取壓縮追蹤記錄做為輸入內容。
請注意,產生的追蹤記錄檔也包含流程事件,有助於顯示建構作業的重要路徑。相應的建構事件會在 cat
欄位的值中顯示 critical_path
。
功能:持續模式可縮短啟動時間
在環境中設定 NINJA_PERSISTENT_MODE=1
,加快後續 Ninja 呼叫速度。這項功能會讓 Ninja 啟動背景伺服器程序,讀取建構資訊清單一次,然後在連續建構之間將建構圖保留在記憶體中。
請注意:
這項功能應完全透明,且不應影響 Ninja 的其他行為。如果發現問題或差異,請透過
fuchsia-build-team@google.com
告訴我們!系統會自動偵測輸入
.ninja
檔案的任何變更。在這種情況下,現有伺服器會關閉,並自動啟動新伺服器。變更 GN 建構檔案或執行jiri update
後,不需要額外與使用者互動。伺服器程序閒置 5 分鐘後,就會按適當流程關機。在環境中設定
NINJA_PERSISTENT_TIMEOUT_SECONDS=<count>
即可變更這項延遲。使用
fx build -t server status
擷取目前建構目錄的伺服器狀態。使用
fx build -t server stop
明確停止任何正在執行的伺服器執行個體。將
NINJA_PERSISTENT_LOG_FILE=<path>
設為將與持續模式相關的記錄檔傳送至指定檔案路徑。目前,每個伺服器程序會為
core.x64
建構設定佔用約 1 GiB 的 RAM。確切數字取決於 Ninja 圖形的大小,而這又取決於您的args.gn
設定。每個 Ninja 建構目錄最多只能由一個伺服器程序提供服務。 但使用多個建構目錄時,可能會有多個程序。
Ninja 工具 (例如
ninja -C <dir> -t commands <target>
) 尚未在伺服器上執行,因此仍會使用緩慢的啟動程序。我們將在日後修正這個問題,加快查詢速度。
已知錯誤 / 注意事項 (將會解決):
在同一目錄中混合使用持續性和非持續性建構作業,目前可能會造成伺服器混淆,因為系統無法正確偵測 Ninja 建構作業和依附元件記錄的獨立變更。我們會修正這個問題。
解決方法:先使用
-t server stop
停止伺服器,再取消環境中的NINJA_PERSISTENT_MODE
設定。「快速啟動」只需要幾秒鐘。目前,每個增量建構作業仍需為建構圖中的所有檔案呼叫 stat(),這目前需要幾秒鐘的時間。未來會使用主機作業系統的 inotify / kqueue 檔案系統監控功能修正這個問題,這樣一來,即使只有少數檔案經過修改,也能立即啟動。
目前不支援 Windows。這是因為 Win32 的技術限制,導致無法將控制台控制代碼複製到其他程序。這主要是上游 Ninja 團隊的問題,因為 Fuchsia 開發作業並非在 Windows 上進行。