外部 Rust crate

Fuchsia 使用外部 Rust crate。外部 Rust crate 放置在 //third_party/rust_crates/vendor 中。这组箱基于 //third_party/rust_crates/Cargo.toml 中列出的依赖项。

一般来说,添加或更新外部箱涉及以下步骤:

  • 计算外部箱的依赖项。

  • 请求开源审核委员会 (OSRB) 批准。

  • 正在等待获得 OSRB 批准。

  • 上传更改以进行代码审核

添加外部箱

如果您找不到想要使用的现有箱,可能需要向 Fuchsia 添加外部箱。

如需添加外部箱,请执行以下操作:

  1. 切换到 Fuchsia 代码库的基本目录。

    例如,如果您的 Fuchsia 目录为 ~/fuchsia,请运行以下命令:

      cd ~/fuchsia
  2. third_party/rust_crates/Cargo.toml 中为要添加的箱添加一个条目。

  3. 运行以下命令可下载所需箱(crate) 并计算该箱的依赖项:

      fx update-rustc-third-party

    fx update-rustc-third-party 下载 rust_crates/Cargo.toml 中列出的所有箱及其依赖项,将下载的箱放置在 vendor 目录中,然后更新 Cargo.tomlCargo.lock

    对于使用 build.rs 脚本的箱,您可能需要提供额外的配置。此配置会替换脚本,而该脚本是构建系统有意不支持的。配置应放置在以下两个位置:

    • Cargo.toml 文件中的 [gn.package.<crate>] 部分,以及
    • //build/bazel/update-rustc-third-party/crate_annotations.bzl

      此配置由 cargo-gnaw(用于生成 GN 构建规则)和 crate_universe(用于生成 Bazel 构建规则)使用。如需了解详情,请参阅 cargo-gnaw 的 README

      在本地提交更改后,再次运行 fx update-rustc-third-party 并确保它成功完成,且未产生任何更改。您可以运行 git status 来确认。

  4. 运行以下命令以执行 build 测试:

      fx set core.x64 && fx build
  5. 通过以下方式请求 OSRB 批准:

    • 使用开源审核委员会 (OSRB) 模板创建问题。
    • 在问题中,执行以下操作:

      • Owner(所有者)字段留空。
        • OSRB 团队会定期开会来审核这些问题。请耐心等待大约一周,我们会尽快回复您。
      • 指定要添加的所有箱 (crate)(无需列出之前已获批准的箱)。包括您要添加的箱以及运行 fx update-rustc-third-party 后确定的依赖箱。
      • 如果源代码库中有任何文件在供应商化时未包含在内,请在向 OSRB 提交的问题中指定这些文件。例如,仅用于测试但在出售箱子时被排除的字体文件需要包含在 OSRB 问题中。
  6. 如果您获得 OSRB 批准,请将相应变更上传到 Gerrit 以供审核。 在更改中添加 OSRB 问题 ID 编号。

  7. 添加外部 Rust 箱目录的 OWNER 作为代码审核者。您必须从代码库的所有者之一处获得 Code Review Label +2

  8. 如果您有权向提交队列 (CQ) 提交已获批准的更改,请提交您的更改,以将该更改合并到 third_party/rust_crates 中。

    如果您无法提交已获批准的更改,请回复您的 Gerrit 更改,并请求某位代码库所有者提交您的更改。

    如需详细了解每种贡献者角色关联的操作,请参阅角色矩阵

更新外部 crate

