Building Firefox with Rust code

This article is obsolete. Please instead refer to the documentation found within the modern Firefox build system documentation; specifically, the section called Including Rust Code in Firefox.

Firefox uses the Rust programming language extensively. This page is a rough guide for people using Rust in Firefox. See also the documentation on this topic on the Oxidation wiki page.

Adding Rust code

We generally target stable Rust, but sometimes issues temporarily require a beta or custom toolchain build. Our goal is to always ship a Firefox release build with a stable Rust toolchain release. If you don't have rust already, use the rustup tool to install it and update as new releases become available, or use the ./mach bootstrap command.

The build system will generate a special 'rust unified library' crate, compiled to a static library (libgkrust.a) which is in turn linked into XUL, so all public symbols will be available to C++ code.

If you have new Rust libraries that code in libxul calls directly, then you should add the appropriate extern crate lines in toolkit/library/rust/shared/lib.rs, and add those libraries (crates) as dependencies in toolkit/library/rust/Cargo.toml. If you want to call code in the "e10s" crate, you would add:

extern crate e10s;

to toolkit/library/rust/shared/lib.rs; you would also need to specify the path to that crate in the dependencies section of toolkit/library/rust/shared/Cargo.toml:

[dependencies]
e10s = { path = "../../../../path/from/srcdir/e10s" }

The e10s crate must also be checked into the tree at the appropriate path. If the e10s crate depends on any other crates, their sources must also be checked into the tree, and e10s's Cargo.toml must have path attributes for each of its dependencies, and so on. This is automated by the mach vendor command, which installs the dependencies in third_party/rust. Be sure the licenses of all dependent crates are compatible.

Cargo.lock files have also been checked in, so you will need to update those as well when appropriate.

Crates for unit tests can be added in a similar fashion to the files in toolkit/library/gtest/rust/.

If your crate has optional features that aren't normally turned on, you are strongly encouraged to remove dependencies for those features when importing code so the build system doesn't require that (unused) code to live in-tree.

The build system will check that there's only one copy of a given crate in a build; this was a deliberate decision to try and avoid code bloat in libxul. If this turns out to be a serious problem in practice, we can look into ways of relaxing that check.

If you need to locally patch a third-party crate, you'll need to add a [replace] section to the referencing Cargo.toml to declare that the vendored source shouldn't match the upstream release. This works even if you use the existing vendored source location, but be aware that other vendor updates could clobber your patch in that case.

Testing Rust code

There's a simple linkage unit test in the tree. You can use it to check that Rust is enabled and working with your build setup.

./mach gtest rust.*

Look for the rust.CallFromCpp test to pass, along with any others.