Fuchsia 构建系统使用的清单文件格式

Fuchsia 构建系统使用许多“清单”指示如何 将文件安装到容器中,例如将文件复制到 Fuchsia 软件包 归档文件中,也可以导入到启动文件系统映像 / ZBI 文件 ,了解所有最新动态。

本页记录了 build 中使用的这些文件格式, 不得在外部公开

请注意,生成和处理这些文件的脚本和 .gni 文件 位于 Fuchsia 源代码树中的 //build/dist/ 下。

FINI (Fuchsia INI) 清单文件格式

在构建过程中调用的多种工具均使用 FINI 清单格式: ffx package build 命令(或旧版 pm 工具), 生成 Fuchsia 软件包归档,或使用 zbi 工具生成 ZBI 映像。

语法非常简单:每行文本都类似于 <destination>=<source>, 其中 <destination> 是目标文件路径,相对于 最终容器,<source> 是源内容的文件路径, 到当前目录(大多数情况下即为 build 目录)。

请注意,目标路径不得以目录分隔符开头, 并且 FINI 文件不支持 Windows INI 文件格式

例如:

bin/foo=foo
lib/ld.so.1=user.libc_x64/libc.so
meta/foo.cm=obj/src/foo/cml/foo_component/foo.cm
meta/package=gen/src/foo/foo_meta_package.txt

发行版清单文件格式

这是一个 JSON 文件,必须包含一个列表,其中每一项都是一个 JSON 对象 作为单个“发行版”介绍了如何安装 并将源文件复制到容器中,并为目标提供 GN 标签 生成它。此处使用的架构为:

  • source:源路径字符串(必需)。

  • destination:目标路径字符串(必需)。

  • label:指向生成源文件的目标的 GN 标签。 仅用于调试(可选)。

示例:

  {
    "destination": "bin/foo",
    "source": "x64-asan/foo",
    "label": "//some/dir:foo"
  }

虽然在概念上与 FINI 清单类似,但发行版分发 清单会提供更多信息(GN 标签),这非常重要 在出现问题时用于调试它们也被另一组 工具。

部分分发清单文件格式

FINI分发清单 通过处理称为“部分分发清单”的中间文件来生成。

部分清单由 GN 元数据收集针对目标生成 都在同一个依赖项树中这是一个 JSON 文件,其中包含一系列 对象“entries”。

有几种类型的条目用于说明 构建和安装要求它们会合并到 FINI 或分发清单。

//build/dist/distribution_manifest.py 中的 Python 模块包含 用于处理这些文件的函数。

常规条目

这些条目与分发清单所用的架构匹配。他们 对应于要安装到指定目标的简单源文件 路径。

  • source:源路径字符串(必需)。

  • destination:目标路径字符串(必需)。

  • label:指向生成源文件的目标的 GN 标签。 仅用于调试(可选)。

  • elf_runtime_dir:仅用于 ELF 可执行文件和可加载模块, 可选的目标目录路径,用于指定 二进制文件的 ELF 依赖项应在运行时。 默认值为“lib”

用于生成发行版清单时,它们按原样复制, 没有 elf_runtime_dir 键插入输出文件,除非有 满足以下条件之一:

  • 它们与另一个常规条目的来源相同(请参阅 此部分了解详情),在此仅提供 系统会保留其中一个条目

  • 其源路径会被重命名的条目使用(请参阅下文)。

示例:

  {
    "destination": "bin/foo",
    "source": "x64-asan/foo",
    "label": "//some/dir:foo",
    "elf_runtime_dir": "lib/asan"
  },

复制条目。

这些条目用于指明相应 build 将特定文件 新的输出位置。此信息稍后会用于处理重命名 (见下文),否则会被忽略。其架构为:

  • copy_from:相对于 build 目录的源路径字符串 (必需)。

  • copy_to:相对于 build 目录的目标路径字符串 (必需)。

  • label:指向生成此条目的目标的 GN 标签 (可选)。

例如,以下条目用于表示“foo” 使用“asan”构建的可执行二进制文件build 变体 ${BUILD_DIR}/x64-asan/foo 也已复制到 ${BUILD_DIR}/foo

示例:

  {
    "copy_from": "x64-asan/foo",
    "copy_to": "foo"
    "label": "//some/dir:foo"
  }

请参阅下文,了解复制条目和重命名条目的交互方式。 真实示例。

重命名的条目

这些条目用于表示某个给定的常规条目应 安装在其他目标位置。对于 这些程序(例如 busybox)的行为会有所不同,具体取决于 以及用于启动应用的程序名称renamed_binary() GN 模板依赖于 。其架构为:

  • destination:目标路径字符串(必需)。

  • renamed_source:与另一个常规条目匹配的源路径 (必需)。

  • label:指向生成此条目的目标的 GB 标签 (可选)。

  • keep_original:一个布尔值标志,如果设置为 true,则表示原始 重命名的二进制文件仍应安装在容器中(可选)。

