fx 工作流程

本文說明在 Fuchsia 開發環境中使用 fx 工具的基本工作流程。

設定 fx

fx 是一組子指令的進入點,可簡化許多與 Fuchsia 開發相關的工作。(執行 fx help 即可查看所有可用的子指令)。

如果您使用 bashzsh 做為殼層,強烈建議您執行 source scripts/fx-env.sh,在殼層中啟用自動完成功能。這項設定已通過測試,並經常與 bashzsh 搭配使用,也可能適用於其他相容的殼層。

  1. 前往 Fuchsia 結帳頁面,例如:

    cd ~/Fuchsia
  2. 在殼層中新增設定,加入 fx-env.sh

    echo "source \"$PWD/scripts/fx-env.sh\"" >> "$HOME/.$(basename "$SHELL")rc"
  3. (選用) 如要使用 Fuchsia 指令碼提供的其他便利工具,請執行下列指令:

    echo "fx-update-path" >> "$HOME/.$(basename "$SHELL")rc"
  4. 重新啟動殼層:

    exec "$SHELL"

這些步驟可提供最明確定義的功能集,且通常不會造成干擾。如果這會導致殼層環境發生錯誤,請回報專案錯誤。

如果基於某些原因,您需要使用多個 Fuchsia 結帳程序 (建議的工作流程應可避免這種情況),則可能需要執行上述以外的動作。如果是這種情況,可以採取幾種做法:

  • 一律明確執行 $FUCHSIA_DIR/scripts/fx
  • 在特定 Fuchsia 目錄中工作時,請使用 direnvdotenv 等工具,將 $FUCHSIA_DIR/.jiri_root/bin 新增至 $PATH

常見的日常工具

簽出 Fuchsia 樹狀結構後,首先要做的就是建構 Fuchsia,然後將其安裝到裝置上。fx 提供一些指令,可協助您完成這項操作:

設定建構作業

