Adding a Rust crate to Thunderbird
To add new Rust code to Thunderbird, first create a new lib crate under
comm/rust, and add the Rust code there.
In this example, we’ll call the crate example_crate, meaning it will live at
comm/rust/example_crate.
Next, modify comm/rust/Cargo.toml to add the crate to the members of the Cargo
workspace:
...
[workspace]
members = [ ..., 'example_crate', ...]
...
Building the crate
If the crate needs to expose symbols, either via FFI or XPCOM, it must be
exposed by the gkrust crate. gkrust is the crate which is hooked into
Thunderbird’s build system, and can expose other crates to be built and linked
alongside it.
Not every crate requires this. For example, if a crate only exists only to be a dependency for other Rust crates (and neither C++ nor JavaScript code will directly interact with it), it can skip this step.
To get example_crate included, let’s add it as a path dependency:
cd comm/rust/gkrust
cargo add example_crate --path ../example_crate
Now let’s expose the crate to the build system. We do this by exposing it as an
extern crate from gkrust in comm/rust/gkrust/src/lib.rs:
...
extern crate example_crate;
...
Now ./mach build should build example_crate. To learn about how to use XPCOM
in your Rust code to interact with the rest of Thunderbird, head over to
Using XPCOM within a Rust component.
Managing a crate’s dependencies
Adding dependencies on internal crates
Dependencies on crates which are internal to Thunderbird (and by extension
Firefox) should be specified as path dependencies. For example, if
example_crate were to depend on the xpcom crate, which lives in
xpcom/rust/xpcom, it would be added with:
cd comm/rust/example_crate
cargo add xpcom --path ../../../xpcom/rust/xpcom
Synchronizing dependencies
Manually changing the dependencies of a crate in comm/rust (by e.g. manually
editing its Cargo.toml file) means comm/rust/Cargo.lock becomes out of date,
which gets in the way of building. To fix this, run:
./mach tb-rust sync