Building Firefox with Rust code

In May 2015 the Rust programming language reached its 1.0 stability milestone, and various experiments with writing parts of Gecko in Rust began. This page is a rough guide for people working in this area.

See bug 1135640 ('oxidation') for overall tracking of Rust language support.

See the corresponding build system documentation.

Adding Rust code

We generally target stable rust, but sometimes support for new platforms requires special toolchain builds. If you don't have rust already, use the `rustup` tool to install it.

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/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/lib.rs; you would also need to specify the path to that crate in the dependencies section of toolkit/library/rust/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.

Disabling Rust code

Basic support for building Rust code landed in bug 1161339 and it was made the default in bug 1283898. No special action is necessary to enable it. For the time being you can build without optional rust features by adding:

ac_add_options --disable-rust

to your mozconfig. We expect to remove this option as rust implementations become non-optional.

Document Tags and Contributors

 Contributors to this page: rillian, chrisdavidmills, wbamberg
 Last updated by: rillian,