Fuchsia 使用外部 Rust crate。外部 Rust crate 放置在 //third_party/rust_crates/vendor
中。这组箱基于 //third_party/rust_crates/Cargo.toml
中列出的依赖项。
一般来说,添加或更新外部箱涉及以下步骤:
添加外部箱
如果您找不到想要使用的现有箱,可能需要向 Fuchsia 添加外部箱。
如需添加外部箱,请执行以下操作:
切换到 Fuchsia 代码库的基本目录。
例如,如果您的 Fuchsia 目录为
~/fuchsia
,请运行以下命令:cd ~/fuchsia
在
third_party/rust_crates/Cargo.toml
中为要添加的箱添加一个条目。运行以下命令可下载所需箱(crate) 并计算该箱的依赖项:
fx update-rustc-third-party
fx update-rustc-third-party
下载rust_crates/Cargo.toml
中列出的所有箱及其依赖项,将下载的箱放置在vendor
目录中,然后更新Cargo.toml
和Cargo.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
来确认。
运行以下命令以执行 build 测试:
fx set core.x64 && fx build
通过以下方式请求 OSRB 批准:
- 使用开源审核委员会 (OSRB) 模板创建问题。
在问题中,执行以下操作:
- 将 Owner(所有者)字段留空。
- OSRB 团队会定期开会来审核这些问题。请耐心等待大约一周,我们会尽快回复您。
- 指定要添加的所有箱 (crate)(无需列出之前已获批准的箱)。包括您要添加的箱以及运行
fx update-rustc-third-party
后确定的依赖箱。 - 如果源代码库中有任何文件在供应商化时未包含在内,请在向 OSRB 提交的问题中指定这些文件。例如,仅用于测试但在出售箱子时被排除的字体文件需要包含在 OSRB 问题中。
- 将 Owner(所有者)字段留空。
如果您获得 OSRB 批准,请将相应变更上传到 Gerrit 以供审核。 在更改中添加 OSRB 问题 ID 编号。
添加外部 Rust 箱目录的 OWNER 作为代码审核者。您必须从代码库的所有者之一处获得
Code Review Label +2
。如果您有权向提交队列 (CQ) 提交已获批准的更改,请提交您的更改,以将该更改合并到 third_party/rust_crates 中。
如果您无法提交已获批准的更改,请回复您的 Gerrit 更改,并请求某位代码库所有者提交您的更改。
如需详细了解每种贡献者角色关联的操作,请参阅角色矩阵。
更新外部 crate
如需更新外部箱,请执行以下操作:
增加了
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
的引用,并相应地更新版本字符串。
- 对于不显示在
运行以下命令:
fx update-rustc-third-party
您可能需要在 Cargo.toml 文件中的
[gn.package.<crate>]
部分更新或提供其他配置。对于使用build.rs
脚本的箱,此配置会替换该脚本,而该脚本是构建系统有意不支持的。此配置由cargo-gnaw
使用,后者会根据Cargo.toml
文件生成 GN 规则。 如需了解详情,请参阅 cargo-gnaw 的 README。检查已更新箱子的版本字符串是否已在
third_party/rust_crates/BUILD.gn
中正确更新,并根据需要手动调整。在本地提交更改后,再次运行
fx update-rustc-third-party
并确保其成功完成,且未产生任何更改。您可以运行git status
来确认。运行以下命令以执行 build 测试:
fx set core.x64 && fx build
检查更改中是否存在许可或依赖项方面的变化。如果存在此类变更,您必须完成 OSRB 审批流程。 通过以下方式请求 OSRB 批准:
- 使用开源审核委员会 (OSRB) 模板创建问题。
在问题中,执行以下操作:
- 将 Owner(所有者)字段留空。
- OSRB 团队会定期开会来审核这些问题。请耐心等待大约一周,我们会尽快回复您。
- 指定要添加的所有箱。包括您要添加的箱以及运行
fx update-rustc-third-party
后确定的依赖箱。 - 如果源代码库中有任何文件在供应商化时未包含在内,请在向 OSRB 提交的问题中指定这些文件。例如,仅用于测试但在出售箱子时被排除的字体文件需要包含在 OSRB 问题中。
- 将 Owner(所有者)字段留空。
更新已修改箱子的 OWNERS 文件。如需详细了解如何更新 OWNERS 文件,请参阅 OWNERS 文件部分。
如果您收到 OSRB 批准,请将相应变更上传到 Gerrit 以供审核。在更改中添加 OSRB 问题 ID 编号。
如果没有许可或依赖项变更,您可以上传变更以供审核,而无需经过 OSRB 审批流程。
添加新镜像
当积极向上游代码库贡献代码或维护 Fuchsia 代码库的长期分支时,使用完整的 Git 代码库(而非 Cargo 的供应商工具)导入 crate 会很有用。虽然此方法很有用,但与默认流程相比,开销很大,因此应谨慎使用。
- 在 fuchsia.googlesource.com 上请求添加镜像。
- 将镜像添加到 Rust 运行时的 Jiri 清单。
- 向工作区添加 crate 的补丁部分。
- 运行更新脚本。
导入箱中的部分文件
在某些情况下,您可能只想导入箱中的部分文件。例如,外部代码库中可能存在与 Fuchsia 的许可要求不兼容的可选许可。下面是一个出现此情况的 OSRB 审核示例。
为此,您需要将箱子的文件添加到 /third_party/rust_crates/forks
。
- 按照添加外部箱子的说明操作。
- 运行
fx update-rustc-third-party
后,将下载的箱子副本从/third_party/rust_crates/vendor/<my_crate>
移至/third_party/rust_crates/forks/<my_crate>
。 - 对导入的文件进行所需的更改。
向
/third_party/rust_crates/Cargo.toml
的[patch.crates-io]
部分添加一行代码,以指向您的新箱:[patch.crates-io] ... my_crate = { path = "forks/<my_crate>" } ...
重新运行
fx update-rustc-third-party
和fx build
。添加一个
/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 的元数据:
- 运行
fx set core.x64 --with //bundles/buildbot/core --with //bundles/kitchen_sink --with-host '//tools/gn_desc:install_gn_desc(//build/toolchain:host_x64)'
- 运行
fx update-3p-owners --rust-metadata <FUCHSIA_BUILD_DIR>/rustlang/3p-crates-metadata.json
。
手动更新 OWNERS 文件
供应商提供的第三方箱的 OWNERS 文件由两个主要来源构建而成:
- 依赖于第三方 Rust crate 的目标会将其 OWNERS 文件导入到所依赖的 crate 的 OWNERS 文件中。例如,如果
src/lib/foo
等目标依赖于bar
crate,则bar
crate 的 OWNERS 文件将包含src/lib/foo/OWNERS
。 - 依赖于另一个第三方 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 或测试,则替换第三方箱会很有用。您可以通过以下步骤实现这一目标。
- 在
third_party/rust_crates/forks/<my_crate>
下克隆(或符号链接)上游代码库。 - 将替换项添加到
third_party/rust_crates/Cargo.toml
中的[patch.crates-io]
部分。
[patch.crates-io]
my_crate = { path = "forks/<my_crate>" }
- 您必须确保箱
Cargo.toml
下的版本与third_party/rust_crates/Cargo.toml
中对该箱的所有引用相匹配。 - 运行
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"
我们正在上游跟踪此问题。