FHO 子工具接口

FHO(Fuchsia 主机对象)是一组库接口,用于连接 ffx 使用子工具(无论是编译到 ffx cli 二进制文件中,还是作为单独的代码编译) build 树或 SDK 中的二进制文件。它的设计允许棘手 向前和向后兼容性,允许使用 FHO 构建的二进制文件 跨大 span 版本互相通信。

在 ffx 子工具(以 ffx 前缀运行的顶级命令)内,FHO 为 最好将其视为程序和设备之间的兼容性层, 运行 Fuchsia 的虚拟机,从而允许该工具忽略所有设置 建立 FIDL 通道,以连接到 设备,并记录有关互动的实用信息。

FHO 主机端 (ffx CLI)

在 FHO 架构中,主机二进制文件 (ffx) 负责发现 有关子工具运行环境的重要信息 这可能包括以下详细信息:

  • 用户和项目配置文件及其内容。
  • 管理活跃守护程序及其提供的服务。
  • 发现并连接到目标设备,尤其是 默认设备(如果已配置)。
  • 发现子工具在项目和/或 SDK 中的位置。
  • 发现 SDK 并验证设备、 SDK 和子工具

大多数工具都应作为外部流程构建,并可通过 SDK 或 build 输出目录,但有些仍在 ffx 二进制文件中。 这些工具不一定与单独编译的工具大相径庭, 但它们在兼容性方面存在更多限制。尽管如此, 即使没有 SDK,也能够访问某些工具。

本文档的其余部分大部分内容介绍了单独编译的子工具, 它们的发现和运行方式。

FHO 工具端

在理想情况下,基于 FHO 的子工具其实就是专为 Fuchsia,但使用 ffx 主机的上下文信息在主机上运行 提供的二进制文件,用于连接到设备上的服务。

不过,可由 ffx 运行的工具具有特殊的入口点,以允许 传达工具正常运行所需的广告投放环境信息。 他们还需要一些元数据,ffx 可以使用这些元数据来发现 验证兼容性并运行它们。

工具元数据

这些工具通常具有与其关联的 JSON 元数据文件, 如下所示:

{
  "name": "echo",
  "description": "run echo test against the daemon",
  "requires_fho": 0,
  "fho_details": {
    "FhoVersion0": {}
  }
}

此 JSON 文件用于向 ffx 以及 运行 ffx helpffx commands 时输出的信息。 上述文件为“版本 0”FHO 说明,这是 子工具界面的起点

FHO 元数据版本

FHO 版本将按顺序进行编号。任何给定的受支持版本 子工具可以根据 requires_fho 键和数字之间的范围确定 fho_details 映射中最高值条目的末尾。子工具应该 能够作为介于这两个值之间的任意版本运行。

在上面的示例中,子工具仅支持 FHO 版本 0。如果主机 工具不支持版本 0,则必须忽略该子工具的实例 取而代之的是在其他地方发现的较新版本,或者如果找不到匹配的版本 错误。

托管工具需要使用 fho_details。例如,这意味着 如果您运行了 ffx 版本,而该版本原生支持版本 3 以下元数据:

{
  "name": "echo",
  "description": "run echo test against the daemon",
  "requires_fho": 0,
  "fho_details": {
    "FhoVersion2": { "some_thing": "is_something" },
    "FhoVersion4": { "some_thing_else": "is_something_else" },
  }
}

托管工具应该会从 FhoVersion4 拉取元数据 并将该程序作为 FhoVersion3 程序运行。

这允许随时间推移对元数据进行增量更改和破坏性更改, 同时让工具本身支持众多版本 增量更改可以直接添加到当前版本的元数据字段中, 旧版本的托管工具会忽略它们,而较新版本的托管工具则会使用它们。

当需要对元数据进行破坏性更改时,完全可以创建新条目 以前的版本将继续使用旧的元数据结构。