如需更新外部箱,请执行以下操作:

  1. 增加了 third_party/rust_crates/Cargo.toml 中箱的补丁号

    • 对于不显示在 third_party_rust_crates/Cargo.toml 中的传递依赖项,请改用 fx host-tool cargo update --manifest-path third_party/rust_crates/Cargo.toml --package $crate_name。该命令的输出将显示 $crate_name 已更新到的版本。接下来,检查 third_party/rust_crates/BUILD.gn 中是否有 $crate_name 的引用,并相应地更新版本字符串。
  2. 运行以下命令:

      fx update-rustc-third-party

    您可能需要在 Cargo.toml 文件中的 [gn.package.<crate>] 部分更新或提供其他配置。对于使用 build.rs 脚本的箱,此配置会替换该脚本,而该脚本是构建系统有意不支持的。此配置由 cargo-gnaw 使用,后者会根据 Cargo.toml 文件生成 GN 规则。 如需了解详情,请参阅 cargo-gnaw 的 README

  3. 检查已更新箱子的版本字符串是否已在 third_party/rust_crates/BUILD.gn 中正确更新,并根据需要手动调整。

    在本地提交更改后,再次运行 fx update-rustc-third-party 并确保其成功完成,且未产生任何更改。您可以运行 git status 来确认。

  4. 运行以下命令以执行 build 测试:

      fx set core.x64 && fx build
  5. 检查更改中是否存在许可或依赖项方面的变化。如果存在此类变更,您必须完成 OSRB 审批流程。 通过以下方式请求 OSRB 批准:

    • 使用开源审核委员会 (OSRB) 模板创建问题。
    • 在问题中,执行以下操作:

      • Owner(所有者)字段留空。
        • OSRB 团队会定期开会来审核这些问题。请耐心等待大约一周,我们会尽快回复您。
      • 指定要添加的所有箱。包括您要添加的箱以及运行 fx update-rustc-third-party 后确定的依赖箱。
      • 如果源代码库中有任何文件在供应商化时未包含在内,请在向 OSRB 提交的问题中指定这些文件。例如,仅用于测试但在出售箱子时被排除的字体文件需要包含在 OSRB 问题中。
  6. 更新已修改箱子的 OWNERS 文件。如需详细了解如何更新 OWNERS 文件,请参阅 OWNERS 文件部分。

  7. 如果您收到 OSRB 批准,请将相应变更上传到 Gerrit 以供审核。在更改中添加 OSRB 问题 ID 编号。

  8. 如果没有许可或依赖项变更,您可以上传变更以供审核,而无需经过 OSRB 审批流程。

添加新镜像

当积极向上游代码库贡献代码或维护 Fuchsia 代码库的长期分支时,使用完整的 Git 代码库(而非 Cargo 的供应商工具)导入 crate 会很有用。虽然此方法很有用,但与默认流程相比,开销很大,因此应谨慎使用。

  1. fuchsia.googlesource.com 上请求添加镜像。
  2. 将镜像添加到 Rust 运行时的 Jiri 清单
  3. 向工作区添加 crate 的补丁部分。
  4. 运行更新脚本。

导入箱中的部分文件

在某些情况下,您可能只想导入箱中的部分文件。例如,外部代码库中可能存在与 Fuchsia 的许可要求不兼容的可选许可。下面是一个出现此情况的 OSRB 审核示例

为此,您需要将箱子的文件添加到 /third_party/rust_crates/forks

  1. 按照添加外部箱子的说明操作。
  2. 运行 fx update-rustc-third-party 后,将下载的箱子副本从 /third_party/rust_crates/vendor/<my_crate> 移至 /third_party/rust_crates/forks/<my_crate>
  3. 对导入的文件进行所需的更改。
  4. /third_party/rust_crates/Cargo.toml[patch.crates-io] 部分添加一行代码,以指向您的新箱:

    [patch.crates-io]
    ...
    my_crate = { path = "forks/<my_crate>" }
    ...
    
  5. 重新运行 fx update-rustc-third-partyfx build

  6. 添加一个 /third_party/rust_crates/forks/<my_crate>/README.fuchsia 文件,该文件与此处其他箱的 README.fuchsia 格式相匹配。如需了解它应包含的内容,请参阅 /third_party/rust_crates/forks/README.md

Unicode 箱

如果项目需要导入新的外部 crate 来处理与 Unicode 和国际化相关的功能,请尽可能选择 UNIC 项目中的 crate。

已豁免的非 UNIC 条板箱

以下非 UNIC 箱已纳入供应商范围,并已获得豁免:

  • unicode-bidi
  • unicode-normalization
  • unicode-segmentation
  • unicode-width
  • unicode-xid

标准化理由

