blob: 17990bbe98ebf3c9d60f527c433a65150542cac4 [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
Lukasz Anforowiczc8ebad82025-05-22 20:51:4112Rust provides a cross-platform, memory-safe language so that all platforms can
danakj6e25f742022-12-01 21:47:4213handle untrustworthy data directly from a privileged process, without the
Lukasz Anforowiczc8ebad82025-05-22 20:51:4114performance overhead and complexity of a utility process.
danakj6e25f742022-12-01 21:47:4215
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
Lukasz Anforowiczc8ebad82025-05-22 20:51:4128For questions or help, reach out to
29[`[email protected]`](https://groups.google.com/a/chromium.org/g/rust-dev),
30or [`#rust` channel](https://chromium.slack.com/archives/C01T3EWCJ9Z)
31on the [Chromium Slack](https://www.chromium.org/developers/slack/),
32or (Google-internal, sorry)
33[Chrome Rust chatroom](https://chat.google.com/room/AAAAk1UCFGg?cls=7).
danakj6e25f742022-12-01 21:47:4234
danakj6e25f742022-12-01 21:47:4235If you use VSCode, we have [additional advice below](#using-vscode).
36
danakjbb4d0c772023-10-13 13:22:2837# Adding a third-party Rust library
danakj6e25f742022-12-01 21:47:4238
danakjbb4d0c772023-10-13 13:22:2839Third-party libraries are pulled from [crates.io](https://crates.io), but
40Chromium does not use Cargo as a build system.
danakj6e25f742022-12-01 21:47:4241
42## Third-party review
43
Lukasz Anforowiczc8ebad82025-05-22 20:51:4144All third-party libraries (not just Rust) need to go through third-party review.
45See [//docs/adding_to_third_party.md](adding_to_third_party.md) for instructions.
danakj6e25f742022-12-01 21:47:4246
danakjbb4d0c772023-10-13 13:22:2847## Importing a crate from crates.io
48
Lukasz Anforowiczc8ebad82025-05-22 20:51:4149Third-party crates (from [crates.io](https://crates.io))
50that Chromium depends on are described by two files:
danakjbb4d0c772023-10-13 13:22:2851
Lukasz Anforowiczc8ebad82025-05-22 20:51:4152* `//third_party/rust/chromium_crates_io/Cargo.toml`.
53 This file defines the set of crates
54 **directly** depended on from first-party code (from Chromium first-party
55 code, but also from Pdfium, V8, etc.). Their transitive dependencies don't
56 need to be listed, because they will be automatically identified and covered
57 by tools like `gnrt`. The file is a [standard `Cargo.toml` file](
58 https://doc.rust-lang.org/cargo/reference/manifest.html), even though the crate
59 itself is never built - it is only used to enable/disable crate features,
60 specify crate versions, etc.
61* `//third_party/rust/chromium_crates_io/gnrt_config.toml`.
62 This file defines Chromium-specific, `cargo`-agnostic metadata like:
63 - Configuring certain aspects of Chromium build (e.g. `allow_unsafe`,
64 `allow_unstable_features`, `extra_src_roots`, `group = "test"`, etc.)
65 - Specifying licensing information when it can't be automatically inferred
66 (e.g. pointing out `license_files` with non-standard filenames).
67
68To import a third-party crate follow the steps below:
69
danakj98bec162023-11-21 14:55:02701. Change directory to the root `src/` dir of Chromium.
711. Add the crate to `//third_party/rust/chromium_crates_io/Cargo.toml`:
72 * `vpython3 ./tools/crates/run_gnrt.py add foo` to add the latest version of `foo`.
73 * `vpython3 ./tools/crates/run_gnrt.py add [email protected]` to add a specific version of `foo`.
Lukasz Anforowiczc8ebad82025-05-22 20:51:4174 * Or, edit `//third_party/rust/chromium_crates_io/Cargo.toml` by hand,
75 finding the version you want from [crates.io](https://crates.io).
danakj98bec162023-11-21 14:55:02761. Download the crate's files:
77 * `./tools/crates/run_gnrt.py vendor` to download the new crate.
Lukasz Anforowiczc8ebad82025-05-22 20:51:4178 * This will also apply any patches in `//third_party/rust/chromium_crates_io/patches`.
79 See `//third_party/rust/chromium_crates_io/patches/README.md` for more details.
danakj98bec162023-11-21 14:55:02801. (optional) If the crate is only to be used by tests and tooling, then
81 specify the `"test"` group in `//third_party/rust/chromium_crates_io/gnrt_config.toml`:
82 ```
83 [crate.foo]
84 group = "test"
85 ```
861. Generate the `BUILD.gn` file for the new crate:
87 * `vpython3 ./tools/crates/run_gnrt.py gen`
Lukasz Anforowiczb7a722f2025-05-30 00:13:31881. Add `//third_party/rust/crate_name/OWNERS`
Lukasz Anforowicz057876d2024-06-05 19:07:58891. Add the new files to git:
90 * `git add -f third_party/rust/chromium_crates_io/vendor`.
91 (The `-f` is important, as files may be skipped otherwise from a
92 `.gitignore` inside the crate.)
93 * `git add third_party/rust`
Lukasz Anforowiczc8ebad82025-05-22 20:51:41941. Upload the CL and get a review from `//third_party/rust/OWNERS`
95 (check
96 [`third_party/rust/OWNERS-review-checklist.md`](../third_party/rust/OWNERS-review-checklist.md)
97 to see what to expect).
danakj0ec93d12023-11-17 16:12:2398
Lukasz Anforowiczfbf3e762025-05-21 17:50:4199Note that at this point the new crate is still not seen by `gn` nor `ninja`,
100and is not covered by CQ. To make the new crate part of the build,
101you need to add a `deps` edge between an existing build target
102and the newly added `//third_party/rust/some_crate/v123:lib` target.
103This will allow `autoninja -C out/Default third_party/rust/some_crate/v123:lib`
104to work. Additionally, this will help CQ to prevent regressions when updating
105`rustc` or enabling new Rust warnings.
106
danakj98bec162023-11-21 14:55:02107## Security
danakjbb4d0c772023-10-13 13:22:28108
danakj98bec162023-11-21 14:55:02109If a shipping library needs security review (has any `unsafe`), and the review
110finds it's not satisfying the [rule of 2](../docs/security/rule-of-2.md), then
111move it to the `"sandbox"` group in `//third_party/rust/chromium_crates_io/gnrt_config.toml`
112to make it clear it can't be used in a privileged process:
113```
114[crate.foo]
115group = "sandbox"
116```
117
118If a transitive dependency moves from `"safe"` to `"sandbox"` and causes
119a dependency chain across the groups, it will break the `gnrt vendor` step.
120You will need to fix the new crate so that it's deemed safe in unsafe review,
121or move the other dependent crates out of `"safe"` as well by setting their
122group in `gnrt_config.toml`.
123
Lukasz Anforowiczc938bcd62025-06-26 11:36:13124## Troubleshooting
125
126### Incomplete sources or inputs listing
127
128`gnrt` enumerates all `.rs` files as crate sources, but may need help
129with discovering additional files consumed with something like
130[`include_str!`](https://doc.rust-lang.org/std/macro.include_str.html).
131So, if you see:
132
133```
134ERROR: file not in GN sources:
135../../third_party/rust/chromium_crates_io/vendor/some_crate/README.md
136```
137
138Then you can:
139
140* Add the missing files to
141 `third_party/rust/chromium_crates_io/gnrt_config.toml` - for example:
142
143 ```
144 [crate.some_crate]
145 extra_input_roots = ['../README.md']
146 ```
147
148* Re-generate `BUILD.gn` files by running:
149 `tools/crates/run_gnrt.py gen`
150
danakj98bec162023-11-21 14:55:02151# Updating existing third-party crates
152
Lukasz Anforowicz85528a62024-03-20 19:12:53153Third-party crates will get updated semi-automatically through the process
154described in
155[`../tools/crates/create_update_cl.md`](../tools/crates/create_update_cl.md).
Lukasz Anforowiczc8ebad82025-05-22 20:51:41156If you nevertheless need to manually update a crate to its latest minor or major
157version, then follow the steps below. To facilitate easier review, we recommend
158uploading separate patchsets for 1) manual changes, and 2) tool-driven,
159automated changes.
Lukasz Anforowicz85528a62024-03-20 19:12:53160
danakj98bec162023-11-21 14:55:021611. Change directory to the root `src/` dir of Chromium.
Dominik Röttschesa07a5532024-01-24 19:16:231621. Update the versions in `//third_party/rust/chromium_crates_io/Cargo.toml`.
Lukasz Anforowiczc8ebad82025-05-22 20:51:41163 * `vpython3 ./tools/crates/run_gnrt.py update <crate name>`.
164 * Under the hood this invokes `cargo update` and accepts the same
165 [command line parameters](https://doc.rust-lang.org/cargo/commands/cargo-update.html#update-options).
166 In particular, you may need to specify `--breaking` when working on
167 major version updates.
danakj98bec162023-11-21 14:55:021681. Download any updated crate's files:
169 * `./tools/crates/run_gnrt.py vendor`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551701. Add the downloaded files to git:
danakj98bec162023-11-21 14:55:02171 * `git add -f third_party/rust/chromium_crates_io/vendor`
172 * The `-f` is important, as files may be skipped otherwise from a
173 `.gitignore` inside the crate.
danakj98bec162023-11-21 14:55:021741. Generate the `BUILD.gn` files
175 * `vpython3 ./tools/crates/run_gnrt.py gen`
176 * Or, directly through (nightly) cargo:
177 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt gen`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551781. Add the generated files to git:
Lukasz Anforowiczc8ebad82025-05-22 20:51:41179 * `git add third_party/rust`
danakjbb4d0c772023-10-13 13:22:28180
181### Directory structure for third-party crates
182
183The directory structure for a crate "foo" version 3.4.2 is:
Lukasz Anforowiczc8ebad82025-05-22 20:51:41184
danakjbb4d0c772023-10-13 13:22:28185```
186//third_party/
187 rust/
danakj98bec162023-11-21 14:55:02188 foo/ (for the "foo" crate)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55189 v3/ (version 3.4.2 maps to the v3 epoch)
danakjbb4d0c772023-10-13 13:22:28190 BUILD.gn (generated by gnrt gen)
danakj98bec162023-11-21 14:55:02191 README.chromium (generated by gnrt vendor)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55192 chromium_crates_io/
193 vendor/
Lukasz Anforowiczc8ebad82025-05-22 20:51:41194 foo-v3 (crate sources downloaded from crates.io)
danakj98bec162023-11-21 14:55:02195 patches/
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55196 foo/ (patches for the "foo" crate)
Lukasz Anforowiczb2b4b1232025-04-25 16:22:33197 0001-Some-changes.diff
danakjbb4d0c772023-10-13 13:22:28198 0002-Other-changes.diff
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55199 Cargo.toml
200 Cargo.lock
201 gnrt_config.toml
danakjbb4d0c772023-10-13 13:22:28202```
203
danakj6e25f742022-12-01 21:47:42204## Writing a wrapper for binding generation
205
206Most Rust libraries will need a more C++-friendly API written on top of them in
danakjbb4d0c772023-10-13 13:22:28207order to generate C++ bindings to them. The wrapper library can be placed
208in `//third_party/rust/<cratename>/<epoch>/wrapper` or at another single place
209that all C++ goes through to access the library. The [CXX](https://cxx.rs) is
210used to generate bindings between C++ and Rust.
danakj6e25f742022-12-01 21:47:42211
212See
danakjbb4d0c772023-10-13 13:22:28213[`//third_party/rust/serde_json_lenient/v0_1/wrapper/`](
214https://source.chromium.org/chromium/chromium/src/+/main:third_party/rust/serde_json_lenient/v0_1/wrapper/)
215and
216[`//components/qr_code_generator`](
217https://source.chromium.org/chromium/chromium/src/+/main:components/qr_code_generator/;l=1;drc=b185db5d502d4995627e09d62c6934590031a5f2)
218for examples.
danakj6e25f742022-12-01 21:47:42219
danakjbb4d0c772023-10-13 13:22:28220Rust libraries should use the
221[`rust_static_library`](
222https://source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_static_library.gni)
223GN template (not the built-in `rust_library`) to integrate properly into the
224mixed-language Chromium build and get the correct compiler options applied to
225them.
danakj6e25f742022-12-01 21:47:42226
Lukasz Anforowiczdcdb524a2025-03-24 19:26:41227See `rust-ffi.md` for information on C++/Rust FFI.
danakj6e25f742022-12-01 21:47:42228
Tatsuyuki Ishib3425ab02025-04-10 19:02:20229# Unstable features
230
231Unstable features are **unsupported** by default in Chromium. Any use of an
232unstable language or library feature should be agreed upon by the Rust toolchain
Lukasz Anforowiczc8ebad82025-05-22 20:51:41233team before enabling it. See
234[`tools/rust/unstable_rust_feature_usage.md`](../tools/rust/unstable_rust_feature_usage.md)
235for more details.
Tatsuyuki Ishib3425ab02025-04-10 19:02:20236
danakj3d037ff2024-11-07 19:31:41237# Logging
Adrian Taylor91eaa362024-02-09 14:17:03238
danakj3d037ff2024-11-07 19:31:41239Use the [log](https://docs.rs/log) crate's macros in place of base `LOG`
240macros from C++. They do the same things. The `debug!` macro maps to
241`DLOG(INFO)`, the `info!` macro maps to `LOG(INFO)`, and `warn!` and `error!`
242map to `LOG(WARNING)` and `LOG(ERROR)` respectively. The additional `trace!`
243macro maps to `DLOG(INFO)` (but there is [WIP to map it to `DVLOG(INFO)`](
244https://chromium-review.googlesource.com/c/chromium/src/+/5996820)).
245
246Note that the standard library also includes a helpful
247[`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro which writes
248everything about a variable to `stderr`.
249
250Logging may not yet work in component builds:
251[crbug.com/374023535](https://crbug.com/374023535).
252
253# Tracing
254
255TODO: [crbug.com/377915495](https://crbug.com/377915495).
256
danakj6e25f742022-12-01 21:47:42257# Using VSCode
258
2591. Ensure you're using the `rust-analyzer` extension for VSCode, rather than
260 earlier forms of Rust support.
danakjbb4d0c772023-10-13 13:22:282612. Run `gn` with the `--export-rust-project` flag, such as:
262 `gn gen out/Release --export-rust-project`.
danakj6e25f742022-12-01 21:47:422633. `ln -s out/Release/rust-project.json rust-project.json`
2644. When you run VSCode, or any other IDE that uses
265 [rust-analyzer](https://rust-analyzer.github.io/) it should detect the
266 `rust-project.json` and use this to give you rich browsing, autocompletion,
267 type annotations etc. for all the Rust within the Chromium codebase.
danakjf3d7f372023-12-07 18:17:122685. Point rust-analyzer to the rust toolchain in Chromium. Otherwise you will
269 need to install Rustc in your system, and Chromium uses the nightly
270 compiler, so you would need that to match. Add the following to
271 `.vscode/settings.json` in the Chromium checkout:
272 ```
273 {
274 // The rest of the settings...
275
276 "rust-analyzer.cargo.extraEnv": {
277 "PATH": "../../third_party/rust-toolchain/bin:$PATH",
278 }
279 }
280 ```
281 This assumes you are working with an output directory like `out/Debug` which
282 has two levels; adjust the number of `..` in the path according to your own
283 setup.
Adrian Taylorc5fbb572023-11-21 14:25:42284
285# Using cargo
286
287If you are building a throwaway or experimental tool, you might like to use pure
288`cargo` tooling rather than `gn` and `ninja`. Even then, you may choose
289to restrict yourself to the toolchain and crates that are already approved for
Lukasz Anforowiczc8ebad82025-05-22 20:51:41290use in Chromium, by
Adrian Taylorc5fbb572023-11-21 14:25:42291
Lukasz Anforowiczc8ebad82025-05-22 20:51:41292* Using `tools/crates/run_cargo.py` (which will use
293 Chromium's `//third_party/rust-toolchain/bin/cargo`)
294* Configuring `.cargo/config.toml` to ask to use the crates vendored
295 into Chromium's `//third_party/rust/chromium_crates_io`.
Adrian Taylorc5fbb572023-11-21 14:25:42296
Lukasz Anforowiczc8ebad82025-05-22 20:51:41297An example of how this can work can be found in
298https://crrev.com/c/6320795/5.
David Adriand8918692024-12-12 22:02:50299
300[interop-rust-doc]: https://docs.google.com/document/d/1kvgaVMB_isELyDQ4nbMJYWrqrmL3UZI4tDxnyxy9RTE/edit?tab=t.0#heading=h.fpqr6hf3c3j0