為何要遷移
新的 FHO 子工具程式庫提供了一些實用的巨集,方便您將現有外掛程式遷移至新的子工具介面。將外掛程式遷移至子工具能享有以下好處:
- 針對錯誤提供更明確的介面邊界。
- 型別安全機器 writer 輸出,最終結構定義驗證。
- 子工具從沙發和
ffx
環境取得更彈性的輸入資料 (請參閱上方連結的 FHO 文件)。 - 魔術效果更少,
- 與
ffx
本身分開建構時的建構時間加快。
請注意,當您要啟動新的子工具時,可以略過舊版外掛程式系統涉及的許多步驟,因此請改為按照入門操作說明進行。
非遞迴外掛程式
沒有子外掛程式且 ffx_plugin()
動作中沒有 plugin_deps
區段的外掛程式相對容易遷移。遷移具有子外掛程式的外掛程式會視為單獨的工作。
下列操作說明主要取決於最初編寫的 ffx daemon echo
外掛程式與 ffx echo
子工具 (用於開發新子工具介面的概念驗證) 之間的差異。
遷移 Rust lib.rs
:
假設有一個外掛程式 lib.rs
檔案,看起來如下:
use anyhow::Result;
use ffx_core::ffx_plugin;
use ffx_echo_args::EchoCommand;
use ffx_writer::Writer;
use fidl_fuchsia_developer_ffx::EchoProxy;
#[ffx_plugin(EchoProxy = "daemon::protocol")]
pub async fn echo(echo_proxy: EchoProxy, cmd: EchoCommand, #[ffx(machine = String)] mut writer: Writer) -> Result<()> {
// implementation here
Ok(())
}
如要遷移至新外掛程式系統,最簡單的方法是移除 #[ffx_plugin]
巨集,並新增以下衍生巨集程式碼:
use fho::{FfxTool, FfxMain, MachineWriter, Result};
use ffx_echo_args::EchoCommand;
use fidl_fuchsia_developer_ffx::EchoProxy;
#[derive(FfxTool)]
pub struct EchoTool {
#[command]
cmd: EchoCommand,
#[with(fho::daemon_protocol())]
echo_proxy: ffx::EchoProxy,
}
#[async_trait(?Send)]
impl FfxMain for EchoTool {
type Writer = MachineWriter<String>;
async fn main(self, writer: MachineWriter<String>) -> Result<()> {
// implementation here
Ok(())
}
}
與先前的巨集不同的是,為 EchoTool
結構體的成員命名沒有任何限制。如果您想執行更複雜的操作,甚至可以從 FHO 衍生特徵來實作自己的載入器。
將這個結構與寫入者視為移動的物件,為 main()
函式提供移動的物件,因此您可以視需要自行解構。
另請注意,Result
類型來自 FHO,而非 anyhow
。在這個邊界內,現在有特定的錯誤類型,其中保留錯誤是否可向使用者顯示及呈現方式。如要進一步瞭解如何處理此錯誤類型,以及這類錯誤與 ffx_error
和 ffx_bail
巨集的互動方式,請參閱錯誤。
目前遷移的外掛程式大多仍須納入主要 ffx
二進位檔中,也就是說,你還需要新增下列巨集叫用,才能產生舊版外掛程式進入點:
fho::embedded_plugin!(EchoTool);
新增 main.rs
由於現在子工具可以獨立執行,因此您需要新增簡單的 main.rs
來呼叫 FHO,讓外掛程式程式庫在 ffx
叫用時正確執行:
use ffx_tool_echo::EchoTool;
use fho::FfxTool;
#[fuchsia_async::run_singlethreaded]
async fn main() {
EchoTool::execute_tool().await
}
一般來說,您不會遇到 main.rs
較為複雜。
適用於頂層外掛程式的 BUILD.gn
針對仍需與現有 ffx
外掛程式系統整合的現有外掛程式,這些外掛程式將繼續使用 ffx_plugin
GN 動作,因為會正確設定所有依附元件,並新增至 ffx
二進位檔。
如果外掛程式是 ffx
的頂層子指令,我們也會新增 ffx_tool()
動作來建構單獨編譯的外掛程式:
# Existing import for the plugin action
import("//src/developer/ffx/build/ffx_plugin.gni")
# New import for the ffx_tool action.
import("//src/developer/ffx/build/ffx_tool.gni")
ffx_plugin("ffx_echo") {
version = "0.1.0"
edition = "2021"
with_unit_tests = true
args_sources = [ "src/args.rs" ]
sources = [ "src/lib.rs" ]
deps = [ "//src/developer/ffx/fidl:fuchsia.developer.ffx_rust" ]
test_deps = [ "//src/lib/fuchsia-async" ]
}
# This will generate the executable file for your plugin.
ffx_tool("ffx_echo_tool") {
edition = "2021"
output_name = "ffx-echo"
deps = [
":ffx_echo",
"//src/developer/ffx/lib/fho:lib",
"//src/lib/fuchsia-async",
]
sources = [ "src/main.rs" ]
# To be included in the sdk in the future, add this:
sdk_category = "partner"
sdk_target_name = "ffx_echo_tool_sdk"
}
在 SDK 中新增個別的子工具建構
此時,您可以建構子工具,但不會主動建構。為此,您需要將其新增至 ffx
config.gni 的「雙模式外掛程式」清單:
# ...snip...
dual_mode_plugins = [
# ...
"//path/to/your/plugin:ffx_echo_tool",
# ...
]
# ...snip...
現在,執行 fx build ffx
應會重新建構 ffx
和外掛程式,如果您執行 ffx commands
,應該就能在「Workspace Commands」清單中看見您的指令。