外部 Rust crate

Fuchsia 使用外部 Rust crate。外部 Rust crate 位于 //third-party/rust_crates/vendor 中。这组 crate 基于 //third_party/rust_crates/Cargo.toml 中列出的依赖项。

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

  • 计算外部 crate 的依赖项。

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

  • 正在等待 OSRB 批准。

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

添加外部 crate

如果您没有找到要使用的现有 crate,可能需要向 Fuchsia 添加一个外部 crate。

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

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

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

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

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

      fx update-rustc-third-party
    

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

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

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

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

      fx set core.x64 && fx build
    
  5. 执行以下操作,请求 OSRB 审批:

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

      • 所有者字段留空。
        • OSRB 团队会定期召开会议,审核问题。 您大约需要一周才能收到回复。
      • 指定要添加的所有 crate(无需列出以前批准的 crate)。添加要添加的 crate 以及运行 fx update-rustc-third-party 后确定的依赖项 crate。
      • 如果源代码库中有任何文件在进行供应商提供时未包含在内,请将问题中的这些文件指定给 OSRB。例如,仅用于测试但在供应商 crate 中被排除的字体文件需要纳入 OSRB 问题中。
  6. 如果您获得 OSRB 批准,请将更改上传到 Gerrit 以供审核。 在更改中添加 OSRB 问题 ID 编号。

  7. 将外部 Rust crate 目录的 OWNER 添加为代码审核者。您必须从代码库的其中一个所有者处获取 Code Review Label +2

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

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

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

更新外部 crate

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

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

    1. 对于传递依赖项(未出现在根 Cargo.toml 中),您可以改用 cargo +fuchsia update --manifest-path third_party/rust_crates/Cargo.toml --package $crate_name 等命令。
  2. 运行以下命令:

      fx update-rustc-third-party
    

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

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

  3. 运行以下命令以执行构建测试:

      fx set core.x64 && fx build
    
  4. 检查许可或依赖项方面的变化,看看是否有任何变化。如果存在这些类型的更改,您必须完成 OSRB 审批流程。 执行以下操作,请求 OSRB 审批:

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

      • 所有者字段留空。
        • OSRB 团队会定期召开会议,审核问题。 您大约需要一周才能收到回复。
      • 指定您要添加的所有 crate。添加要添加的 crate 以及运行 fx update-rustc-third-party 后确定的依赖项 crate。
      • 如果源代码库中有任何文件在进行供应商提供时未包含在内,请将问题中的这些文件指定给 OSRB。例如,仅用于测试但在供应商 crate 中被排除的字体文件需要纳入 OSRB 问题中。
  5. 为修改后的 crate 更新 OWNERS 文件。如需详细了解如何更新 OWNERS 文件,请参阅 OWNERS 文件部分。

  6. 如果您获得 OSRB 批准,请将更改上传到 Gerrit 进行审核。在更改中添加 OSRB 问题 ID 编号。

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

添加新镜像

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

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

导入 crate 中的部分文件

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

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

  1. 按照添加外部 crate 的说明进行操作。
  2. 运行 fx update-rustc-third-party 后,将已下载的 crate 副本从 /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] 部分添加一行代码以指向您的新 crate:

    [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 文件,该文件与其他 crate 的 README.fuchsia 的格式相匹配。如需了解其中应包含的内容,请参阅 /third_party/rust_crates/forks/README.md

Unicode crate

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

豁免的非 UNIC crate

以下非 UNIC crate 已提供,因此获得豁免:

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

标准化的理由

与其他 crate 相比,UNIC crate 具有明显的优势:

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

    • 独立开发的 crate 没有共同的发布时间表、版本控制方案或遵循任何特定版本的 Unicode 标准。
  • UNIC crate 由一组一致的 Unicode 数据文件生成。

    • 每个独立的 crate 使用任意版本和数据子集。例如,对于是否分配特定代码点、其属性等而言,不同的 crate 可能会有不同的假设。
  • UNIC 项目旨在实现全面的功能覆盖,就像 Rust 的 ICU 一样。如果项目成功,对不相关的 Unicode crate 的依赖应该会随着时间的推移而减少。

OWNERS 个文件

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

update-rustc-third-party 工具会尽最大努力使用其有限的数据更新这些文件,但难免出错。update-3p-owners 工具可以直接从我们的 build 图重新生成 OWNERS 文件,以达到更好的效果。

运行该工具

该工具会发现哪些 build 目标依赖于给定 crate,这意味着它需要从完成最大“厨房接收器”构建时获得的元数据:

  1. 运行 fx set core.x64 --with //bundles/buildbot/core --with //bundles/kitchen_sink
  2. 运行 fx update-3p-owners --rust-metadata <FUCHSIA_BUILD_DIR>/rustlang/3p-crates-metadata.json

手动更新所有者

供应商提供的第三方 crate 的 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 文件导入自己的文件。例如,如果 bar crate 依赖于 baz crate,则 bar crate 的 OWNERS 文件将包含 third_party/rust_crates/vendor/bar-1.0.0/OWNERS

对于现有 crate 的版本递增,通常只需将 include 语句更新到更新后的 crate 的最新版本即可。

添加替换项

一些 crate 的用户数超出了可信赖的水平(请参阅旁观者效应)。而其他代码会实现特定于某个网域的行为,例如安全性,并且我们希望由一个特定的团队来负责代码审核。

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

更新频率

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

在本地替换

如果您是向上游贡献内容,并希望运行树内 build 或测试,替换第三方 crate 会很有用。这可以通过以下步骤实现。

  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. 您必须确保 crate 的 Cargo.toml 下的版本与 third_party/rust_crates/Cargo.toml 中对该 crate 的所有引用相匹配。
  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 中注释掉紫红色目标线来解决此问题:

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

添加评论后,它将变为:

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

此问题已在上游进行跟踪。