Fuchsia 使用外部 Rust crate。外部 Rust crate 放置在 //third-party/rust_crates/vendor
中。这组 crate 基于 //third_party/rust_crates/Cargo.toml
中列出的依赖项。
通常,添加或更新外部 crate 涉及以下步骤:
计算外部 crate 的依赖项。
请求 Open Source Review Board (OSRB) 批准。
- 如需了解详情,请参阅本文档中的添加外部 crate 或更新外部 crate 部分。
正在等待 OSRB 批准。
上传更改以进行代码审核。
添加外部 crate
如果您找不到要使用的现有 crate,不妨考虑向 Fuchsia 添加外部 crate。
如需添加外部 crate,请执行以下操作:
切换到 Fuchsia 代码库的基础目录。
例如,如果您的 Fuchsia 目录为
~/fuchsia
,请运行以下命令:cd ~/fuchsia
在
third_party/rust_crates/Cargo.toml
中为您要添加的 crate 添加条目。运行以下命令可下载所需的 crate 并计算该 crate 的依赖项:
fx update-rustc-third-party
fx update-rustc-third-party
会下载rust_crates/Cargo.toml
中列出的所有 crate 及其依赖项,将下载的 crate 放置在vendor
目录中,然后更新Cargo.toml
和Cargo.lock
。您可能需要在
Cargo.toml
文件内的[gn.package.<crate>]
部分中提供其他配置。对于使用build.rs
脚本的 crate,此配置会替换该脚本,因为构建系统故意不支持该脚本。cargo-gnaw
会使用此配置,并根据 Cargo.toml 文件生成 GN 规则。如需了解详情,请参阅 cargo-gnaw 的 README。在本地提交更改后,请再次运行
fx update-rustc-third-party
,并确保它成功完成且未产生任何更改。您可以运行git status
来确认。运行以下命令以执行构建测试:
fx set core.x64 && fx build
请按以下步骤申请 OSRB 批准:
- 使用 Open Source Review Board (OSRB) 模板创建问题。
在问题中,执行以下操作:
- 将 Owner(所有者)字段留空。
- OSRB 团队会定期开会审核相关问题。请耐心等待大约一周的时间,我们会给您回复。
- 指定您要添加的所有 crate(无需列出之前已获批准的 crate)。添加要添加的 crate 以及运行
fx update-rustc-third-party
后识别出的依赖项 crate。 - 如果源代码库中有任何文件在供应商化时未包含,请在向 OSRB 提交的问题中指明这些文件。例如,仅用于测试但在 crate 被供应商化时被排除的字体文件需要包含在 OSRB 问题中。
- 将 Owner(所有者)字段留空。
如果您获得 OSRB 批准,请将更改上传到 Gerrit 以供审核。 在更改中添加 OSRB 问题 ID 编号。
将外部 rust crate 目录的所有者添加为代码审核者。您必须从代码库的所有者之一那里获取
Code Review Label +2
。如果您能够将已获批准的更改提交到提交队列 (CQ),请提交更改,以将该更改合并到 third_party/rust_crates。
如果您无法提交已获批准的更改,请回复您的 Gerrit 更改,并请求某个代码库所有者提交您的更改。
如需详细了解每个贡献者角色的相关操作,请参阅角色矩阵。
更新外部 crate
如需更新外部 crate,请执行以下操作:
在
third_party/rust_crates/Cargo.toml
中提高了 crate 的补丁编号- 对于传递依赖项(未显示在
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
脚本的 crate,此配置会替换该脚本,因为构建系统故意不支持该脚本。此配置由cargo-gnaw
使用,后者会根据Cargo.toml
文件生成 GN 规则。如需了解详情,请参阅 cargo-gnaw 的 README。检查更新后的 crate 的版本字符串是否已在
third_party/rust_crates/BUILD.gn
中正确更新,并根据需要手动调整。在本地提交更改后,请再次运行
fx update-rustc-third-party
,并确保它成功完成且未产生任何更改。您可以运行git status
来确认。运行以下命令以执行构建测试:
fx set core.x64 && fx build
检查更改,确认许可或依赖项是否发生了任何变化。如果有此类更改,您必须完成 OSRB 审批流程。 请按以下步骤申请 OSRB 批准:
- 使用 Open Source Review Board (OSRB) 模板创建问题。
在问题中,执行以下操作:
- 将 Owner(所有者)字段留空。
- OSRB 团队会定期开会审核相关问题。请耐心等待大约一周的时间,我们会给您回复。
- 指定要添加的所有 crate。添加要添加的 crate 以及运行
fx update-rustc-third-party
后识别出的依赖项 crate。 - 如果源代码库中有任何文件在供应商化时未包含,请在向 OSRB 提交的问题中指明这些文件。例如,仅用于测试但在 crate 被供应商化时被排除的字体文件需要包含在 OSRB 问题中。
- 将 Owner(所有者)字段留空。
更新了经过修改的 crate 的 OWNERS 文件。如需详细了解如何更新 OWNERS 文件,请参阅 OWNERS 文件部分。
获得 OSRB 批准后,将更改上传到 Gerrit 以供审核。在更改中添加 OSRB 问题 ID 编号。
如果没有许可或依赖项更改,您可以直接上传更改以供审核,而无需经过 OSRB 审批流程。
添加新镜像
在积极为上游代码库做出贡献或维护 Fuchsia 代码库的长期分支时,使用完整的 Git 代码库(而不是 Cargo 的供应商工具)导入 crate 可能会很有用。虽然此方法很有用,但与默认流程相比,其开销非常大,因此应谨慎使用。
- 在 fuchsia.googlesource.com 上请求添加镜像。
- 将镜像添加到 Rust 运行时的 Jiri 清单中。
- 将 crate 的补丁部分添加到工作区。
- 运行更新脚本。
导入 crate 中的部分文件
在某些情况下,您可能只希望导入 crate 中的部分文件。例如,外部代码库中可能包含与 Fuchsia 的许可要求不兼容的可选许可。下面是一个发生这种情况的 OSRB 审核示例。
为此,您需要将 crate 的文件添加到 /third_party/rust_crates/forks
。
- 按照添加外部 crate 的说明操作。
- 运行
fx update-rustc-third-party
后,将 crate 的下载副本从/third_party/rust_crates/vendor/<my_crate>
移至/third_party/rust_crates/forks/<my_crate>
。 - 对导入的文件进行所需的更改。
将一行代码添加到
/third_party/rust_crates/Cargo.toml
的[patch.crates-io]
部分,以指向您的新 crate:[patch.crates-io] ... my_crate = { path = "forks/<my_crate>" } ...
重新运行
fx update-rustc-third-party
和fx build
。添加一个与其他 crate 的
README.fuchsia
格式匹配的/third_party/rust_crates/forks/<my_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
文件,以指明负责审核和更新这些 crate 的人员。这些文件是通过构建图元数据和显式替换文件的组合生成的。
update-rustc-third-party
工具会尽力使用其有限的数据更新这些文件,但可能会出错。update-3p-owners
工具可以直接从我们的构建图重新生成 OWNERS 文件,从而取得更好的效果。
运行该工具
该工具会发现哪些构建目标依赖于给定 crate,这意味着它需要在完成最大“厨房水槽”构建后获得元数据:
- 运行
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
供应商第三方 crate 的 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
。
对于现有 crate 的版本升级,通常只需将 include 语句更新为更新后的 crate 的最新版本即可。
添加替换项
有些 crate 的用户数量过多,无法依靠用户来维护(请参阅旁观者效应)。其他模块则实现了特定于某个领域(例如安全)的行为,我们希望由特定团队负责审核这些代码。
在这些情况下,请向 //third_party/owners.toml
添加一个条目,其中包含要引用的其他 OWNERS
文件的路径,然后重新运行该工具。这会将反向依赖项元数据所有权替换为被替换的路径。
更新频率
Rust on Fuchsia 团队的一名成员目前负责定期运行该工具。如需跟踪自动更新 OWNERS 文件的流程,请参阅 https://fxbug.dev/42152910。
在本地覆盖
如果您要向上游贡献代码,并希望运行树内 build 或测试,则覆盖第三方 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>" }
- 您必须确保 crate 的
Cargo.toml
下的版本与third_party/rust_crates/Cargo.toml
中对该 crate 的所有引用一致。 - 运行
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"
我们正在上游跟踪此问题。