fx 工作流程

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

設定 fx

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

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

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

    cd ~/Fuchsia
  2. 在 Shell 中新增設定,以便納入 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 是什麼?

設定最終會指定相依項 (大多是套件),這些相依項會影響建構作業的輸出構件 (大多是映像檔和套件存放區)。建構作業會加入參數,以決定要將哪些依附元件 (大多是套件) 新增至哪些輸出成果 (映像檔或套件存放區)。這三個軸分別稱為「base」、「cache」和「universe」:

  • Base:新增至 base 的套件會納入版本產生的系統映像檔。這些檔案會納入無線下載更新,且一律以單一單位更新。在執行階段,您無法從裝置中移除基礎包,因為這些包會編碼設定的可能最小大小。
  • 快取:快取中的套件會納入系統映像檔,但不會納入無線系統更新,且可根據資源需求 (例如磁碟空間壓力) 從系統中移除。您隨時可以更新快取中的套件,且每個套件都可以獨立更新。這是「選用」軟體,但建議一開始就安裝。
  • Universe:Universe 中的套件是可供隨選的額外套件,可隨需求擷取及執行,但不會預先編譯至任何系統映像檔。

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

主要產品設定

除了下列設定之外,還有許多其他設定,但您必須熟悉下列三個特別重要的設定:

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

其他重要建構目標

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

  • //bundles/tools 包含多種最常見的開發人員工具。其中包括從指令列殼層產生元件的工具、用於重新設定及測試網路的工具、發出 HTTP 要求、偵錯程式、變更音量等。核心產品會根據預設在 Universe 套件中加入 //bundles/tools
  • //bundles/tests 會導致所有測試程式建構。大多數測試程式都可以使用裝置上的 run-test-suitefx test 叫用。
  • //bundles/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 set --auto-dir。在這個模式中,fx set 會為不同的設定選擇不同的輸出目錄。請注意,這會增加磁碟用量,您可能需要刪除不再需要的舊輸出目錄。

啟用增量套件重建功能

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

您可以將 export FUCHSIA_DISABLED_incremental=0 新增至 ~/.bashrc 或等效項目,啟用增量重建功能。這項變更會導致以下結果:

  • (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 會定義 Ninja 別名,其外觀與 GN 標籤相似,但沒有 // 開頭前置字串,因此 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 建構。

如要進一步瞭解建構目標,請參閱建構系統總覽

產生建構封存檔案

除了執行建構作業,您也可以使用 fx build 指令產生建構封存檔案 (即 .tar.tgz.zip)。這個建構封存檔案包含 fx build 產生的建構構件特定組合,可讓建構輸出內容可用於各種用途。舉例來說,您可以將這個建構封存檔案做為 ffx target flash 指令的輸入內容,將建構內容閃燈至 Fuchsia 裝置。

如要產生建構封存檔案,請使用下列特殊目標執行 fx build

fx build build-archive.FORMAT

FORMAT 替換為 tartgzzip,例如:

fx build build-archive.zip

建構作業完成後,這個指令會在 Fuchsia 建構目錄中建立建構封存檔案 (上例中的 build-archive.zip),該目錄預設為 out/default。(如要查看建構目錄的確切位置,請執行 fx get-build-dir)。

建立產品組合 ZIP 檔案

如果您已建構 Fuchsia 產品 (透過執行 fx build),可以執行下列指令,建立包含產品套件的 ZIP 檔案

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

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

準備 Zedboot USB 隨身碟

將 Fuchsia 刷入目標裝置時,所需的確切準備作業會因特定裝置而異,但您可以使用 fx mkzedboot 為啟動至 Zedboot 的 x64 裝置準備可啟動的 USB 驅動程式。

什麼是 Zedboot?

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

如要在 arm64 目標上進入 Zedboot,請開啟裝置,並觸發啟動進入快速啟動閃爍模式 (通常需要在重新啟動或開機時按住特定按鈕,這取決於特定硬體目標)。進入閃電模式後,請在主機系統上執行 fx flash

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

什麼是網路啟動?

在 Fuchsia 中,「netboot」是指將一組構件傳送至 Zedboot 例項,而非變更磁碟,這樣系統就會從 RAM 啟動。使用者可以執行「netboot」,方法是先使用 fx flash (arm64) 或 fx mkzedboot (x64) 將裝置啟動至 Zedboot,然後在主機系統上執行 fx netboot

提供版本

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

fx serve 指令會在內部執行兩項功能:

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

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

更新目標裝置

如先前各節所述,Fuchsia 裝置上有不同的軟體群組:

  • 核心系統「基礎」的一部分,會在單一交易中更新。
  • 除了可暫時更新的基礎 (快取) 之外,Zedboot 映像檔的其他軟體。
  • 永遠是暫時性質的軟體 (universe)。

針對新使用者開發工作流程,協助更新目標裝置的最常見指令是 fx otafx 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

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

連線至目標殼層

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

不過,透過 fx shell 提供的殼層對於在 Fuchsia 目標上強制執行程式,以及探索檔案系統樹狀結構中提供的部分診斷 / 偵錯介面 (例如 /hub/dev) 來說,都非常實用。這對叫用 /bin/run 等提供啟動 Fuchsia 元件設施的程式也相當實用。如果建構設定中提供 tools 套件,許多常見的 Unix 殼層環境工具都已移植並可供使用,例如 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 重新啟動至「recovery」(Zedboot)
  • fx reboot -b 重新啟動至「bootloader」(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 的 CheckOut 同步至發布分支

如要將本機 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