本文說明在 Fuchsia 開發環境中使用 fx 工具的基本工作流程。
設定 fx
fx 是一組子指令的進入點,可簡化許多與 Fuchsia 開發相關的工作。(執行 fx help 即可查看所有可用的子指令)。
如果您使用 bash 或 zsh 做為殼層,強烈建議您執行 source scripts/fx-env.sh,在殼層中啟用自動完成功能。這項設定經過測試,並經常與 bash 和 zsh 搭配使用,也可能適用於其他相容的殼層。
前往 Fuchsia 簽出,例如:
cd ~/Fuchsia在殼層中新增設定,納入
fx-env.sh:echo "source \"$PWD/scripts/fx-env.sh\"" >> "$HOME/.$(basename "$SHELL")rc"(選用) 如果您想使用 Fuchsia 指令碼提供的其他便利工具,請執行:
echo "fx-update-path" >> "$HOME/.$(basename "$SHELL")rc"重新啟動殼層:
exec "$SHELL"
這些步驟可提供最明確的特徵集,而且通常不會造成侵入性。如果殼層環境發生錯誤,請回報專案錯誤。
如果基於某些原因,您需要使用多個 Fuchsia 檢出 (建議的工作流程應可避免這種需求),則可能需要執行上述以外的操作。在這種情況下,有幾種方法可以提供良好支援:
- 一律明確執行
$FUCHSIA_DIR/scripts/fx - 在特定 Fuchsia 目錄中工作時,請使用 direnv 或 dotenv 等工具,將
$FUCHSIA_DIR/.jiri_root/bin新增至$PATH。
常用工具
簽出 Fuchsia 樹狀結構後,首先要建構 Fuchsia,然後將其安裝到裝置上。fx 提供一些指令,可協助您完成這項操作:
fx set設定建構作業fx build執行建構作業fx mkzedboot準備 Zedboot USB 隨身碟fx serve提供版本fx publish cache疊代快取套件fx ota更新目標fx test執行測試fx shell連線至目標殼層- 以及許多其他小工作
目標、主機和端對端情境
Fuchsia 開發作業涉及編譯及執行不同環境的程式碼:
- 目標:Fuchsia 裝置或模擬器 (例如 x64 或 arm64 Fuchsia)。
- 主機:開發工作站 (Linux)。
fx build
fx build(預設):建構要在 Fuchsia 目標上執行的構件 (驅動程式、元件、指令列工具)。fx build --host:建構要在開發主機上執行的工具或測試 (例如fidlc編譯器、zxdb偵錯工具、主機端單元測試、端對端測試)。- 何時使用
--host:在開發人員工具、主機端測試,或需要建構主機二進位檔,但不需要建構整個 Fuchsia 系統映像檔時,請使用這個指令。
fx test
fx test(預設):執行所選測試。系統會自動偵測測試是主機測試還是裝置測試,並在適當的環境中執行。fx test --host:篩選選取項目,只執行主機測試 (在工作站上執行)。fx test --device:篩選選取項目,只執行裝置測試 (在 Fuchsia 裝置/模擬器上執行)。fx test --e2e:可執行端對端測試。這些測試會在主機上執行,但會與 Fuchsia 裝置互動,測試系統層級的行為。這類測試通常不會納入預設測試執行作業,因為需要連結裝置,且可能速度緩慢或造成沉重負載。
設定建構作業
首先,請設定建構作業。為此,您需要做出幾項選擇:
- 您想使用哪種產品設定?(不確定:請試試
workbench_eng) - 您要為哪個主機板建構?(不確定:請試試
x64) - 您需要哪些額外的建構目標?(例如:
--with-test //my/team:tests)
根據上述選擇 (如果您尚未閱讀上述內容,請立即閱讀),您已準備好設定建構作業:
fx set workbench_eng.x64 --with-test //my/team:tests在結帳頁面執行 fx set 後,除非需要修改後續引數,否則不必再次執行。
如要在建構設定中新增更多測試,而不執行 fx set,可以使用下列指令:
fx add-test <label>:附加目標端測試標籤 (新增至developer_test_labels)。fx add-host-test <label>:附加符合主機工具鍊資格的主機端測試標籤 (新增至host_test_labels)。
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提供特定板。另請注意,一般arm64主機板設定不支援在模擬器中執行,您必須改用qemu-arm64。執行fx list-boards即可查看已知主機板設定清單。 - 您正在建構
tests,做為universe套件組合的一部分,但這項作業不會永久生效。
套件部署選項
--with 選項有三種變體,與套件部署至 Fuchsia 裝置的方式有關:--with-base、--with-cache 和 --with (表示 universe)。
除了這些部署軸之外,fx set 還提供特定情境的標記:
--with-host:新增在開發主機上執行的工具或測試 (例如zxdb)。這些工具或測試不會部署到 Fuchsia 裝置。請參閱「HostContext」。--with-test:在建構作業中加入特定測試 (例如//my/team:tests)。這些測試會視需要暫時提供。
那麼,base、cache 和 universe 是什麼?
設定最終會指定依附元件 (主要是套件),這些依附元件會影響建構作業的輸出構件 (主要是映像檔和套件存放區)。建構作業會參數化,以判斷哪些依附元件 (主要是套件) 會新增至哪些輸出構件 (映像檔或套件存放區)。這三個軸分別稱為「base」、「cache」和「universe」:
- Base:新增至 Base 的套件會包含在建構作業產生的系統映像檔中。這些元件包含在無線更新中,且一律會以單一單元的形式更新。基本套件在執行階段無法從裝置中移除,因為這類套件會編碼設定的最小可能大小。
- 快取:快取中的套件會包含在系統映像檔中,但不會包含在無線系統更新中,且允許在資源需求 (例如磁碟空間壓力) 時從系統中移除。只要有可用的更新,快取中的套件隨時可以更新,而且每個套件都可以獨立更新。這類軟體是「選用」性質,但最好能立即「現成」使用。
- Universe:Universe 中的套件是額外的選用套件,可隨選擷取及執行,但不會預先內建在任何系統映像檔中。
「board」和「產品」設定會為每個套件組合挑選一組預先定義的成員。最常見的情況是,主機板設定會指定一組要新增至基本依附元件組的重要啟動驅動程式,例如在快取組中加入一些選用但常見的周邊裝置驅動程式。板設定也可能包含一些板專屬開發人員工具 (通常是主機工具,而非目標套件),用於與「universe」中的板互動。產品設定會根據所代表產品的定義和特徵集,選擇在基礎、快取或通用套件集中新增或減少軟體。舉例來說,喇叭產品會在基礎上新增許多音訊媒體相關套件。工作台產品會在基礎上新增各種 GUI、媒體和許多其他套件。
主要產品設定
除了以下三項,還有許多其他設定,但請務必熟悉這三項特別重要的設定:
bringup是功能最精簡的產品,著重於簡單和精實。其存在是為了提供快速建構和小型映像檔 (主要用於 netboot,而非時尚),非常適合用於非常低階的設施,例如 Zircon 核心或主機板專屬驅動程式和設定。它缺乏大部分網路功能,因此無法在執行階段新增軟體或自行升級。這也表示部分fx指令 (例如fx serve和fx shell) 無法與bringup產品搭配使用。core是最小功能集,可安裝其他軟體 (例如新增至「universe」依附元件集的項目)。所有高階產品設定都從這裡開始。具備常見的網路功能,並可透過無線更新系統。workbench_eng是通用開發環境的基礎,適合用於開發 UI、媒體和許多其他高階功能。這也是愛好者玩樂和探索的最佳環境。
主要額外建構目標
fx set 的 --with 和 --with-test 旗標會採用任意建構目標。為方便起見,我們定義了多個套件,其中包含各種常用的建構目標。請務必熟悉下列套件:
//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 會定義 Ninja 別名,看起來像 GN 標籤,但沒有開頭的 // 前置字元,因此 fx build examples/hello_world:hello_world 會在預設工具鍊中建構 GN 目標 //examples/hello_world 的輸出。
不過,如果目標是在非預設工具鍊中宣告,您就必須猜測 Ninja 輸出路徑,這通常非常棘手。不過,主機二進位檔通常位於 host_x64 子目錄下。因此,如果該目標僅定義為 executable(),則可以使用 fx build host_x64/blah 建構 //foo/bar:blah(//build/toolchain:host_x64)。
如要進一步瞭解建構目標,請參閱建構系統總覽。
建立產品組合 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。不過,您可以使用 --bucket (或 -b) 旗標指定其他 GCS bucket:
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 mkzedboot 為 x64 裝置準備可啟動的 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 中選取「Boot from USB」。
什麼是網路啟動?
在 Fuchsia 中,「netboot」是指將一組構件傳送至 Zedboot 執行個體,該執行個體不會變更磁碟,而是直接從 RAM 啟動。使用者可以先使用 fx flash (arm64) 或 fx mkzedboot (x64) 將裝置啟動至 Zedboot,然後在主機系統上執行 fx netboot,藉此執行「網路啟動」。
提供版本
Fuchsia 的許多建構設定都包含軟體,這些軟體不會立即包含在建構作業產生的基本映像檔中,而是在刷寫期間寫入裝置。這類軟體會隨選提供給目標裝置,通常稱為「臨時軟體」。
fx serve 指令會在內部執行兩項功能:
- 啟動套件 Repository 伺服器,用於在執行階段動態安裝軟體,以及更新整個系統。
在內部,fx serve 指令也會搜尋要設定的裝置,並在發現裝置後 (可能會受到 fx set-device 或 fx -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 旗標設為 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 殼層環境常見的工具都已移植並可供使用,例如 ps、ls、cat、curl、vim 等。
執行其他常見工作
取得記錄
fx log 會擷取低階和高階程式的所有記錄,包括核心、驅動程式和其他使用者空間程式。fx log
仰賴運作中的高階網路堆疊和 SSH。因此,fx log 不適用於 Zedboot 或「啟動」產品設定。如果裝置處於 fx log 停止運作的狀態,通常可以切換至 fx klog,擷取更多可能原因的相關資訊。
fx klog 只會擷取名為「klog」的低層級記錄串流。klog 串流包含 Zircon 核心本身的記錄,以及使用者空間軟體的子集 (最主要是驅動程式和低階核心軟體)。fx klog 依賴名為 netsvc 的輕量網路堆疊,即使高階軟體發生問題,該堆疊仍會保持可用狀態。netsvc 套件也一律可在「啟動」產品設定中使用,因此 fx klog 在處理 Zircon 核心或驅動程式等低階軟體時最實用。
詳情請參閱「查看記錄」。
複製檔案
fx cp 提供 scp 的基本包裝函式,類似於 fx shell 是 ssh 的包裝函式。
# 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.qemu-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重新啟動並進入「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> -h 或 fx <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。