Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Epic] Build Materialize with Bazel #26796

Open
2 of 10 tasks
ParkMyCar opened this issue Apr 24, 2024 · 2 comments
Open
2 of 10 tasks

[Epic] Build Materialize with Bazel #26796

ParkMyCar opened this issue Apr 24, 2024 · 2 comments
Assignees
Labels
A-build Area: build systems (Bazel, Rust, etc.) Epic [Auto] Multi-stage issue

Comments

@ParkMyCar
Copy link
Member

ParkMyCar commented Apr 24, 2024

Product outcome

CI becomes much faster, increasing developer productivity.

Currently almost all CI builds must first build Materialize from scratch which at the moment takes 25 - 30 minutes. Only then can we begin to run our test suite, where most targets run in ~10 minutes, with a few ("cargo test", "MySQL CDC Resumption", "cloudtest") taking another 20-30. All in all CI runs take ~60 minutes.

The biggest problem is building everything from scratch, most PRs are quite small and with proper caching should take <5 minutes to build. Then if we run all of our tests CI would end up taking 25-35 minutes. If we can shard or speedup the three slow test targets (which a naively we should be able to), we could get CI end-to-end running in ~15 minutes.

Discovery

We started a Slack channel (wg-compile-times) regarding compile times as a whole, there are generally three different approaches we could take:

  1. sccache - This wraps Cargo/rustc and gives it remote caching abilities. AFAIU we tried this a few years ago and among several issues the biggest blocker is the Cargo itself is bad at caching. It will spuriously decide it needs to rebuild something at which point sccache provides no benefit.
  2. bazel - A distributed build system from Google, a fork of their internal tool blaze. Totally separate from Cargo, invokes rustc (and other compilers) directly, creates a build graph and tracks everything that is part of your build, designed to provide hermetic builds which are great for caching.
  3. buck2 - A new distributed build system from Meta, successor to buck, which (rumor has it) was based on Bazel, the two are very similar.

I have previous experience with bazel and spent a few hours playing with buck2. buck2 is exciting! It's written in Rust and looks to provide a more modern interface, but unfortunately it's just not as mature as bazel. There isn't as much documentation, there are fewer open source rules sets, and there doesn't seem to be as large of a community (e.g. see BazelCon and their Slack) which just makes it a harder tool to use.

Work items

Database V0

Tasks

Note: As far as I can tell testsuites like sqllogictest and testdrive rely on the outputs from the Build - <arch> steps, and from there use mzcompose. So once the build steps use Bazel these other testsuites should see the benefits "for free".

Database Vx

In no specific order, these are follow up items we could do once a Bazel build system is in good working order.

Tasks

Cloud

Tasks

Decision log

  • 1 January 1970. Issue created.
@ParkMyCar ParkMyCar added the Epic [Auto] Multi-stage issue label Apr 24, 2024
@ParkMyCar ParkMyCar self-assigned this Apr 24, 2024
@ParkMyCar
Copy link
Member Author

cc @chaas @guswynn

I dumped all of the tasks I could think of, but they could definitely be broken down further and probably more added. Feel free to edit this however you see fit!

@guswynn
Copy link
Contributor

guswynn commented Apr 26, 2024

@ParkMyCar looks like a good start!