请注意,重命名条目只能指向常规source 条目或者复制到副本条目的 copy_to 路径下。使用未知路径,或 另一个重命名条目的目标路径出现构建错误。

您可以多次重命名相同的条目。当 相同的原始二进制文件需要以不同名称多次安装。

以下示例将 busybox 二进制文件安装为 bin/cpbin/catbin/ls 位于同一容器中。请注意,bin/busybox 将 但不会安装到容器中。

  {
    "destination": "bin/busybox",
    "source": "busybox",
    "label": "//third_party/busybox:busybox"
  },
  {
    "destination": "bin/cp",
    "renamed_from": "busybox"
  },
  {
    "destination": "bin/cat",
    "renamed_from": "busybox"
  },
  {
    "destination": "bin/ls",
    "renamed_from": "busybox"
  }

如果任何重命名条目将 keep_original 标志设置为 true,则原始条目 不会从清单中移除,而是保留原始二进制文件,如下所示:

  {
    "destination": "bin/busybox",
    "source": "busybox",
    "label": "//third_party/busybox:busybox"
  },
  {
    "destination": "bin/cp",
    "renamed_from": "busybox",
    "keep_original": true
  }

这将确保 bin/busyboxbin/cp 均已安装到 容器。

文件条目

这些条目用于包含其他分发清单文件 可能由其他目标生成其架构为:

  • file:指向其他分发清单的文件路径字符串 文件(必需)。

  • label:将应用于 包含的文件,前提是它们没有自己的 label 值(可选)。

发行版文件包含的内容可以是递归的。

示例:

  {
    "file": "path/to/other.dist_manifest",
    "label": "//some/dir:label"
  }

清单文件中的重复条目

根据 Fuchsia 构建的工作原理,清单文件(任何 格式),以提供使用同一 <destination> 路径的多个条目。这是 但前提是源路径或其内容相同;其中 忽略大小写重复内容。

多个条目具有相同的目标路径,但不同的情况 脚本。

副本与重命名的条目之间的交互

为了说明复制条目和重命名条目的交互方式, renamed_binary() 目标,用于重命名 foo 二进制文件的安装位置。 如果未选择任何 build 变体,对应的 build 清单将包含 如下所示的两个条目:

  {
    "destination": "bin/foo",
    "source": "foo",
    "label": "//src:foo",
  },
  {
    "destination": "bin/foo_renamed",
    "renamed_from": "foo",
  },

第一个常规条目表明 ${BUILD_DIR}/foo 是由 默认工具链中的 //src:foo 目标,并且应安装到 容器内部的 bin/foo

第二个复制条目会指示以 ${BUILD_DIR}/foo 形式构建的二进制文件应该 实际上会安装到 bin/foo_renamed,而不是其默认位置 (即 bin/foo)。

从逻辑上讲,这等同于单个条目:

  {
    "destination": "bin/foo_renamed",
    "source": "foo",
    "label": "//src/foo",
  },

例如,第一个条目,其中只更改了目标路径。

不过,在使用 asan 变体构建相同内容时,已启用, 清单内容将与之前略有不同:

  {
    "destination": "bin/foo",
    "source": "x64-asan/foo",
    "label": "//src:foo(//build/toolchain:x64-asan)",
  },
  {
    "copy_from": "x64-asan/foo",
    "copy_to": "foo",
  },
  {
    "destination": "bin/foo_renamed",
    "renamed_from": "foo",
  },

现在,第一个条目表明 ${BUILD_DIR}/x64-asan/foo 已构建 由 asan 工具链中的 //src:foo 目标 (//build/toolchain:x64-asan) 执行, 并且默认仍会安装在 bin/foo 中。

第二个条目表明 ${BUILD_DIR}/foo${BUILD_DIR}/x64-asan/foo,因为这是构建系统执行的操作。

第三个条目与之前相同,因为 renamed_binary() 目标 完全不知道使用哪个工具链或变体进行构建 ${BUILD_DIR}/foo

这在逻辑上等同于如下所示的单个条目:

  {
    "destination": "bin/foo_renamed",
    "source": "x64-shared/foo",
    "label": "//src/foo(//build/toolchain:x64-asan)",
  },

复制条目仅在 build 变体已启用时使用,它们会关联重命名 将条目替换为特定于变体的常规条目。为什么这些 每个条目都是通过不同的 目标,并且无法将所有内容关联在一起 在 GN 生成传递期间进行。