Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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 under stress.

  • Next to the test.log file produced by your test, you can find a test.xml file. This file contains specific information on each test run and its status, as well as timing information.

  • The -v argument to dev test will result in more verbose logging as well as more detailed information written to the test.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 builds dev 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 if bin is in your PATH, 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 additionally make lintshort as dev'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 your cockroach repo.

  • Tired of running .dev gen bazel? Set the ALWAYS_RUN_GAZELLE env-var to automatically run ./dev gen bazel before every dev test or dev build incantation. Note this does add a tiny delay – noticeable when iterating on small tests through dev test.

    • i.e. echo 'export ALWAYS_RUN_GAZELLE=1' >> ~/.zshrc

  • bazel will fail with an error like ccache: error: Failed to create temporary file for /home/alyshanjahani/.ccache/tmp/message_li.stdout: Read-only file system. To avoid this you should get the ccache links out of your PATH manually (i.e. uninstall ccache).

    • 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

...