You might have been lead here by reading CONTRIBUTING.md. If not, please read that as well! That will give you the high level overview; this is the document is all about the needed elbow grease you'll have to apply.
Buck2 is written in Rust, and currently requires a nightly toolchain. You
need rustup installed to provision the necessary
version of rustc
and cargo
as a result.
You can either build buck2
from a clone of the Buck2 repo (this will cause
rustup/cargo to install the right nightly version of rustc
):
git clone https://github.com/facebook/buck2.git
cd buck2/
cargo install --path=app/buck2
Or, alternatively, install it directly from GitHub:
rustup install nightly-2023-04-23
cargo +nightly-2023-04-23 install --git https://github.com/facebook/buck2.git buck2
Side note: using Nix to compile the source
NOTE: You shouldn't need to do this if you already have a tool such as
rustup
installed. The following instructions are for Nix and NixOS users specifically.
Most Nix users provision tools directly with Nix itself, rather than rustup;
the Buck2 source code includes a flake.nix
file, which can be used to compile
Buck2 itself via cargo
:
git clone https://github.com/facebook/buck2.git
cd buck2/
nix develop . # add 'rustc' and 'cargo' to $PATH
cargo build --release --path=app/buck2
A Nix package (e.g. nix build .#buck2
) does not yet exist.
NOTE: You can probably skip this if you're on a typical "Tier 1" operating system like aarch64/x86_64 Linux, Windows, or macOS.
Buck2 uses Protocol Buffers quite extensively in its internals, and also for
communication with remote systems for tasks like Remote Execution. Therefore
there are .proto
files in the codebase that need to be compiled to Rust code.
Due to the architecture of how Protocol Buffers works, you'll need the protoc
compiler available in order to do this.
For the 3 major operating systems — Linux, Windows, and macOS — the
cargo
build uses prebuilt protoc
binaries from
protoc-bin-vendored crate to
accomplish this. So everything should transparently work with no intervention
needed and just running cargo build
is enough.
But there are non-Tier-1 operating systems where Buck2 might be used, and the
above crate won't work, and you'll need to override it. You will need to install
protoc
from some other source. Doing that is out of scope for this document.
But once you've done so, you can use the following two environment variables
before running cargo build
to override the crate:
BUCK2_BUILD_PROTOC
, the path to theprotoc
binaryBUCK2_BUILD_PROTOC_INCLUDE
, the path to the protocol buffers header file directory
Assuming you have your protocol buffers installation located in /opt/protobuf
,
you can do the following:
export BUCK2_BUILD_PROTOC=/opt/protobuf/bin/protoc
export BUCK2_BUILD_PROTOC_INCLUDE=/opt/protobuf/include
Buck2 should then build with cargo
using the steps above.
Beyond the obvious (well-tested, easy to read) we prefer guidelines that are automatically enforced, e.g. through Rustfmt, Clippy or the custom linter we have written. Some rules:
- Follow standard
rustfmt
conventions. - Use the utilities from Gazebo where they are useful, in particular,
dupe
. - Prefer
to_owned
to convert&str
toString
. - Qualify
anyhow::Result
rather thanuse anyhow::Result
. - Most errors should be returned as
anyhow::Result
. Inspecting errors outside tests and the top-level error handler is strongly discouraged. - Most errors should be constructed with
thiserror
derivingenum
values, not rawanyhow!
. - We use the
derivative
library to derive thePartialEq
andHash
traits when some fields should be ignored. - Prefer
use crate::foo::bar
overuse super::bar
oruse crate::foo::*
, apart from test modules which often haveuse super::*
at the top. - Modules should either have submodules or types/functions/constants, but not both.
- Prefer
anyhow::Error
for checking internal invariants that are maintained between multiple files, whilepanic!
/unreachable!
are reasonable if the invariant is file-local.
- Names (of variables, targets, files, etc) should be quoted with backticks,
e.g.
Variable `x` not defined
. - Lists should use square brackets, e.g.
Available targets: [`aa`, `bb`]
. - Error messages should start with an upper case letter. Error messages should not end with a period.