Fuchsia uses external Rust crates. External Rust crates are placed in //third-party/rust_crates/vendor
. This set of crates is based on the dependencies listed in //third_party/rust_crates/Cargo.toml
.
Generally, adding or updating an external crate involves the following:
Calculating the dependencies of your external crate.
Note: Pay attention to transitive dependencies. An external crate may depend on other external crates. List all the new crates that end up being brought in along with the originally intended crate, within the OSRB review.
Requesting Open Source Review Board (OSRB) approval.
Waiting to be granted OSRB approval.
Warning: You must receive approval from the OSRB before pushing a commit to Gerrit that adds an external crate. Do not request a code review for adding an external crate until you have approval from the OSRB.
Uploading the change for code review.
If you don't find an existing crate that you want to use, you may want to add an external crate to Fuchsia.
To add an external crate, do the following:
Change to Fuchsia repository's base directory.
For example, if your fuchsia directory is ~/fuchsia
, run the following command:
cd ~/fuchsia
Add an entry in third_party/rust_crates/Cargo.toml
for the crate that you want to add.
Run the following command to download your desired crate(s) and calculate that crate's dependencies:
Note: On Linux, you need to install pkg-config
with your chosen package manager prior to running this command.
fx update-rustc-third-party
fx update-rustc-third-party
downloads all of the crates listed in rust_crates/Cargo.toml
as well as their dependencies, places the downloaded crates in the vendor
directory, and then updates Cargo.toml
and Cargo.lock
.
You may need to provide additional configuration in a [gn.package.<crate>]
section inside the Cargo.toml
file. For crates that use a build.rs
script, this configuration replaces the script, which is intentionally unsupported by the build system. This configuration is used by cargo-gnaw
, which generates the GN rules from the Cargo.toml file. See cargo-gnaw's README for more details.
Run the following command to perform a build test:
fx set core.x64 && fx build
Request OSRB approval by doing the following:
fx update-rustc-third-party
.Note: As part of the OSRB review, you may be asked to import only a subset of the files in an external crate. See Importing a subset of files in a crate for more information.
If you receive OSRB approval, upload the change to Gerrit for review. Include the OSRB Issue ID number in the change.
Warning: You must receive approval from the OSRB before pushing a commit to Gerrit that adds an external crate. Do not request a code review for adding an external crate until you have approval from the OSRB.
Add an OWNER of the external rust crate directory as a code reviewer. You must get a Code Review Label +2
from one of the repository's owners.
If you have the ability to submit an approved change to the Commit Queue (CQ), submit your change to merge that change into third_party/rust_crates.
If you don't have the ability to submit an approved change, reply to your Gerrit change and request that one of the repository owners submit your change.
For more information about the associated actions for each contributor role, see Role matrix.
Warning: You must receive approval from the OSRB before pushing a commit to Gerrit if updating an external crate changes the license or pulls in a new crate as a dependency. Do not request a code review until you have approval from the OSRB in these circumstances.
To update an external crate, do the following:
Increase the patch number of the crate in third_party/rust_crates/Cargo.toml
.
Run the following command:
fx update-rustc-third-party
You may need to update or provide additional configuration in [gn.package.<crate>]
sections inside the Cargo.toml file. For crates that use a build.rs
script this configuration replaces the script, which is intentionally unsupported by of the build system. This configuration is used by cargo-gnaw
, which generates the GN rules from the Cargo.toml
file. See cargo-gnaw's README for more details.
Run the following command to perform a build test:
fx set core.x64 && fx build
Request OSRB approval by doing the following:
fx update-rustc-third-party
.Note: As part of the OSRB review, you may be asked to import only a subset of the files in an external crate. See Importing a subset of files in a crate for more information.
If you receive OSRB approval, upload the change for review to Gerrit. Include the OSRB Issue ID number in the change.
Add an OWNER of the external rust crate repository as a code reviewer. You must get a Code Review Label +2
from one of the repository's owners.
If you have the ability to submit an approved change to the Commit Queue (CQ), submit your change to merge that change into third_party/rust_crates.
If you don't have the ability to submit an approved change, reply to your Gerrit change and request that one of the repository owners submit your change.
For more information about the associated actions for each contributor role, see Role matrix.
When actively contributing to an upstream repository or maintaining a long-lived fork of a Fuchsia repository, it can be useful to import a crate using a full git repository rather than Cargo's vendoring tools. While this approach is useful, it has significant overhead compared to the default flow and should be approached with caution.
Warning: You must receive approval from the OSRB before pushing a commit to Gerrit that adds or updates an external crate. Do not request a code review for adding or updating an external crate until you have approval from the OSRB.
In some cases, you may want to import only a subset of files in a crate. For example, there may be an optional license in the external repository that‘s incompatible with Fuchsia’s license requirements. Here's an example OSRB review in which this happened.
To do this, you‘ll need to add the crate’s files to /third_party/rust_crates/forks
.
Follow the instructions for adding an external crate.
After running fx update-rustc-third-party
, move the downloaded copy of your crate from /third_party/rust_crates/vendor/<my_crate>
to /third_party/rust_crates/forks/<my_crate>
.
Make the changes you need to make to the imported files.
Add a line to the [patch.crates-io]
section of /third_party/rust_crates/Cargo.toml
to point to your new crate:
[patch.crates-io] ... my_crate = { path = "forks/<my_crate>" } ...
Re-run fx update-rustc-third-party
and fx build
.
Add a /third_party/rust_crates/forks/<my_crate>/README.fuchsia
file which matches the format of other crates' README.fuchsia
s there. See [/third_party/rust_crates/forks/README.md] for what it should contain.
If the project requires importing a new external crate to handle functionality related to Unicode and internationalization, prefer crates from the UNIC project{: .external} when available.
The following non-UNIC crates are already vendored and are exempted:
unicode-bidi
unicode-normalization
unicode-segmentation
unicode-width
unicode-xid
UNIC crates have distinct advantages over other crates:
UNIC crates are developed in a single repo, with shared common code and a single version scheme.
UNIC crates are generated from a consistent set of Unicode data files.
The UNIC project is aiming for comprehensive feature coverage, to be like ICU{: .external} for Rust. If the project succeeds, our dependencies on unrelated Unicode crates should be reduced over time.
OWNERS
files are maintained for all of the external Rust crates to indicate who is responsible for their reviews and updates. These files are generated from a combination of build graph metadata and an explicit override file.
The tool discovers which build targets depend on a given crate, which means it needs the metadata from the completion of a maximal “kitchen sink” build:
//bundles/buildbot:core
and //bundles:kitchen_sink
in your buildfx build
fx update-rust-3p-owners --num-threads <NUM_THREADS>
. It's usually a good idea to limit the number of threads to 50% of available CPUs (see #75382 for details).Some crates have more users than can be relied upon to maintain (see Bystander effect{: .external}). Others implement behavior specific to a domain like security and we would prefer for a specific team to be responsible for reviews of the code.
In these cases, add an entry to //third_party/rust_crates/owners.toml
with the path(s) to other OWNERS
files to reference, then re-run the tool. This replaces the reverse-dependency metadata ownership with the overridden paths.
A member of the Rust on Fuchsia team is currently responsible for running the tool on a regular cadence. See https://fxbug.dev/73348 to track the process of automating updates to OWNERS files.
It can be useful to override a third party crate if you're contributing upstream and want to run in-tree builds or tests. That can be achieved with the following steps.
third_party/rust_crates/forks/<my_crate>
.[patch.crates-io]
section in third_party/rust_crates/Cargo.toml
.[patch.crates-io] my_crate = { path = "forks/<my_crate>" }
Cargo.toml
matches all references to that crate in third_party/rust_crates/Cargo.toml
.fx update-rustc-third-party
.After running fx update-rustc-third-party
, if you encounter an error like this:
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
You can fix this issue commenting out your fuchsia target in .cargo/config
:
[build] ... target = "x86_64-fuchsia"
After commenting, it becomes:
[build] ... # target = "x86_64-fuchsia"
This issue is being tracked upstream{: .external}.