Develop with Bazel
Build, test, and run NativeLink with Bazel, the same dev loop CI uses.
The Bazel-based dev loop is the one our CI runs. Use this if you want the most reproducible setup or if your editor integration prefers Bazel.
Prerequisites
- Bazelisk, which reads
.bazelversionand fetches the right Bazel for you. CI runs 9.1.1 and also checks 8.7.0. - A C++ toolchain (clang or gcc) for native dependencies.
- On macOS: XCode command-line tools.
- On Linux, inside the Nix shell, the LRE toolchains link with
mold; outside it Bazel uses whatever the host toolchain provides.
First build
git clone https://github.com/TraceMachina/nativelink
cd nativelink
bazel test //...The first bazel test will take 10-20 minutes as it builds the
toolchain and dependencies. Subsequent builds finish in seconds.
Hooking up your own cache
.bazelrc already defines --config=self_test (remote cache at
grpc://127.0.0.1:50051) and --config=self_execute (remote executor at
grpc://127.0.0.1:50052) for a NativeLink running locally. For any other
endpoint, put the flags in user.bazelrc at the repository root, which
.bazelrc pulls in with try-import and git ignores:
build --remote_cache=grpc://localhost:50051
build --remote_executor=grpc://localhost:50051With a NativeLink cluster running, subsequent builds will hit the cache for any action your team has already produced.
Common commands
# Run all tests.
bazel test //...
# Run one crate's tests/ directory.
bazel test //nativelink-store:integration
# Run the in-file `mod tests` suites, or the doc examples.
bazel test //:unit_tests
bazel test doctests
# Build the server binary. The binary is defined in the root BUILD.bazel,
# so its label is `//:nativelink`; there is no `//nativelink` package.
bazel build //:nativelink
# Run the built binary against a config.
bazel run //:nativelink -- /path/to/config.json5
# Format Rust code. The formatting config uses nightly-only options, so
# stable `cargo fmt` produces different output than CI expects.
bazel run --config=rustfmt @rules_rust//:rustfmtSee the testing guide for what unit_test
and integration actually mean in this repository; they do not mean what
the names suggest.
Editor integration
For rust-analyzer:
bazel run @rules_rust//tools/rust_analyzer:gen_rust_projectThis generates a rust-project.json that VS Code / Helix / your
editor of choice will pick up.
Common pitfalls
- LRE flags are missing:
.bazelrcpulls inlre.bazelrc,nativelink.bazelrc,nixos.bazelrcanddarwin.bazelrcwithtry-import, and the Nix dev shell is what generates them. Withoutnix developthey do not exist, and thetry-means Bazel says nothing about it. See Develop with Nix. - Slow first build with no cache: expected. Subsequent builds reuse Bazel's local cache; pointing at a remote NativeLink cluster makes a fresh clone fast for everyone.
- A new source file builds with Cargo and fails under Bazel: Bazel
enumerates
srcsrather than globbing. Add the file to the crate'sBUILD.bazel, alphabetically.