This document describes how to write Rust code in the kernel.
The code is automatically formatted using the
rustfmt tool. This is very
If you contribute from time to time to the kernel, you do not need to learn and remember one more style guide. You will also need less patch roundtrips to land a change.
If you are a reviewer or a maintainer, you will not need to spend time on pointing out style issues anymore.
We use the tool’s default settings. This means we are following the idiomatic Rust style. For instance, we use 4 spaces for indentation rather than tabs.
Typically, you will want to instruct your editor/IDE to format while you type, when you save or at commit time. However, if for some reason you want to reformat the entire kernel Rust sources at some point, you may run:
To check if everything is formatted (printing a diff otherwise), e.g. if you have configured a CI for a tree as a maintainer, you may run:
clang-format for the rest of the kernel,
rustfmt works on
individual files, and does not require a kernel configuration. Sometimes it may
even work with broken code.
rustc is a very helpful compiler, some extra lints and analysis are
clippy, a Rust linter. To enable it, pass
the same invocation you use for compilation, e.g.:
make ARCH=... CROSS_COMPILE=... CC=... -j... CLIPPY=1
At the moment, we do not enforce a “clippy-free” compilation, so you can treat
the output the same way as the extra warning levels for C, e.g. like
Still, we use the default configuration, which is relatively conservative, so
it is a good idea to read any output it may produce from time to time and fix
the pointed out issues. The list of enabled lists will be likely tweaked over
time, and extra levels may end up being introduced, e.g.
Abstractions vs. bindings¶
We don’t have abstractions for all the kernel internal APIs and concepts, but we would like to expand coverage as time goes on. Unless there is a good reason not to, always use the abstractions instead of calling the C bindings directly.
If you are writing some code that requires a call to an internal kernel API or concept that isn’t abstracted yet, consider providing an (ideally safe) abstraction for everyone to use.
Rust code has access to conditional compilation based on the kernel configuration:
#[cfg(CONFIG_X)] // `CONFIG_X` is enabled (`y` or `m`) #[cfg(CONFIG_X="y")] // `CONFIG_X` is enabled as a built-in (`y`) #[cfg(CONFIG_X="m")] // `CONFIG_X` is enabled as a module (`m`) #[cfg(not(CONFIG_X))] // `CONFIG_X` is disabled