Introduction
As I mentioned in the April 2025 HardenedBSD Status Report, I had attended a small hackathon with a few FreeBSD developers. This hackathon was focused on providing basic support for optional userland components written in Rust. This is a status report for that work.
For those following along, we now have a feature branch (hardened/current/rust-in-base) for the Rust work.
Originally, I had intended to write a ubiquitous, generic "optional support for userland components written in other languages, starting with Rust." Alan, Warner, and I came up with something that looks different, specific to Rust.
Alan brought in a number of vendored dependencies. These dependencies live in the vendor/rust subdirectory of the src tree. He also created a src-specific Rust workspace. All optional installable userland components live in that Rust workspace.
We introduced a new BSD makefile, located at share/mk/bsd.rust.mk, that enables building a Rust application during buildworld. As of this writing, we only support building and installing Rust applications. Supporting library crates is planned (we would like to be able to build/install library crates that expose an FFI, like for C/C++ compatibility). Normal library crates build and install just fine. Support for cdylib Rust library crates specifically is what's missing, but is desired and planned.
We do NOT currently support Rust in the kernel. Kernel support requires more work that we deemed out-of-scope for this initial proof-of-concept/work-in-progress patchset. We also do NOT support building multiple programs in the same BSD Makefile (like with bsd.progs.mk), though that is also a desired feature.
The current patchset does support pkgbase.
Implementation
For Rust userland components, instead of including , you would include . share/mk/bsd.rust.mk is self-contained, doing much of the same work that share/mk/bsd.prog.mk performs.
The entire logic depends on a new src.conf knob: OPTIONAL_TOOLCHAINS. This variable should contain rust-cargo. If OPTIONAL_TOOLCHAINS does not contain "rust-cargo", the build of Rust components is skipped.
We rely on Cargo for building the application and its vendored dependencies. All crates that an application depends on lives in the vendor/rust subdirectory. When building, Cargo is instructed NOT to reach out to Internet-facing resources (the --offline flag is passed to cargo). Meaning, all crates that the to-be-built application depends on MUST be imported in to the `vendor/rust` subdirectory in the src tree.
env(1) is used to change directory to the to-be-built binary crate. It appears cargo can get confused when using the --path argument.
At buildworld time, cargo will build the vendored crates on which the component depends and the component itself. At installworld time, cargo will install the component to its rightful place.
Example Components
Several application crates have been imported into the hardened/current/rust-in-base branch. These are:
- usr.bin/freebsd-geom-exporter
- usr.bin/jail_exporter
- usr.bin/nfs-exporter
- usr.sbin/gstat
As of this writing, these example components (and the crates on which they depend) are not planned for upstreaming. They simply serve as good examples while we develop the underlying optional Rust-in-base support.
Next Steps
We still have a bunch of work left to do. The following list might not be complete, but it's comprised of the things I'd like to work on next.
- Support for library crates as buildable/installable components. Specifically, support for cdylib library crates.
- Support for building multiple Rust applications with a single Makefile (provide something akin to bsd.progs.mk).
- Develop firmer guidlines on how to perform vendor imports of crates. This could already be a solved problem, given that FreeBSD already performs vendor imports of certain (non-Rust) components.
- Support for installing manual pages, include files, and other auxiliary files.
Upstreaming
Once we feel confident in the overall approach, we will open a patch review in Phabricator. I believe the patchset, in its current state, is not well-suited for a formal review in Phabric. At the very least, the "next steps" items above need to be addressed.