UNIC 箱具有优于其他箱的明显优势:

  • UNIC 箱是在单个代码库中开发的,具有共享的通用代码和单个版本方案。

    • 独立开发的箱不共享共同的发布时间表、版本控制方案或对任何特定版本的 Unicode 标准的遵守情况。
  • UNIC 箱是从一组一致的 Unicode 数据文件生成的。

    • 每个独立箱子都使用任意版本和数据子集。例如,不同的箱子可能对特定代码点是否已分配、其属性是什么等有不同的假设。
  • UNIC 项目旨在实现全面的功能覆盖,成为 Rust 的 ICU。如果该项目成功,我们对不相关的 Unicode 箱的依赖性应会随着时间的推移而降低。

OWNERS 文件

所有外部 Rust crate 都会维护 OWNERS 文件,以指明谁负责其审核和更新。这些文件是根据 build 图元数据和显式替换文件的组合生成的。

update-rustc-third-party 工具会尽力使用有限的数据更新这些文件,但可能会出错。update-3p-owners 工具可以通过直接从 build 图中重新生成 OWNERS 文件来做得更好。

运行该工具

该工具会发现哪些 build 目标依赖于给定的 crate,这意味着它需要完成最大“厨房水槽”build 的元数据:

  1. 运行 fx set core.x64 --with //bundles/buildbot/core --with //bundles/kitchen_sink --with-host '//tools/gn_desc:install_gn_desc(//build/toolchain:host_x64)'
  2. 运行 fx update-3p-owners --rust-metadata <FUCHSIA_BUILD_DIR>/rustlang/3p-crates-metadata.json

手动更新 OWNERS 文件

供应商提供的第三方箱的 OWNERS 文件由两个主要来源构建而成:

  1. 依赖于第三方 Rust crate 的目标会将其 OWNERS 文件导入到所依赖的 crate 的 OWNERS 文件中。例如,如果 src/lib/foo 等目标依赖于 bar crate,则 bar crate 的 OWNERS 文件将包含 src/lib/foo/OWNERS
  2. 依赖于另一个第三方 Rust crate 的第三方 Rust crate 会将其依赖项的 OWNERS 文件导入到自己的 OWNERS 文件中。例如,如果 bar crate 依赖于 baz crate,则 bar crate 的 OWNERS 文件将包含 third_party/rust_crates/vendor/bar-1.0.0/OWNERS

对于现有箱的增量版本,通常只需将 include 语句更新为已更新箱的最新版本即可。

添加替换值

有些箱子的用户数量过多,无法依靠他们来维护(请参阅旁观者效应)。其他代码实现特定于某个领域(例如安全性)的行为,我们希望由特定团队负责审核这些代码。

在这种情况下,请向 //third_party/owners.toml 添加一个条目,其中包含要引用的其他 OWNERS 文件的路径,然后重新运行该工具。 这会将反向依赖项元数据所有权替换为被替换的路径。

更新频率

Rust on Fuchsia 团队的一名成员目前负责定期运行该工具。如需跟踪自动更新 OWNERS 文件的流程,请参阅 https://fxbug.dev/42152910

在本地覆盖

如果您要向上游贡献代码,并希望运行树内 build 或测试,则替换第三方箱会很有用。您可以通过以下步骤实现这一目标。

  1. third_party/rust_crates/forks/<my_crate> 下克隆(或符号链接)上游代码库。
  2. 将替换项添加到 third_party/rust_crates/Cargo.toml 中的 [patch.crates-io] 部分。
[patch.crates-io]
my_crate = { path = "forks/<my_crate>" }
  1. 您必须确保箱 Cargo.toml 下的版本与 third_party/rust_crates/Cargo.toml 中对该箱的所有引用相匹配。
  2. 运行 fx update-rustc-third-party

问题排查

配置损坏

运行 fx update-rustc-third-party 后,如果您遇到如下错误:

Generating GN file from /$HOME/fuchsia/third_party/rust_crates/Cargo.toml
Error: GNaw config exists for crates that were not found in the Cargo
build graph:

library crate, package handlebars version 2.0.0-beta.2
library crate, package core-foundation-sys version 0.7.0
library crate, package pulldown-cmark version 0.6.0
library crate, package nix version 0.18.0

您可以通过在 .cargo/config 中注释掉 Fuchsia 目标来解决此问题:

[build]
...
target = "x86_64-unknown-fuchsia"

评论后,它会变为:

[build]
...
# target = "x86_64-unknown-fuchsia"

我们正在上游跟踪此问题。