@ParkMyCar ParkMyCar added the A-build Area: build systems (Bazel, Rust, etc.) label May 10, 2024
ParkMyCar added a commit that referenced this issue May 10, 2024
This PR adds Bazel build rules for all of our required C dependencies,
and a
[`build_test`](https://github.com/bazelbuild/bazel-skylib/blob/main/docs/build_test_doc.md)
to make sure things are setup correctly. Note: this test does not yet
run in CI. Specifically it adds build rules for:

* `bzip2`
* `jemalloc`
* `lz4`
* `zlib`
* `zstd`
* `rocksdb` (which includes `snappy`)
* `librdkafka`
* `protoc` (we include the `protobuf` repo which has its own build rule)

It also pulls a few new rulesets into the `WORKSPACE` that are required
to build the C deps, specifically:

* `bazel-skylib`
* `rules_cc`
* `rules_pkg`

It also restructures the `/bazel` directory a bit so all C dependencies
are defined in a single folder, and get included into the `WORKSPACE`
via a single macro. Previously `openssl` was the only C dependency it
had it's own folder and own macro flow. Having all C dependencies in one
spot felt cleaner, open to suggestions though!

### Motivation

Makes progress towards
#26796

### Tips for reviewer

<!--
Leave some tips for your reviewer, like:

    * The diff is much smaller if viewed with whitespace hidden.
    * [Some function/module/file] deserves extra attention.
* [Some function/module/file] is pure code movement and only needs a
skim.

Delete this section if no tips.
-->

### Checklist

- [ ] This PR has adequate test coverage / QA involvement has been duly
considered. ([trigger-ci for additional test/nightly
runs](https://trigger-ci.dev.materialize.com/))
- [ ] This PR has an associated up-to-date [design
doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md),
is a design doc
([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)),
or is sufficiently small to not require a design.
  <!-- Reference the design in the description. -->
- [ ] If this PR evolves [an existing `$T ⇔ Proto$T`
mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md)
(possibly in a backwards-incompatible way), then it is tagged with a
`T-proto` label.
- [ ] If this PR will require changes to cloud orchestration or tests,
there is a companion cloud PR to account for those changes that is
tagged with the release-blocker label
([example](MaterializeInc/cloud#5021)).
<!-- Ask in #team-cloud on Slack if you need help preparing the cloud
PR. -->
- [ ] This PR includes the following [user-facing behavior
changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note):
- <!-- Add release notes here or explicitly state that there are no
user-facing behavior changes. -->
ParkMyCar added a commit that referenced this issue May 13, 2024
This PR gets Bazel running in CI. Specifically it does the following:

1. Adds `bazel` to the `ci-builder` image
2. Tweaks `rules_foreign_cc` so we can bootstrap `make` on Linux
3. Adds a new test group to the Nightly pipeline that invokes `bazel
test //...` and uses the remote cache introduced in
MaterializeInc/i2#1847
* The only tests we have right now are a `build_test` to make sure our C
dependencies successfully build.

[Nightly
run](https://buildkite.com/materialize/nightly/builds/7739#018f64f9-8e46-467c-bd1a-cb4ef2a964f8),
if you look at the retries you'll see the tests weren't actually run,
Bazel returned cached results!

### Hermetic Builds

This isn't yet testing hermeticy of our builds, to do that we need to
[add a
sysroot](https://steven.casagrande.io/articles/sysroot-generation-toolchains-llvm)
to our toolchain so Bazel can find system headers, and ideally we don't
even use `ci-builder` but instead have a separate bazel-only image. But
I figured this was a good first step!

### Motivation

Related to #26796

### Checklist

- [ ] This PR has adequate test coverage / QA involvement has been duly
considered. ([trigger-ci for additional test/nightly
runs](https://trigger-ci.dev.materialize.com/))
- [ ] This PR has an associated up-to-date [design
doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md),
is a design doc
([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)),
or is sufficiently small to not require a design.
  <!-- Reference the design in the description. -->
- [ ] If this PR evolves [an existing `$T ⇔ Proto$T`
mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md)
(possibly in a backwards-incompatible way), then it is tagged with a
`T-proto` label.
- [ ] If this PR will require changes to cloud orchestration or tests,
there is a companion cloud PR to account for those changes that is
tagged with the release-blocker label
([example](MaterializeInc/cloud#5021)).
<!-- Ask in #team-cloud on Slack if you need help preparing the cloud
PR. -->
- [x] This PR includes the following [user-facing behavior
changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note):
  - N/a
ParkMyCar added a commit that referenced this issue May 28, 2024
This PR adds the initial setup for building Rust code/Cargo projects
with Bazel.

### Motivation

Progress towards
#26796

### Tips for reviewer

This PR is split into individual parts which can be reviewed separately:

1. Rust setup in the `WORKSPACE`
    * Add `rules_rust` to our `WORKSPACE`
    * Define a `crates_repository` for all of our external dependencies
    * Add an explainer to the `README` what `crate_repository` is
* Adds and uses our own little `rust_toolchain` macro that allows us to
greatly slim down the size of the Rust toolchain, and thus startup time.
2. Adds support for running `cxx` in Bazel. This is a little tricky
because the [suggested](https://cxx.rs/build/bazel.html) approach to
running `cxx` in Bazel is to build and invoke the command line tool.
    * Pull down the command line tool from `crates.io`
    * Use `rules_rust` to build the tool
* Add a custom `rust_cxx_bridge` macro that makes it easy to invoke the
tool
* Note: I really tried to avoid doing all of this and allowing `cxx`
within a build script to run, but ran into a bunch of issues with
resolving parts of the C toolchain. The approach we take is what's
recommended by the author of `cxx`.
3. Add the necessary
[annotations](http://bazelbuild.github.io/rules_rust/crate_universe.html#crateannotation)
for the Rust crates that depend on C libraries, so we can link against
the libraries built by Bazel and not a build script.
* This also involved tweaking a couple of the `BUILD` files for our C
dependencies, and I added a `BUILD` file for `protobuf-native` that uses
the `cxx` infra in the previous commit.
4. Adds the lock files generated by `crates_repository`, this commit can
be entirely ignored.

### Checklist

- [ ] This PR has adequate test coverage / QA involvement has been duly
considered. ([trigger-ci for additional test/nightly
runs](https://trigger-ci.dev.materialize.com/))
- [ ] This PR has an associated up-to-date [design
doc](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/README.md),
is a design doc
([template](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/design/00000000_template.md)),
or is sufficiently small to not require a design.
  <!-- Reference the design in the description. -->
- [ ] If this PR evolves [an existing `$T ⇔ Proto$T`
mapping](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/command-and-response-binary-encoding.md)
(possibly in a backwards-incompatible way), then it is tagged with a
`T-proto` label.
- [ ] If this PR will require changes to cloud orchestration or tests,
there is a companion cloud PR to account for those changes that is
tagged with the release-blocker label
([example](MaterializeInc/cloud#5021)).
<!-- Ask in #team-cloud on Slack if you need help preparing the cloud
PR. -->
- [x] This PR includes the following [user-facing behavior
changes](https://github.com/MaterializeInc/materialize/blob/main/doc/developer/guide-changes.md#what-changes-require-a-release-note):
  - N/a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-build Area: build systems (Bazel, Rust, etc.) Epic [Auto] Multi-stage issue
Projects
None yet
Development

No branches or pull requests

2 participants