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.

Enabling Rust code

Basic support for building Rust code landed in bug 1161339. It is turned on for official builds on most platforms, but off by default for local builds. If you have rustc in your path you can add:

ac_add_options --enable-rust

to your mozconfig and it will probably work. 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.

If you get an link error on mac with debug builds about 'too many personality types' try rebuilding with `LDFLAGS="-Wl,-no_compact_unwind" ./mach build` as a work-around. We expect this to be resolved in rust 1.12.

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.

Adding Rust code

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/, and those libraries 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/; you would also need to specify the path to that crate in the dependencies section of toolkit/library/rust/Cargo.toml:

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 libraries, 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 somewhat tedious but will eventualy be automated through the cargo vendor extension.

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.

Document Tags and Contributors

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