We’re partway through a migration of our build system to Bazel. Bazel is a modern build system with better performance characteristics and correctness guarantees than we currently have with make
/go build
. Today, you can perform most day-to-day CRDB dev tasks with Bazel rather than with make
-- and for the few tasks that you can’t/don’t know how to do with Bazel, please ask a question or contribute a solution. The Bazel migration is actively in progress and we always accept contributions even for minor/QOL improvements.
NOTE: for specific debugging tips on:
- Build failures, see “How to ensure your code builds with Bazel”
- Test failures, see “How to ensure your tests can run in the Bazel sandbox”
Prerequisites
Follow the directions on "Getting and building CockroachDB from source" or "Building from source on macOS" to get your development environment set up. If you’ve installed everything you need for the make
build, you should already have more than enough for the Bazel build – for example, you don’t actually need Golang installed to build with Bazel (the Bazel build will download Go toolchain bits as needed).
...
--cross
takes an optional argument which is the platform to cross-compile to: --cross=linux
, --cross=windows
, --cross=macos
. dev
will symlink the built binaries into the artifacts
directory in this case.
For more debugging tips on building with Bazel, see “How to ensure your code builds with Bazel”
Running tests
Run ./dev test
with the name of one or more packages to execute all tests from those packages:
...
dev test
has a--stress
flag for running tests understress
.Next to the
test.log
file produced by your test, you can find atest.xml
file. This file contains specific information on each test run and its status, as well as timing information.The
-v
argument todev test
will result in more verbose logging as well as more detailed information written to thetest.xml
.As with
dev build
,dev test
allows you to pass additional arguments directly to Bazel by putting them after--
: for example,dev test pkg/sql/types -- --verbose_failures --sandbox_debug
.To get test results printed as tests are being run add
-v -- --test_output streamed
to the test command.For more tips on debugging test failures, see “How to ensure your tests can run in the Bazel sandbox”
Other tasks
Code Block |
---|
# Run benchmarks for pkg/sql/parser ./dev bench pkg/sql/parser # Open a container running the "bazelbuilder" image. Requires Docker. ./dev builder # Generate code (run this before submitting your PR). ./dev generate # Run lints (WARNING: not all lints work in Bazel yet) ./dev lint # logic tests! ./dev testlogic --files=$FILES --subtests=$SUBTESTS --config=$CONFIG |
...
Since
./dev
always buildsdev
unconditionally before doing anything else, that means there will be a slight delay before your build or test actually begins. Due to caching this pause should never be too long, but if it’s annoying you or you’ve found a way to thrash the cache, you can do:Code Block ./dev build dev
This will place a binary at
bin/dev
and ifbin
is in yourPATH
, you can then omit the leading./
. In this document we’ll always spell./dev
with the leading./
to squash ambiguity and for ease of copy-pasting.
A (hopefully) fast and error proof dev
workflow
TODO(a UI developer): fill in gaps for UI dev workflow
1. Switch to a new branch
2. If your workflow involves an IDE, generate your protos ./dev gen protobuf
Your IDE relies on generated files for many tasks (e.g. code navigation, IntelliSense, debugging), and will complain unless you have re-generated those files.
If you need to re-generate all generated go files, use the slower
dev gen go
If the above fails, run the slowest
./dev gen
to update all of your generated files.You may recall that with
make
, this step was not necessary. If you’re curious why, see this slack thread.
3. Write some code!
If you add new files or imports, run
./dev gen bazel
before compiling or running a test.compilepkg: missing strict dependencies:
is usually the indicator that./dev gen bazel
needs to be re-run.to skip this step, see tip below on
ALWAYS_RUN_GAZELLE
Build the binary:
./dev build short
4. Run a test
On an IDE: your normal workflow should work if your generated files are up to date (See step 2).
From the command line:
./dev test [path/to/pkg] --filter [test_name]
5. Before opening/updating a PR:
Run
dev lint --short
(maybe additionallymake lintshort
asdev
's linter doesn’t have 100% coverage yet)Assert your workspace is clean by running
./dev gen bazel
. If you modified other generated files, run the appropriate./dev gen [file_type]
command.
General Bazel tips
Bazel has a configuration file called .bazelrc. You can put a global configuration file at
~/.bazelrc
or a per-repository file at.bazelrc.user
in the root of yourcockroach
repo.Tired of running
.dev gen bazel
? Set theALWAYS_RUN_GAZELLE
env-var to automatically run./dev gen bazel
before everydev test
ordev build
incantation. Note this does add a tiny delay – noticeable when iterating on small tests throughdev test
.i.e.
echo 'export ALWAYS_RUN_GAZELLE=1' >> ~/.zshrc
bazel
will fail with an error likeccache: error: Failed to create temporary file for /home/alyshanjahani/.ccache/tmp/message_li.stdout: Read-only file system
. To avoid this you should get theccache
links out of yourPATH
manually (i.e. uninstallccache
).Alternatively, if you would like to use Bazel with
ccache
, you can enable support for writing outside the sandbox by adding the following to your$HOME/.bazelrc
or<repo>/.bazelrc.user
file:
For MacOS/Darwin:Code Block build --sandbox_writable_path=/Users/<USER>/Library/Caches/ccache/
For Linux:
Code Block build --sandbox_writable_path=/home/<USER>/.ccache
...