首先,請設定建構作業。如要這麼做,請選擇下列項目:

  • 你想要哪種產品設定? (不確定:請嘗試 workbench_eng)
  • 您要建構的開發板為何?(不確定:請嘗試 x64)
  • 您還想加入哪些額外測試目標?(不確定:請嘗試 //bundles/tools,如果您正在開發功能,可能需要 //bundles/tests)

現在您已掌握上述選項 (如果還沒看過,請先閱讀),可以開始設定建構作業:

fx set workbench_eng.x64 --with //bundles/tests

在結帳程序中執行 fx set 後,除非需要修改後續引數,否則不必再次執行。

fx set 會將設定儲存在輸出目錄的 args.gn 檔案中。 輸出內容直接為 out/default。您可以使用 fx --dir <out_dir> set <set_args> 指定其他目錄。

您可以使用 fx args 指令編輯產生的 args.gn 檔案,建立更精細的設定。fx args 會在編輯器中開啟 args.gn,讓您進行變更並重新產生建構圖。

發生什麼事了?

  • 您選取了產品 workbench_eng (如要查看其他產品設定的清單,請執行 fx list-products)。
  • 您選取的開發板是 x64,這款開發板支援許多以 x64 架構為基礎的常見開發板。(請注意,arm64 板的互換性較低,建構 arm64 架構時,您很可能需要提供 fx set 特定板。執行 fx list-boards,即可查看已知主機板設定的清單。
  • 您正在暫時建構 tests,做為 universe 套件組合的一部分。

套件部署選項

--with 選項有三種變體,與套件部署至 Fuchsia 裝置的方式有關:--with-base--with-cache--with (表示 universe)。(請注意,fx set 也有 --with-host 選項,用於建構僅限主機的目標,例如以主機為基礎的工具和程式庫)。

那麼 basecacheuniverse 是什麼?

設定最終會指定有助於建構輸出構件 (主要是映像檔和套件存放區) 的依附元件 (主要是套件)。建構作業會經過參數化,以判斷要將哪些依附元件 (主要是套件) 新增至哪些輸出成果 (映像檔或套件存放區)。這三個軸分別是「基礎」、「快取」和「宇宙」:

  • 基礎:新增至基礎的套件會納入建構作業產生的系統映像檔。這些項目會透過無線更新提供,且一律會以單一單元的形式更新。基礎中的套件無法在執行階段從裝置中逐出,因為這些套件會編碼設定的最小可能大小。
  • 快取:快取中的套件會納入系統映像檔,但不會納入無線系統更新,且系統可因應資源需求 (例如磁碟空間不足) 移除這些套件。快取中的套件可在有更新時隨時更新,且每個套件可獨立更新。這類軟體屬於「選用」性質,但「開箱」後即可立即使用,因此相當實用。
  • Universe:Universe 中的套件是額外的選用套件,可視需要擷取及執行,但不會預先建構到任何系統映像檔中。

「主機板」和「產品」設定會為每個套件組選擇預先定義的一組成員。通常主機板設定會指定一組要新增至基本依附元件集的開機重要驅動程式,例如快取集可能包含一些選用但常見的周邊驅動程式。此外,主機板設定也可能包含一些主機板專用的開發工具 (通常是主機工具,而非目標套件),用於在「宇宙」中與主機板互動。產品設定會根據所代表產品的定義和功能集,選擇在基礎、快取或宇宙套件集中加入更多或更少的軟體。舉例來說,音箱產品會將許多音訊媒體相關套件新增至基礎。工作台產品會在基礎中加入各種 GUI、媒體和許多其他套件。

主要產品設定

以下僅列出部分設定,但建議您熟悉下列三項特別重要的設定:

  • bringup 是一套功能最少的產品,著重於簡單和精簡。這個工具可提供快速建構和小型映像檔 (主要用於 netboot,而非時尚),非常適合處理極低層級的設施,例如 Zircon 核心或特定主機板的驅動程式和設定。因此無法在執行階段新增軟體或升級。這也表示部分 fx 指令 (例如 fx servefx shell) 無法搭配 bringup 產品使用。
  • core 是一組最基本的功能,可安裝其他軟體 (例如新增至「universe」依附元件集的項目)。這是所有高階產品設定的起點。具備常見的網路功能,可透過無線方式更新系統。
  • workbench_eng 是通用開發環境的基礎,適合處理 UI、媒體和許多其他高階功能。這也是愛好者盡情玩樂和探索的最佳環境。

主要額外建構目標

fx set--with 旗標會接收任意建構目標。為方便起見,系統定義了許多套件組合,其中包含各種常用的建構目標。請務必熟悉下列套裝組合:

  • //bundles/tools 包含各種最常用的開發人員工具。包括從指令列殼層產生元件的工具、重新設定及測試網路的工具、發出 HTTP 要求、偵錯程式、變更音量等。核心產品預設會包含在宇宙套件組合中。//bundles/tools
  • //bundles/tests 會導致所有測試程式建構完成。大多數測試程式都可以使用裝置上的 run-test-suite 或透過 fx test 叫用。
  • //bundles/kitchen_sink 是會納入所有其他建構目標的目標。這項功能有助於測試核心變更的影響,或是在程式碼庫中進行大規模變更。對於愛好者來說,這也是很有趣的設定,因為其中包含來源樹狀結構中的所有軟體。請注意,Kitchen Sink 會產生超過 20 GB 的建構構件,且目標裝置上至少需要 2 GB 的儲存空間 (2019 年第 1 季的預估大小)。

執行建構作業

如上所示,使用 fx set 設定建構作業後,您就可以使用 fx build 執行建構作業。這項指令會建構所有必要目標及其輸出內容。

清除建構作業

你可以在結帳時繼續變更檔案,然後執行 fx build 來重建。如果先前建構作業有結果,建構系統會嘗試減少工作量。使用先前建構結果的建構作業稱為增量建構,通常比簡潔的重建作業快得多。

變更設定不應導致累加建構作業中斷,但由於建構系統的限制,在極少數情況下仍可能發生這種情形。如果發生這種情況,請提交詳細錯誤報告,其中包含重現問題的步驟,以及建構記錄等診斷資訊。然後使用下列指令復原:

  • fx clean 會清除所有建構構件。
  • fx clean-build 相當於 fx clean,然後 fx build
  • fx cleandead-build 相當於 fx cleandead,然後 fx build

啟用增量套件重建

根據預設,fx build 會為指定產品設定建構所有套件。這對某些開發人員工作流程來說是必要的,但對許多其他工作流程來說則過於繁瑣。 如果您只是要疊代測試,應該不需要重建及重新發布所有暫時性 (universe) 套件。

如要在 ~/.bashrc 或同等項目中新增 export FUCHSIA_DISABLED_incremental=0,即可啟用增量重建功能。這項變更會導致下列情況:

  • (fx serve)fx-serve-ref 會監控在 Fuchsia 建構作業中建立或修改的套件,並自動發布這些套件。這可讓您從空白樹狀結構繼續執行 fx serve,並在您工作時逐步發布變更。

  • fx test 只會建構執行所需的最低目標。如果是元件測試,則為套件、GN 依附元件和 //zircon

請注意,fx build 的行為維持不變。

疊代快取套件

執行 fx build 除了編譯及發布快取套件外,還會觸發完整的系統組裝作業。如果工作流程只需要疊代重建快取套件,執行 fx build 可能會造成過度負載,導致速度變慢。

如要重建快取套件,請將 fx build 替換為 fx publish cache,即可加快建構速度。以下是典型開發工作流程的範例:

# Set up your workspace here.
$ fx serve

# Make changes to cache packages here.

# Rebuild and publish cache packages:
$ fx publish cache

# Restart your component, for example:
$ ffx component stop /core/your_component
$ ffx session restart

已知問題:重新啟動 Fuchsia 模擬器不會導致元件從更新的套件執行。您必須手動重新啟動元件。

如要查看所有快取套件的清單,可以執行 fx list-packages --cache

建立特定目標

fx build 可以指定要建構的特定目標或檔案名稱。

如果啟用實驗性 build-with-labels 功能,可以直接將 GN 標籤傳遞至 fx build。舉例來說,fx build //examples/hello_world 會建構 Fuchsia 的 //examples/hello_world:hello_world GN 目標,而 fx build --host //examples/hello_world 則會為主機建構該目標。

如果未啟用這項功能,您也可以傳遞其中一個 GN 目標輸出的 Ninja 目標路徑。對於在預設工具鍊中定義的 GN 目標,GN 會定義類似 GN 標籤的 Ninja 別名,但沒有開頭的 // 前置字串,因此 fx build examples/hello_world:hello_world 會在預設工具鍊中建構 GN 目標 //examples/hello_world 的輸出內容。

不過,如果目標是在非預設工具鍊中宣告,您就必須猜測 Ninja 輸出路徑,這通常非常棘手。不過,主機二進位檔通常位於 host_x64 子目錄下。因此,如果該目標只定義為 executable(),則 //foo/bar:blah(//build/toolchain:host_x64) 可以使用 fx build host_x64/blah 建構。

如需建構目標的詳細討論,請參閱建構系統總覽

建立產品組合 ZIP 檔案

如果您已建構 Fuchsia 產品 (執行 fx build),可以執行下列指令建立 ZIP 檔案,其中包含產品組合:

fx create-pb-zip -o <path-to-pb-zip>

這個指令會在您指定的路徑中,建立包含產品組合的 ZIP 檔案。

建立及上傳產品組合 ZIP 檔案

fx build-and-upload 指令提供便利的方式,可透過單一步驟建構 Fuchsia、建立產品組合 ZIP 檔案,並上傳至 Google Cloud Storage (GCS) bucket。

fx build-and-upload

根據預設,這項指令會將產品組合上傳至 gs://fuchsia-build-stage 值區。不過,您可以使用 --bucket (或 -b) 旗標指定其他 GCS 儲存空間:

fx build-and-upload --bucket gs://<bucket-name>

上傳完成後,即可直接使用列印的 GS 網址,透過 ffx 指令刷寫目標裝置或啟動模擬器,例如:

# Flash a target device
$ ffx target flash -b gs://fuchsia-build-stage/pb.zip
# Start the emulator
$ ffx emu start gs://fuchsia-build-stage/pb.zip -H

準備 Zedboot USB 隨身碟

將 Fuchsia 刷入目標裝置所需的準備工作因裝置而異,但您可以使用 fx mkzedbootx64 裝置準備可開機的 USB 磁碟機,並啟動 Zedboot。

什麼是 Zedboot?

Zedboot 是 Zircon 的特殊設定,包含簡單的網路堆疊、簡單的裝置廣告和探索通訊協定,以及一組通訊協定,可將 Fuchsia 寫入目標磁碟和/或透過網路啟動目標系統。Zedboot 是指整體程序,也是一種特殊的建構設定。許多人稱之為「ASCII 藝術藍畫面」。

如要在 arm64 目標上進入 Zedboot,請啟動裝置,同時觸發啟動進入 Fastboot 刷機模式 (通常需要按住特定按鈕,然後重新啟動或啟動裝置,具體做法因硬體目標而異)。進入閃爍模式後,在主機系統上執行 fx flash

如要在 x64 目標上進入 Zedboot,請先使用 fx mkzedboot <path-to-usb-device> 產生 Zedboot USB 金鑰 (如要在系統上列出合適的 USB 裝置,請執行 fx list-usb-disks)。完成後,請移除 USB 金鑰,插入目標裝置,然後重新啟動目標裝置,並從開機選項或裝置 BIOS 中選取「從 USB 開機」。

什麼是網路開機?

在 Fuchsia 中,「netboot」是指將一組構件傳送至 Zedboot 例項,該例項不會變更磁碟,只會從 RAM 開機。使用者可以先使用 fx flash (arm64) 或 fx mkzedboot (x64) 將裝置啟動至 Zedboot,然後在主機系統上執行 fx netboot,即可執行「網路啟動」。

提供建構版本

Fuchsia 的許多建構設定都包含軟體,但建構作業產生的基礎映像檔不會立即納入這些軟體,而是在閃爍期間寫入裝置。這類軟體會視需要提供給目標裝置,通常俗稱為「暫時性軟體」。

fx serve 指令會在內部執行兩項函式:

  • 啟動套件存放區伺服器,用於在執行階段動態安裝軟體,以及進行全系統更新。

在內部,fx serve 指令也會搜尋要設定的裝置,並在探索到裝置後 (可能受 fx set-devicefx -t 限制/調變),將目標裝置設定為使用存放區伺服器做為動態套件和系統更新的來源。

更新目標裝置

如先前章節所述,Fuchsia 裝置上有多個軟體群組:

  • 屬於核心系統「基礎」的軟體,會透過單一交易更新。
  • 屬於 Zedboot 映像檔 (而非基礎 (快取)) 的軟體,可暫時更新。
  • 一律為暫時性 (宇宙) 的軟體。

對於新使用者開發工作流程,最通用的指令是 fx ota,可協助更新目標裝置。fx ota 指令會先更新「base」和「cache」軟體,完成後重新啟動目標裝置。就軟體版本而言,這個程序的最終結果應與全新刷機的裝置無異。

由於 fx ota 程序會導致裝置重新啟動,因此有時並非診斷、偵錯或其他非測試工作流程或需求的最佳程序。在這些情況下,使用者可以選擇確保裝置上的軟體定期更新。

fx serve 程序會設定具有自動更新功能的 Fuchsia 軟體存放區。每當基礎存放區更新時 (每次成功執行 fx build 後就會更新),存放區就會通知目標裝置有新的軟體更新。對於許多軟體元件,開發期間最簡單的更新方式是確保這些元件未納入基本設定,而是納入「快取」或「universe」。在這種情況下,只要重新啟動目標上的軟體 (例如完全關閉軟體,或叫用 killall),軟體就會在再次啟動時立即更新。

執行測試

Fuchsia 程式碼集包含許多測試。這些測試大多是元件本身,可透過與其他元件相同的方式在目標裝置上啟動。在目標裝置上,部分程式也會協助處理元件啟動的測試相關問題,例如 run-test-suite。您也可以透過 fx test,從開發主機輕鬆控管這個程序。詳情請參閱「執行 Fuchsia 測試」。

部分使用者發現,有效的高專注工作流程是讓系統在每次儲存原始碼時,建構、推送及執行測試。您可以使用 fx 輕鬆達成此目的,例如:

fx -i test hello-world-rust-tests

每當樹狀結構中的原始碼有所變更,上述指令就會執行測試。-i 旗標會將 -i 變更為 fx,導致 fx 在樹狀結構中的原始碼每次變更時,重複執行其餘指令。由於 fx test 指令會先執行建構作業,然後在目標上執行測試,因此這個組合提供方便的自動測試迴圈,非常適合測試驅動開發等高度專注的工作流程。

連線至目標殼層

大多數產品設定都包含 SSH 伺服器,並採用 Fuchsia 專屬設定。fx shell 指令是透過 SSH 連線至目標裝置的便利包裝函式,可存取非常簡單的 POSIX 樣式殼層。請注意,雖然這個殼層是 POSIX 殼層的分支,但並未提供一般 Unix 殼層的所有功能。特別是使用者會發現 CTRL+C 有奇怪的怪癖,而且可能會經常發現子殼層運算式和某些更進階的 IO 重新導向或環境變數傳播有怪癖。這些錯誤功能是 Fuchsia 不是 POSIX 系統的副作用。

儘管如此,透過 fx shell 提供的殼層對於在 Fuchsia 目標上強制執行程式,以及探索檔案系統樹狀結構中提供的部分診斷 / 偵錯介面 (例如 /hub/dev) 來說,都非常實用。這項功能也適用於叫用 /bin/run 等程式,方便啟動 Fuchsia 元件。如果建構設定中提供 tools 組合,許多常見的 Unix Shell 環境工具都已完成移植,可供使用,例如 pslscatcurlvimfortune 等等。

執行其他常見工作

取得記錄

fx log 會擷取低階和高階程式的所有記錄,包括核心、驅動程式和其他使用者空間程式。fx log 取決於可正常運作的高階網路堆疊和 SSH。因此,fx log 不適用於 Zedboot 或「啟動」產品設定。如果裝置處於 fx log 停止運作的狀態,通常切換至 fx klog 有助於擷取可能原因的相關資訊。

fx klog 只會擷取名為「klog」的低階記錄串流。klog 串流包含 Zircon 核心本身的記錄,以及使用者空間軟體的子集 (最明顯的是驅動程式和低階核心軟體)。fx klog 依賴名為 netsvc 的輕量型網路堆疊,即使高階軟體發生問題,這個堆疊仍可繼續運作。此外,netsvc 套件一律適用於「啟動」產品設定,因此在處理 Zircon 核心或驅動程式等低階軟體時,fx klog 最為實用。

詳情請參閱「查看記錄」。

複製檔案

fx cp 提供 scp 的基本包裝函式,類似於 fx shellssh 的包裝函式。

# copy ./book.txt from the host, to /tmp/book.txt on the target
$ fx cp book.txt /tmp/book.txt
# copy /tmp/poem.txt on the target to poem.txt on the host
$ fx cp --to-host /tmp/poem.txt poem.txt

使用多部 Fuchsia 裝置

部分使用者會在網路上擁有多部 Fuchsia 裝置,並希望將各種指令的效果限制在特定裝置上。fx set-device 指令可協助處理這個用途。

fx set-device 指令會將特定裝置節點名稱繫結至特定建構目錄。如果使用者想在多個建構設定中保留多部不同的裝置,這項功能就特別實用,設定方式如下:

$ fx --dir out/workbench set workbench_eng.x64
$ fx build
$ fx set-device <workbench-node-name>

$ fx --dir out/core set core.arm64
$ fx build
$ fx set-device <core-node-name>

# Start a server for the workbench:
$ fx --dir=out/workbench serve
# Set the default build-dir and target device to the arm64 core, and
# connect to a shell on that device:
$ fx use out/core
$ fx shell

此外,如果使用者想從目前的預設建構目錄對單一 Fuchsia 裝置執行指令,可以透過 fx 全域標記 -d 覆寫單一指令叫用的目標節點名稱。

重新啟動裝置

fx reboot

在部分裝置上 (目前大多為 arm64 裝置),還有一些實用標記:

  • fx reboot -r 重新啟動進入「復原」模式 (Zedboot)
  • fx reboot -b 重新啟動進入「開機載入程式」(Flash)

判斷 CL 的狀態

您可以使用 fx cl 指令,透過新的瀏覽器分頁在 Gerrit 中開啟目前的 CL。

偵錯及開發 fx 指令

  • fx -x -x 旗標會開啟 fx 指令碼的追蹤功能,並列印在 fx 呼叫期間評估的所有運算式。
  • fx exec 會在目前的 fx 環境中執行後續的任意程式。舉例來說,fx exec env 會列印該環境中的所有環境變數 (fx exec env | grep FUCHSIA 可能會很有用)。

取得「fx」相關協助

fx help <command> 提供該指令的最佳入門說明文件。部分指令也支援並提供 fx <command> -hfx <command> --help,但並非所有指令都提供這項說明。 這種情況並不常見,但會受到實作詳細資料影響。在內部,許多 fx 指令只會執行其他程式 (通常是建構作業產生的程式),且標記在許多情況下會原封不動地傳遞至這些程式。在這些情況下,傳遞一般的 -h--help 標記可能無法提供 fx <command> 的文件,而是提供 fx 下游所叫用程式的文件。

使用者一律應從 fx help <command> 開始。

fx help (不含其他引數) 會提供 fx 中所有可用指令的清單,以及 fx 全域標記的說明文件。

顯示待處理的提交

fx pending-commits 會顯示尚未推出至全球整合的提交內容。

如要查看 Fuchsia 的整合資訊主頁,請參閱「建構者」。

將 Fuchsia 結帳作業同步至發布分支

如要將本機 Fuchsia 結帳作業同步至特定發布分支,請執行下列指令:

fx sync-to RELEASE_BRANCH

RELEASE_BRANCH 替換為要切換到的發布分支 (例如 refs/heads/releases/f6)。如要查看所有可用的發布分支清單,請參閱 Fuchsia 全域整合存放區頁面的「分支」一節。

以下指令範例會將 Fuchsia 結帳作業同步至 F6 發布分支:

fx sync-to refs/heads/releases/f6

如要將 Fuchsia 結帳作業重設為樹狀結構頂端,請執行下列指令:

fx sync-to reset

如需更多選項,請參閱 fx sync-to 參考資料頁面。

定義持續性本機建構引數

如要定義在執行 fx set 時一併納入的建構引數,請將這些引數新增至 $FUCHSIA_DIR/local/args.gn。重新產生建構引數時,這些引數會附加至 $FUCHSIA_BUILD_DIR/args.gn

如要禁止加入 local/args.gn,請執行 fx set ... --skip-local-args