Fuchsia 构建系统使用许多“清单”文件,这些文件指示如何将文件安装到容器中,例如将文件复制到 Fuchsia 软件包 归档中,或复制到 ZBI 文件的启动文件系统映像中。
本页介绍了在构建过程中使用的这些文件格式,这些格式不应在构建过程之外公开。
请注意,生成和处理这些文件的脚本和 .gni 文件位于 Fuchsia 源代码树中的 //build/dist/ 下。
FINI(Fuchsia INI)清单文件格式
FINI 清单格式由构建期间调用的多个工具使用:生成 Fuchsia 软件包归档的
ffx package build 命令或生成 ZBI 映像的 zbi 工具。
语法非常简单:每行文本看起来像 <destination>=<source>,
其中 <destination> 是相对于最终容器顶部的目标文件路径,而 <source> 是相对于当前目录(在大多数情况下是构建目录)的源内容的文件路径。
请注意,目标路径绝不应以目录分隔符开头,并且 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 文件,其中包含对象“条目”的列表。
有几种类型的条目用于描述构建和安装要求的各个方面。它们都会合并到 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"
},
复制条目。
这些条目用于指示构建过程将特定文件复制到了新的输出位置。此信息稍后用于正确处理重命名的条目(见下文),否则会被忽略。其架构为:
copy_from:相对于构建目录的源路径字符串(必需)。copy_to:相对于构建目录的目标路径字符串(必需)。label:指向生成此条目的目标的 GN 标签(可选)。
例如,以下条目用于指示使用 ${BUILD_DIR}/x64-asan/foo 中的“asan”build 变体构建的“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/cp、bin/cat 和 bin/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/busybox 和 bin/cp 都安装到容器中。
文件条目
这些条目用于包含其他分发清单文件,这些文件可能由不同的目标生成。其架构为:
file:指向另一个分发清单文件的文件路径字符串(必需)。label:默认 GN 标签,如果包含的文件中的所有条目都没有自己的label值,则将应用于这些条目(可选)。
分发文件包含可以是递归的。
示例:
{
"file": "path/to/other.dist_manifest",
"label": "//some/dir:label"
}
清单文件中的重复条目
由于 Fuchsia 构建的工作方式,清单文件(任何
格式)可能会提供多个使用相同 <destination>路径的条目。但是,只要源路径或其内容相同,这都是有效的;在这种情况下,重复项将被忽略。
如果多个条目具有相同的目标路径,但源路径和内容不同,则处理脚本会将这种情况视为构建错误。
复制条目和重命名条目之间的交互
为了阐明复制条目和重命名条目之间的交互方式,请考虑使用给定的 renamed_binary() 目标来重命名 foo
二进制文件的安装位置的示例。
如果未选择任何构建变体,则相应的构建清单将包含两个如下所示的条目:
{
"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 工具链 (//build/toolchain:x64-asan)
中的 //src:foo 目标构建,并且仍默认安装到 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)",
},
仅当启用了构建变体时,才会使用复制条目,它们会将重命名的条目与特定于变体的常规条目相关联。之所以将所有这些信息分散开来,是因为每个条目都是通过构建图中的不同目标生成的,并且在 GN 生成传递期间无法将所有内容关联在一起。