1. 主页
  2. 文档
  3. Fuchsia OS 简体中文文档 2021...
  4. 概念
  5. 构建系统
  6. Fuchsia 构建系统:变体

Fuchsia 构建系统:变体


Fuchsia GN 构建体系允许独立组件(component)以不同“变体”(variant)构建。一个变体通常仅意味着使用额外编译器选项,但如果您编写更多的 GN 代码,您会发现它们的功效不止于此。目前为止定义的变体启用了诸如 sanitizerLT0 的功能。

GN 构建参数 select_variant 控制在哪些变量中构建哪些组件。它会自动应用于 GN 文件中的每个 executableloadable_moduledriver_module 目标。这是一种灵活的机制,您可以在其中提供一系列匹配的规则来应用于每个目标,以决定要使用哪个变体(若有)。为了支持这种灵活性,select_variant 的值使用了详细的 GN 语法。 对于简单情况,它可以仅是一个字符串列表。

使用fx set

fx set core.x64 --variant=host_asan --variant=asan/cat --variant=asan/ledger

或者,您可以通过编辑 GN 参数对现存构建进行添加或修改(按需将您的构建的 GN 输出目录替换为 out/default)。

gn args out/default

该命令将打开编辑器。向文件尾添加:

select_variant = [ "host_asan", "asan/cat", "asan/ledger" ]

  1. 第一个开关(switch)应用 host_asan 匹配规则,该规则对所有为在构建主机上运行而构建的可执行文件启用 AddressSanitizer

  2. 第二个开关应用 asan 匹配规则,该规则对 为在目标设备(即 Fuchsia 设备)上运行而构建的可执行文件启用 AddressSanitizer。/cat 后缀将此匹配规则仅限制在名为 cat 的二进制文件上。

  3. 第三个开关与第二个相同,但匹配名为 ledger 的二进制文件。

GN 代码不仅支持二进制名称,还支持更加灵活的匹配规则,但是这些规则没有简写形式。参阅 select_variant 构建参数文档以获取更多信息。

要查看可用的变体列表,了解有关如何定义新变体的更多信息,请参阅 known_variants 构建参数。

故障排除说明

复制 ASan 故障

我们的记录队列(commit queue)在启用 ASan 的配置中运行测试。要在该配置中复制该构建,请使用下面的 args.gn 文件:

import("//boards/<x64-or-arm64>.gni")
import("//products/core.gni")

base_package_labels+=[ "//bundles/buildbot:core" ]
goma_dir="<path-to-goma-dir>"
is_debug=true
select_variant=["asan","host_asan"]
target_cpu="<x64-or-arm64>"
use_goma=true

x64-or-arm64 替换为您所希望的目标架构,并将 <path-to-goma-dir> 替换为您的 goma 文件夹(对于使用 goma 的用户)。这也可以通过命令行生成:

fx set core.x64 --with-base //bundles/buildbot:core --variant host_asan --variant asan --goma

注意,这将会构建由记录队列运行的所有测试,并将它们安装在系统镜像中。出于以下两个原因,这可能是令人讨厌的:

  • 构建所有测试经常又慢又没有必要。开发者可能会发现将包(package)标签限制到他们所需的测试会更加有效。
  • 提前将所有的测试安装在系统镜像中意味着软件部署工作流未实施。

从启用 ASan 的二进制文件中启动可执行文件

您如果正试图使用 ASan 变体,则可能遇到类似这样的错误:

launcher: error: Launch: elf_load: handle_interp failed
dlsvc: could not open 'asan/ld.so.1'

Fuchsia 是围绕包和组件构造的。每一个组件包含了它运行时所需要的所有共享库。这帮助 Fuchsia 规避了困扰了其他操作系统的库版本控制问题。这也意味着,如果您想从一个组件中运行一个二进制文件,您必须为该二进制文件提供正确的共享库加载器。

在 Fuchsia 安装目录的 /boot/ 目录中有一套命令行程序,它们不包含在包中,而是包含在引导文件系统(boot filesystem)中。这些程序没有自己的共享库加载器,而将使用执行它们的组件提供的任何共享库。这通常能够运作,因为诸如 shls 的程序具有非常少、非常常见的依赖关系。但是,不能保证组件的包会有足够的或兼容的共享库以满足命令行程序的需求。启用 ASan 的包通常不包含这些程序的正确启动器,因此大多数启用 ASan 的组件无法在 /boot 之外运行可执行文件。启用了 ASan 的组件如果尝试这样做,则会得到上面的错误。

幸运的是,事实证明,其修复涉及的是所有包该做的事情,即显式地声明其依赖。如果您的包依赖于一个二进制文件,则应将其声明为依赖,然后使用这个已经声明了的依赖,而不要使用 /boot 目录中的依赖项。在我们构建系统的案例中,在 //build/config/fuchsia/zircon_images.gni 中定义的 zircon_extras_manifest 规则将允许您依赖在 /boot 目录中的任何二进制文件。它们将被安装在
/pkg/bin/,您应当从那里执行它们。

我们要如何帮助您?

Comments

Leave a reply

您的电子邮箱地址不会被公开。 必填项已用 * 标注