blob: 95837536b2b97adef4c5e32f896eb301cd55ddef [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
124# Updating existing third-party crates
125
Lukasz Anforowicz85528a62024-03-20 19:12:53126Third-party crates will get updated semi-automatically through the process
127described in
128[`../tools/crates/create_update_cl.md`](../tools/crates/create_update_cl.md).
Lukasz Anforowiczc8ebad82025-05-22 20:51:41129If you nevertheless need to manually update a crate to its latest minor or major
130version, then follow the steps below. To facilitate easier review, we recommend
131uploading separate patchsets for 1) manual changes, and 2) tool-driven,
132automated changes.
Lukasz Anforowicz85528a62024-03-20 19:12:53133
danakj98bec162023-11-21 14:55:021341. Change directory to the root `src/` dir of Chromium.
Dominik Röttschesa07a5532024-01-24 19:16:231351. Update the versions in `//third_party/rust/chromium_crates_io/Cargo.toml`.
Lukasz Anforowiczc8ebad82025-05-22 20:51:41136 * `vpython3 ./tools/crates/run_gnrt.py update <crate name>`.
137 * Under the hood this invokes `cargo update` and accepts the same
138 [command line parameters](https://doc.rust-lang.org/cargo/commands/cargo-update.html#update-options).
139 In particular, you may need to specify `--breaking` when working on
140 major version updates.
danakj98bec162023-11-21 14:55:021411. Download any updated crate's files:
142 * `./tools/crates/run_gnrt.py vendor`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551431. Add the downloaded files to git:
danakj98bec162023-11-21 14:55:02144 * `git add -f third_party/rust/chromium_crates_io/vendor`
145 * The `-f` is important, as files may be skipped otherwise from a
146 `.gitignore` inside the crate.
danakj98bec162023-11-21 14:55:021471. Generate the `BUILD.gn` files
148 * `vpython3 ./tools/crates/run_gnrt.py gen`
149 * Or, directly through (nightly) cargo:
150 `cargo run --release --manifest-path tools/crates/gnrt/Cargo.toml --target-dir out/gnrt gen`
Lukasz Anforowicz8452bd8d2023-11-28 23:31:551511. Add the generated files to git:
Lukasz Anforowiczc8ebad82025-05-22 20:51:41152 * `git add third_party/rust`
danakjbb4d0c772023-10-13 13:22:28153
154### Directory structure for third-party crates
155
156The directory structure for a crate "foo" version 3.4.2 is:
Lukasz Anforowiczc8ebad82025-05-22 20:51:41157
danakjbb4d0c772023-10-13 13:22:28158```
159//third_party/
160 rust/
danakj98bec162023-11-21 14:55:02161 foo/ (for the "foo" crate)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55162 v3/ (version 3.4.2 maps to the v3 epoch)
danakjbb4d0c772023-10-13 13:22:28163 BUILD.gn (generated by gnrt gen)
danakj98bec162023-11-21 14:55:02164 README.chromium (generated by gnrt vendor)
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55165 chromium_crates_io/
166 vendor/
Lukasz Anforowiczc8ebad82025-05-22 20:51:41167 foo-v3 (crate sources downloaded from crates.io)
danakj98bec162023-11-21 14:55:02168 patches/
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55169 foo/ (patches for the "foo" crate)
Lukasz Anforowiczb2b4b1232025-04-25 16:22:33170 0001-Some-changes.diff
danakjbb4d0c772023-10-13 13:22:28171 0002-Other-changes.diff
Lukasz Anforowicz8452bd8d2023-11-28 23:31:55172 Cargo.toml
173 Cargo.lock
174 gnrt_config.toml
danakjbb4d0c772023-10-13 13:22:28175```
176
danakj6e25f742022-12-01 21:47:42177## Writing a wrapper for binding generation
178
179Most Rust libraries will need a more C++-friendly API written on top of them in
danakjbb4d0c772023-10-13 13:22:28180order to generate C++ bindings to them. The wrapper library can be placed
181in `//third_party/rust/<cratename>/<epoch>/wrapper` or at another single place
182that all C++ goes through to access the library. The [CXX](https://cxx.rs) is
183used to generate bindings between C++ and Rust.
danakj6e25f742022-12-01 21:47:42184
185See
danakjbb4d0c772023-10-13 13:22:28186[`//third_party/rust/serde_json_lenient/v0_1/wrapper/`](
187https://source.chromium.org/chromium/chromium/src/+/main:third_party/rust/serde_json_lenient/v0_1/wrapper/)
188and
189[`//components/qr_code_generator`](
190https://source.chromium.org/chromium/chromium/src/+/main:components/qr_code_generator/;l=1;drc=b185db5d502d4995627e09d62c6934590031a5f2)
191for examples.
danakj6e25f742022-12-01 21:47:42192
danakjbb4d0c772023-10-13 13:22:28193Rust libraries should use the
194[`rust_static_library`](
195https://source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_static_library.gni)
196GN template (not the built-in `rust_library`) to integrate properly into the
197mixed-language Chromium build and get the correct compiler options applied to
198them.
danakj6e25f742022-12-01 21:47:42199
Lukasz Anforowiczdcdb524a2025-03-24 19:26:41200See `rust-ffi.md` for information on C++/Rust FFI.
danakj6e25f742022-12-01 21:47:42201
Tatsuyuki Ishib3425ab02025-04-10 19:02:20202# Unstable features
203
204Unstable features are **unsupported** by default in Chromium. Any use of an
205unstable language or library feature should be agreed upon by the Rust toolchain
Lukasz Anforowiczc8ebad82025-05-22 20:51:41206team before enabling it. See
207[`tools/rust/unstable_rust_feature_usage.md`](../tools/rust/unstable_rust_feature_usage.md)
208for more details.
Tatsuyuki Ishib3425ab02025-04-10 19:02:20209
danakj3d037ff2024-11-07 19:31:41210# Logging
Adrian Taylor91eaa362024-02-09 14:17:03211
danakj3d037ff2024-11-07 19:31:41212Use the [log](https://docs.rs/log) crate's macros in place of base `LOG`
213macros from C++. They do the same things. The `debug!` macro maps to
214`DLOG(INFO)`, the `info!` macro maps to `LOG(INFO)`, and `warn!` and `error!`
215map to `LOG(WARNING)` and `LOG(ERROR)` respectively. The additional `trace!`
216macro maps to `DLOG(INFO)` (but there is [WIP to map it to `DVLOG(INFO)`](
217https://chromium-review.googlesource.com/c/chromium/src/+/5996820)).
218
219Note that the standard library also includes a helpful
220[`dbg!`](https://doc.rust-lang.org/std/macro.dbg.html) macro which writes
221everything about a variable to `stderr`.
222
223Logging may not yet work in component builds:
224[crbug.com/374023535](https://crbug.com/374023535).
225
226# Tracing
227
228TODO: [crbug.com/377915495](https://crbug.com/377915495).
229
danakj6e25f742022-12-01 21:47:42230# Using VSCode
231
2321. Ensure you're using the `rust-analyzer` extension for VSCode, rather than
233 earlier forms of Rust support.
danakjbb4d0c772023-10-13 13:22:282342. Run `gn` with the `--export-rust-project` flag, such as:
235 `gn gen out/Release --export-rust-project`.
danakj6e25f742022-12-01 21:47:422363. `ln -s out/Release/rust-project.json rust-project.json`
2374. When you run VSCode, or any other IDE that uses
238 [rust-analyzer](https://rust-analyzer.github.io/) it should detect the
239 `rust-project.json` and use this to give you rich browsing, autocompletion,
240 type annotations etc. for all the Rust within the Chromium codebase.
danakjf3d7f372023-12-07 18:17:122415. Point rust-analyzer to the rust toolchain in Chromium. Otherwise you will
242 need to install Rustc in your system, and Chromium uses the nightly
243 compiler, so you would need that to match. Add the following to
244 `.vscode/settings.json` in the Chromium checkout:
245 ```
246 {
247 // The rest of the settings...
248
249 "rust-analyzer.cargo.extraEnv": {
250 "PATH": "../../third_party/rust-toolchain/bin:$PATH",
251 }
252 }
253 ```
254 This assumes you are working with an output directory like `out/Debug` which
255 has two levels; adjust the number of `..` in the path according to your own
256 setup.
Adrian Taylorc5fbb572023-11-21 14:25:42257
258# Using cargo
259
260If you are building a throwaway or experimental tool, you might like to use pure
261`cargo` tooling rather than `gn` and `ninja`. Even then, you may choose
262to restrict yourself to the toolchain and crates that are already approved for
Lukasz Anforowiczc8ebad82025-05-22 20:51:41263use in Chromium, by
Adrian Taylorc5fbb572023-11-21 14:25:42264
Lukasz Anforowiczc8ebad82025-05-22 20:51:41265* Using `tools/crates/run_cargo.py` (which will use
266 Chromium's `//third_party/rust-toolchain/bin/cargo`)
267* Configuring `.cargo/config.toml` to ask to use the crates vendored
268 into Chromium's `//third_party/rust/chromium_crates_io`.
Adrian Taylorc5fbb572023-11-21 14:25:42269
Lukasz Anforowiczc8ebad82025-05-22 20:51:41270An example of how this can work can be found in
271https://crrev.com/c/6320795/5.
David Adriand8918692024-12-12 22:02:50272
273[interop-rust-doc]: https://docs.google.com/document/d/1kvgaVMB_isELyDQ4nbMJYWrqrmL3UZI4tDxnyxy9RTE/edit?tab=t.0#heading=h.fpqr6hf3c3j0