blob: 25e381be3276a67eebed63994490511a4dd526ad [file] [log] [blame] [view]
danakj6e25f742022-12-01 21:47:421# Rust in Chromium
2
3[TOC]
4
5# Why?
6
danakjbb4d0c772023-10-13 13:22:287Handling untrustworthy data in non-trivial ways is a major source of security
8bugs, and it's therefore against Chromium's security policies
9[to do it in the Browser or Gpu process](../docs/security/rule-of-2.md) unless
10you are working in a memory-safe language.
danakj6e25f742022-12-01 21:47:4211
12Rust provides a cross-platform memory-safe language so that all platforms can
13handle untrustworthy data directly from a privileged process, without the
14performance overheads and complexity of a utility process.
15
danakj6e25f742022-12-01 21:47:4216# Status
17
danakjbb4d0c772023-10-13 13:22:2818The Rust toolchain is enabled for and supports all platforms and development
19environments that are supported by the Chromium project. The first milestone
20to include full production-ready support was M119.
danakj6e25f742022-12-01 21:47:4221
danakjbb4d0c772023-10-13 13:22:2822Rust is approved by Chrome ATLs for production use in
23[certain third-party scenarios](../docs/adding_to_third_party.md#Rust).
danakj6e25f742022-12-01 21:47:4224
25For questions or help, reach out to `[email protected]` or `#rust` on the
26[Chromium Slack](https://www.chromium.org/developers/slack/).
27
danakj6e25f742022-12-01 21:47:4228If you use VSCode, we have [additional advice below](#using-vscode).
29
danakjbb4d0c772023-10-13 13:22:2830# Adding a third-party Rust library
danakj6e25f742022-12-01 21:47:4231
danakjbb4d0c772023-10-13 13:22:2832Third-party libraries are pulled from [crates.io](https://crates.io), but
33Chromium does not use Cargo as a build system.
danakj6e25f742022-12-01 21:47:4234
35## Third-party review
36
danakj6e25f742022-12-01 21:47:4237All third-party crates need to go through third-party review. See
38[//docs/adding_to_third_party.md](adding_to_third_party.md) for instructions on
39how to have a library reviewed.
40
danakjbb4d0c772023-10-13 13:22:2841## Importing a crate from crates.io
42
43The `//third_party/rust/third_party.toml` crate defines the set of crates
44depended on from first-party code. Any transitive dependencies will be found
45from those listed there. The file is a subset of a
46[standard `Cargo.toml` file](https://doc.rust-lang.org/cargo/reference/manifest.html),
47but only listing the `[dependencies]` section.
48
49To use a third-party crate "bar" version 3 from first party code, add the
50following to `//third_party/rust/third_party.toml` in `[dependencies]`:
51```toml
52[dependencies]
53bar = "3"
54```
55
56To enable a feature "spaceships" in the crate, change the entry in
57`//third_party/rust/third_party.toml` to include the feature:
58```toml
59[dependencies]
60bar = { version = "3", features = [ "spaceships" ] }
61```
62
63### Generating `BUILD.gn` files for third-party crates
64
65To generate `BUILD.gn` files for all third-party crates, and find missing
66transitive dependencies to download, use the `gnrt` tool:
67
681. Change directory to the root `src/` dir of Chromium.
691. Run `vpython3 ./tools/crates/run_gnrt.py gen` to build and run gnrt with the `gen` action.
70
71Or, to directly build and run gnrt with the system Rust toolchain:
72
731. Change directory to the root `src/` dir of Chromium.
741. Build and run `gnrt gen`:
75 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt gen`.
76
77This will generate a `BUILD.gn` file for each third-party crate. The `BUILD.gn`
78file changes will be visible in `git status` and can be added with `git add`.
79
80### Downloading missing third-party crates
81
82To download crate "foo", at version 4.2.3:
831. Change directory to the root src/ dir of Chromium.
841. Run `gnrt` with the `download` action. e.g.
85 `vpython3 ./tools/crates/run_gnrt.py download --security-critical=yes --shipped=yes foo 4.2.3`
86
87This will download the crate and unpack it into
88`//third_party/rust/foo/v4/crate`. The entire `v4` directory, which includes the
89`crate` subdirectory as well as a generated `README.chromium` file, should be
90added to the repository with `git add third_party/rust/foo/v4`.
91
92Once all the crates are downloaded and `gnrt gen` completes, a CL can be
93uploaded to go through third-party review.
94
95### Patching third-party crates.
96
97You may patch a crate in tree, but save any changes made into a diff file in
98a `patches/` directory for the crate. The diff file should be generated by
99`git-format-patch` each new patch numbered consecutively so that they can be
100applied in order. For example, these files might exist if the "foo" crate was
101patched with a couple of changes:
102
103```
104//third_party/rust/foo/v4/patches/0001-Edit-the-Cargo-toml.diff
105//third_party/rust/foo/v4/patches/0002-Other-changes.diff
106```
107
108### Updating existing third-party crates
109
110To update a crate "foo" to the latest version you must just re-import it at this
111time. To update from version "1.2.0" to "1.3.2":
1121. Remove the `//third_party/rust/foo/v1/crate` directory, which contains the
113 upstream code.
1141. Re-download the crate at the new version with `out/gnrt/release/gnrt download
115 foo 1.3.2`.
1161. If there are any, re-apply local patches with
117 `for i in $(find third_party/rust/foo/v1/patches/*); do patch -p1 < $i; done`
1181. Run `vpython3 ./tools/crates/run_gnrt.py gen` to re-generate all third-party
119 `BUILD.gn` files.
1201. Build `all_rust` to verify things are working.
121
122### Directory structure for third-party crates
123
124The directory structure for a crate "foo" version 3.4.2 is:
125```
126//third_party/
127 rust/
128 foo/
129 v3/
130 BUILD.gn (generated by gnrt gen)
131 README.chromium (generated by gnrt download)
132 crate/
133 Cargo.toml
134 src/
135 ...etc...
136 patches/
137 0001-Edit-the-Cargo-toml.diff
138 0002-Other-changes.diff
139```
140
danakj6e25f742022-12-01 21:47:42141## Writing a wrapper for binding generation
142
143Most Rust libraries will need a more C++-friendly API written on top of them in
danakjbb4d0c772023-10-13 13:22:28144order to generate C++ bindings to them. The wrapper library can be placed
145in `//third_party/rust/<cratename>/<epoch>/wrapper` or at another single place
146that all C++ goes through to access the library. The [CXX](https://cxx.rs) is
147used to generate bindings between C++ and Rust.
danakj6e25f742022-12-01 21:47:42148
149See
danakjbb4d0c772023-10-13 13:22:28150[`//third_party/rust/serde_json_lenient/v0_1/wrapper/`](
151https://source.chromium.org/chromium/chromium/src/+/main:third_party/rust/serde_json_lenient/v0_1/wrapper/)
152and
153[`//components/qr_code_generator`](
154https://source.chromium.org/chromium/chromium/src/+/main:components/qr_code_generator/;l=1;drc=b185db5d502d4995627e09d62c6934590031a5f2)
155for examples.
danakj6e25f742022-12-01 21:47:42156
danakjbb4d0c772023-10-13 13:22:28157Rust libraries should use the
158[`rust_static_library`](
159https://source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_static_library.gni)
160GN template (not the built-in `rust_library`) to integrate properly into the
161mixed-language Chromium build and get the correct compiler options applied to
162them.
danakj6e25f742022-12-01 21:47:42163
danakjbb4d0c772023-10-13 13:22:28164The [CXX](https://cxx.rs) tool is used for generating C++ bindings to Rust
165code. Since it requires explicit declarations in Rust, an wrapper shim around a
166pure Rust library is needed. Add these Rust shims that contain the CXX
167`bridge` macro to the `cxx_bindings` GN variable in the `rust_static_library`
168to have CXX generate a C++ header for that file. To include the C++ header
169file, rooted in the `gen` output directory, use
danakj6e25f742022-12-01 21:47:42170```
danakjbb4d0c772023-10-13 13:22:28171#include "the/path/to/the/rust/file.rs.h"
danakj6e25f742022-12-01 21:47:42172```
173
danakj6e25f742022-12-01 21:47:42174# Using VSCode
175
1761. Ensure you're using the `rust-analyzer` extension for VSCode, rather than
177 earlier forms of Rust support.
danakjbb4d0c772023-10-13 13:22:281782. Run `gn` with the `--export-rust-project` flag, such as:
179 `gn gen out/Release --export-rust-project`.
danakj6e25f742022-12-01 21:47:421803. `ln -s out/Release/rust-project.json rust-project.json`
1814. When you run VSCode, or any other IDE that uses
182 [rust-analyzer](https://rust-analyzer.github.io/) it should detect the
183 `rust-project.json` and use this to give you rich browsing, autocompletion,
184 type annotations etc. for all the Rust within the Chromium codebase.