blob: 8d77cf20eb396f5abb1b78abdac919ad8ccb341b [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
David Adriand8918692024-12-12 22:02:5022Rust can be used anywhere in the Chromium repository (not just `//third_party`)
23subject to [current interop capabilities][interop-rust-doc], however it is
24currently subject to a internal approval and FYI process. Googlers can view
25go/chrome-rust for details. New usages of Rust are documented at
26[`[email protected]`](https://groups.google.com/a/chromium.org/g/rust-fyi).
danakj6e25f742022-12-01 21:47:4227
28For questions or help, reach out to `[email protected]` or `#rust` on the
29[Chromium Slack](https://www.chromium.org/developers/slack/).
30
danakj6e25f742022-12-01 21:47:4231If you use VSCode, we have [additional advice below](#using-vscode).
32
danakjbb4d0c772023-10-13 13:22:2833# Adding a third-party Rust library
danakj6e25f742022-12-01 21:47:4234
danakjbb4d0c772023-10-13 13:22:2835Third-party libraries are pulled from [crates.io](https://crates.io), but
36Chromium does not use Cargo as a build system.
danakj6e25f742022-12-01 21:47:4237
38## Third-party review
39
danakj6e25f742022-12-01 21:47:4240All third-party crates need to go through third-party review. See
41[//docs/adding_to_third_party.md](adding_to_third_party.md) for instructions on
42how to have a library reviewed.
43
danakjbb4d0c772023-10-13 13:22:2844## Importing a crate from crates.io
45
danakj0ec93d12023-11-17 16:12:2346The `//third_party/rust/chromium_crates_io/Cargo.toml` file defines the set of crates
danakjbb4d0c772023-10-13 13:22:2847depended on from first-party code. Any transitive dependencies will be found
danakj0ec93d12023-11-17 16:12:2348from those listed there. The file is a [standard `Cargo.toml` file](
49https://doc.rust-lang.org/cargo/reference/manifest.html), though the crate
50itself is never built, it is only used to collect dependencies through the
51`[dependencies]` section.
danakjbb4d0c772023-10-13 13:22:2852
danakj0ec93d12023-11-17 16:12:2353To use a third-party crate "bar" version 3 from first party code:
danakj98bec162023-11-21 14:55:02541. Change directory to the root `src/` dir of Chromium.
551. Add the crate to `//third_party/rust/chromium_crates_io/Cargo.toml`:
56 * `vpython3 ./tools/crates/run_gnrt.py add foo` to add the latest version of `foo`.
57 * `vpython3 ./tools/crates/run_gnrt.py add [email protected]` to add a specific version of `foo`.
58 * Or, directly through (nightly) cargo:
59 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt add foo`
60 * Or, edit the Cargo.toml by hand, finding the version you want from [crates.io](https://crates.io).
611. Download the crate's files:
62 * `./tools/crates/run_gnrt.py vendor` to download the new crate.
63 * Or, directly through (nightly) cargo:
danakj0ec93d12023-11-17 16:12:2364 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt vendor`
danakjf509caa2023-11-23 15:29:4365 * This will also apply any patches in `//third_party/rust/chromium_crates_io/patches`
66 for the crates. If a patch can not apply, the crate's download will be cancelled and
Lukasz Anforowiczb2b4b1232025-04-25 16:22:3367 an error will be printed. See
68 `//third_party/rust/chromium_crates_io/patches/README.md` for more details.
danakj98bec162023-11-21 14:55:02691. (optional) If the crate is only to be used by tests and tooling, then
70 specify the `"test"` group in `//third_party/rust/chromium_crates_io/gnrt_config.toml`:
71 ```
72 [crate.foo]
73 group = "test"
74 ```
751. Generate the `BUILD.gn` file for the new crate:
76 * `vpython3 ./tools/crates/run_gnrt.py gen`
77 * Or, directly through (nightly) cargo:
78 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt gen`
Lukasz Anforowicz057876d2024-06-05 19:07:58791. Add the new files to git:
80 * `git add -f third_party/rust/chromium_crates_io/vendor`.
81 (The `-f` is important, as files may be skipped otherwise from a
82 `.gitignore` inside the crate.)
83 * `git add third_party/rust`
Lukasz Anforowiczf6888b7b2025-03-25 17:41:13841. Upload the CL and get a review from `//third_party/rust/OWNERS`.
danakj0ec93d12023-11-17 16:12:2385
86### Cargo features
danakjbb4d0c772023-10-13 13:22:2887
88To enable a feature "spaceships" in the crate, change the entry in
danakj0ec93d12023-11-17 16:12:2389`//third_party/rust/chromium_crates_io/Cargo.toml` to include the feature:
danakjbb4d0c772023-10-13 13:22:2890```toml
91[dependencies]
92bar = { version = "3", features = [ "spaceships" ] }
93```
94
danakj98bec162023-11-21 14:55:0295## Security
danakjbb4d0c772023-10-13 13:22:2896
danakj98bec162023-11-21 14:55:0297If a shipping library needs security review (has any `unsafe`), and the review
98finds it's not satisfying the [rule of 2](../docs/security/rule-of-2.md), then
99move it to the `"sandbox"` group in `//third_party/rust/chromium_crates_io/gnrt_config.toml`
100to make it clear it can't be used in a privileged process:
101```
102[crate.foo]
103group = "sandbox"
104```
105
106If a transitive dependency moves from `"safe"` to `"sandbox"` and causes
107a dependency chain across the groups, it will break the `gnrt vendor` step.
108You will need to fix the new crate so that it's deemed safe in unsafe review,
109or move the other dependent crates out of `"safe"` as well by setting their
110group in `gnrt_config.toml`.
111
112# Updating existing third-party crates
113
Lukasz Anforowicz85528a62024-03-20 19:12:53114Third-party crates will get updated semi-automatically through the process
115described in
116[`../tools/crates/create_update_cl.md`](../tools/crates/create_update_cl.md).
117If you nevertheless need to manually update a crate to its latest minor
118version, then follow the steps below:
119
danakj98bec162023-11-21 14:55:021201. Change directory to the root `src/` dir of Chromium.
Dominik Röttschesa07a5532024-01-24 19:16:231211. Update the versions in `//third_party/rust/chromium_crates_io/Cargo.toml`.
Lukasz Anforowicz85528a62024-03-20 19:12:53122 * `vpython3 ./tools/crates/run_gnrt.py update <crate name>`
danakj98bec162023-11-21 14:55:02123 * Or, directly through (nightly) cargo:
Lukasz Anforowicz85528a62024-03-20 19:12:53124 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt update <crate name>`
danakj98bec162023-11-21 14:55:021251. Download any updated crate's files:
126 * `./tools/crates/run_gnrt.py vendor`
Dominik Röttschesa07a5532024-01-24 19:16:23127 * If you want to restrict the update to certain crates, add the crate names
128 as arguments to `vendor`, like: `./tools/crates/run_gnrt.py vendor
129 <crate-name>`
danakj98bec162023-11-21 14:55:02130 * Or, directly through (nightly) cargo:
131 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt vendor`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551321. Add the downloaded files to git:
danakj98bec162023-11-21 14:55:02133 * `git add -f third_party/rust/chromium_crates_io/vendor`
134 * The `-f` is important, as files may be skipped otherwise from a
135 `.gitignore` inside the crate.
danakj98bec162023-11-21 14:55:021361. Generate the `BUILD.gn` files
137 * `vpython3 ./tools/crates/run_gnrt.py gen`
138 * Or, directly through (nightly) cargo:
139 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt gen`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551401. Add the generated files to git:
141 * `git add -f third_party/rust`
danakjbb4d0c772023-10-13 13:22:28142
143### Directory structure for third-party crates
144
145The directory structure for a crate "foo" version 3.4.2 is:
146```
147//third_party/
148 rust/
danakj98bec162023-11-21 14:55:02149 foo/ (for the "foo" crate)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55150 v3/ (version 3.4.2 maps to the v3 epoch)
danakjbb4d0c772023-10-13 13:22:28151 BUILD.gn (generated by gnrt gen)
danakj98bec162023-11-21 14:55:02152 README.chromium (generated by gnrt vendor)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55153 chromium_crates_io/
154 vendor/
155 foo-3.4.2 (crate sources downloaded from crates.io)
danakj98bec162023-11-21 14:55:02156 patches/
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55157 foo/ (patches for the "foo" crate)
Lukasz Anforowiczb2b4b1232025-04-25 16:22:33158 0001-Some-changes.diff
danakjbb4d0c772023-10-13 13:22:28159 0002-Other-changes.diff
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55160 Cargo.toml
161 Cargo.lock
162 gnrt_config.toml
danakjbb4d0c772023-10-13 13:22:28163```
164
danakj6e25f742022-12-01 21:47:42165## Writing a wrapper for binding generation
166
167Most Rust libraries will need a more C++-friendly API written on top of them in
danakjbb4d0c772023-10-13 13:22:28168order to generate C++ bindings to them. The wrapper library can be placed
169in `//third_party/rust/<cratename>/<epoch>/wrapper` or at another single place
170that all C++ goes through to access the library. The [CXX](https://cxx.rs) is
171used to generate bindings between C++ and Rust.
danakj6e25f742022-12-01 21:47:42172
173See
danakjbb4d0c772023-10-13 13:22:28174[`//third_party/rust/serde_json_lenient/v0_1/wrapper/`](
175https://source.chromium.org/chromium/chromium/src/+/main:third_party/rust/serde_json_lenient/v0_1/wrapper/)
176and
177[`//components/qr_code_generator`](
178https://source.chromium.org/chromium/chromium/src/+/main:components/qr_code_generator/;l=1;drc=b185db5d502d4995627e09d62c6934590031a5f2)
179for examples.
danakj6e25f742022-12-01 21:47:42180
danakjbb4d0c772023-10-13 13:22:28181Rust libraries should use the
182[`rust_static_library`](
183https://source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_static_library.gni)
184GN template (not the built-in `rust_library`) to integrate properly into the
185mixed-language Chromium build and get the correct compiler options applied to
186them.
danakj6e25f742022-12-01 21:47:42187
Lukasz Anforowiczdcdb524a2025-03-24 19:26:41188See `rust-ffi.md` for information on C++/Rust FFI.
danakj6e25f742022-12-01 21:47:42189
Tatsuyuki Ishib3425ab02025-04-10 19:02:20190# Unstable features
191
192Unstable features are **unsupported** by default in Chromium. Any use of an
193unstable language or library feature should be agreed upon by the Rust toolchain
194team before enabling it.
195
196Since Chromium imports the Rust toolchain at its HEAD and builds it in a
197nightly-like configuration, it is technically possible to depend on unstable
198features. However, unstable features often change in a backwards incompatible
199way without a warning. If such incompatible changes are introduced, importing a
200new version of toolchain now requires the owner to fix forward, instead of being
201an automated process. This makes toolchain upgrades prohibitively difficult.
202
203When an exception is required, consider:
204
205- Whether the unstable feature brings significant value that is unattainable
206 in stable alternatives
207- The risk of breaking changes to the feature
208- Ways to fallback in case a backward-incompatible toolchain change is
209 introduced
210
211A list of exceptions is maintained in
212[`../tools/rust/unstable_rust_feature_usage.md`](../tools/rust/unstable_rust_feature_usage.md).
213
danakj3d037ff2024-11-07 19:31:41214# Logging
Adrian Taylor91eaa362024-02-09 14:17:03215
danakj3d037ff2024-11-07 19:31:41216Use the [log](https://docs.rs/log) crate's macros in place of base `LOG`
217macros from C++. They do the same things. The `debug!` macro maps to
218`DLOG(INFO)`, the `info!` macro maps to `LOG(INFO)`, and `warn!` and `error!`
219map to `LOG(WARNING)` and `LOG(ERROR)` respectively. The additional `trace!`
220macro maps to `DLOG(INFO)` (but there is [WIP to map it to `DVLOG(INFO)`](
221https://chromium-review.googlesource.com/c/chromium/src/+/5996820)).
222
223Note that the standard library also includes a helpful
224[`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro which writes
225everything about a variable to `stderr`.
226
227Logging may not yet work in component builds:
228[crbug.com/374023535](https://crbug.com/374023535).
229
230# Tracing
231
232TODO: [crbug.com/377915495](https://crbug.com/377915495).
233
234# Strings
235
236Prefer to use [`BString`](https://docs.rs/bstr/latest/bstr/struct.BString.html)
237and [`BStr`](https://docs.rs/bstr/latest/bstr/struct.BStr.html) to work with
238strings in first-party code instead of `std::String` and `str`. These types do
239not require the strings to be valid UTF-8, and avoid error handling or panic
240crashes when working with strings from C++ and/or from the web. Because the
241web is not UTF-8 encoded, many strings in Chromium are also not.
242
243In cross-language bindings, `&[u8]` can be used to represent a string until
244native support for `BStr` is available in our interop tooling. A `u8` slice
245can be converted to `BStr` or treated as a string with
246[`ByteSlice`](https://docs.rs/bstr/latest/bstr/trait.ByteSlice.html).
Adrian Taylor91eaa362024-02-09 14:17:03247
danakj6e25f742022-12-01 21:47:42248# Using VSCode
249
2501. Ensure you're using the `rust-analyzer` extension for VSCode, rather than
251 earlier forms of Rust support.
danakjbb4d0c772023-10-13 13:22:282522. Run `gn` with the `--export-rust-project` flag, such as:
253 `gn gen out/Release --export-rust-project`.
danakj6e25f742022-12-01 21:47:422543. `ln -s out/Release/rust-project.json rust-project.json`
2554. When you run VSCode, or any other IDE that uses
256 [rust-analyzer](https://rust-analyzer.github.io/) it should detect the
257 `rust-project.json` and use this to give you rich browsing, autocompletion,
258 type annotations etc. for all the Rust within the Chromium codebase.
danakjf3d7f372023-12-07 18:17:122595. Point rust-analyzer to the rust toolchain in Chromium. Otherwise you will
260 need to install Rustc in your system, and Chromium uses the nightly
261 compiler, so you would need that to match. Add the following to
262 `.vscode/settings.json` in the Chromium checkout:
263 ```
264 {
265 // The rest of the settings...
266
267 "rust-analyzer.cargo.extraEnv": {
268 "PATH": "../../third_party/rust-toolchain/bin:$PATH",
269 }
270 }
271 ```
272 This assumes you are working with an output directory like `out/Debug` which
273 has two levels; adjust the number of `..` in the path according to your own
274 setup.
Adrian Taylorc5fbb572023-11-21 14:25:42275
276# Using cargo
277
278If you are building a throwaway or experimental tool, you might like to use pure
279`cargo` tooling rather than `gn` and `ninja`. Even then, you may choose
280to restrict yourself to the toolchain and crates that are already approved for
281use in Chromium.
282
283Here's how.
284
285```
286export PATH_TO_CHROMIUM_SRC=~/chromium/src
287mkdir my-rust-tool
288cd my-rust-tool
289mkdir .cargo
290cat <<END > .cargo/config.toml
291[source.crates-io]
292replace-with = "vendored-sources"
293
294[source.vendored-sources]
295directory = "$PATH_TO_CHROMIUM_SRC/third_party/rust/chromium_crates_io/vendor"
296END
297$PATH_TO_CHROMIUM_SRC/third_party/rust-toolchain/bin/cargo init --offline
298$PATH_TO_CHROMIUM_SRC/third_party/rust-toolchain/bin/cargo run --offline
299```
300
301Most `cargo` tooling works well with this setup; one exception is `cargo add`,
302but you can still add dependencies manually to your `Cargo.toml`:
303
304```
305[dependencies]
306log = "0.4"
307```
David Adriand8918692024-12-12 22:02:50308
309[interop-rust-doc]: https://docs.google.com/document/d/1kvgaVMB_isELyDQ4nbMJYWrqrmL3UZI4tDxnyxy9RTE/edit?tab=t.0#heading=h.fpqr6hf3c3j0