子工具可以包含 FhoVersion0 部分, 即使 requires_fho 更高,也表示可以在 简化模式FhoVersion0 部分不应包含任何 键。

您可以在以下位置找到当前的 FHO 元数据 JSON 架构 在源代码树中

工具发现

目前,可在以下位置搜索子工具:

  • 在 FFX 二进制文件本身中。
  • 在项目特定的 build 输出位置。
  • 在已配置的 SDK 的元数据中。

基于路径的发现

如果 ffx 配置了 build 输出目录或任何其他位置 搜索子工具时,系统可能会在这些位置搜索与 以下格式:

/ffx-([-_a-zA-Z0-9]/)ffx-toolname,其中 toolname 是子命令 调用它的名称。请注意,它处理其他连字符 更深的嵌套,即ffx-some-sub-toolffx some-sub-tool 的身份运行, 而非 ffx some sub tool。子工具负责自己的嵌套命令 但 FHO 库本身可能会提供帮助程序来实现此操作。

这些文件必须附有一个同名且带有 .json 的文件 扩展名后缀。此文件将是前面部分所述的元数据, 其中的详细信息必须与正在运行的二进制文件匹配(例如,name 顶层键必须与二进制文件和元数据中的 toolname 相同 文件名)。

符合此格式但没有相应元数据文件的文件 不会被视为子工具,将被忽略。

SDK 发现

在 SDK 中,工具是通过元数据搜索发现的。通过 在 SDK 清单中搜索 atoms 类型的 ffx_tool,它指向 SDK 相对资源 元数据和可执行二进制文件的位置。

为了运行子命令,与 ffx_tool 类型匹配的 SDK 条目将为 直到找到匹配的名称。与基于路径的搜索一样,在 而不会创建更深层的命令名称嵌套。

托管工具可以将 SDK 中的主 ffx host_tool 二进制文件视为 “default”命令以遵循,如果未找到子工具,则将其作为 FHO 进行调用 版本 0(这实质上会像调用 ffx 一样调用 subtool, 一个子命令)。

工具界面

如上所述,元数据声明了 ffx 之间的版本化接口 二进制文件和正在运行的子工具这样做的目的是 会随着时间的推移而变得更有条理,但开始时相对简单, 突破当前内置在子工具中的任何预期。

子工具可以支持比它们更早的 FHO 接口版本 尤其是当某些子工具 即使在 ffx 不再支持此版本后,也需要继续实现版本 0 具体取决于它们在构建脚本等方面的用途。

FHO 版本 0

FHO 版本 0 是第一个也是最简单的 FHO 版本。仅支持 SDK 中不应包含版本 0,但 SDK 中包含的工具 额外支持版本 0。

FHO 版本 0 子工具的调用过程非常简单。它的运行方式很简单 与调用 ffx 给出的参数完全一致,包括所有参数 ffx 本身。也就是说,如果您调用:

> ffx --isolate-dir "/tmp/blah" echo stuff

您运行的 ffx 二进制文件会搜索匹配的 ffx-echo 二进制文件,并且如果 其最高通用受支持版本为零,则将其调用为:

> ffx-echo --isolate-dir "/tmp/blah" echo stuff

子工具必须支持该版本的所有已知顶级 ffx 参数 (共 ffx 个)。它还将使用环境变量运行 FFX_BIN_ENV,指向对 API 进行顶级调用的文件系统路径 ffx(但不应该覆盖它),或者可以运行 从运行子工具的同一上下文环境重新开始处理 目录。

否则,系统将为子进程提供相同的 (stdin,stdout,stderr) 三组变量和环境变量。

版本为 0 接口的原因如下:

  • 它允许在构建过程中直接调用子工具, 主要 ffx 二进制文件,从 build 的 关键路径。
  • 它不会干扰需要完整安装的现有插件 对运行它们的输入和输出环境进行控制。
  • 让此架构的第一个版本能够专注于更重要的 各个方面。