Bazel is a build tool with a growing popularity, maybe the one I'm looking for (I tried to create my own few years ago). So I read part of its documentation, viewed some talks from introduction to more advanced subjects (BazelCon, Bazel Days,...). I also played a little with it and tried to use it on a "real" project.
This serie of articles collects my notes (present and future), my fights, my fails, and I hope my success during my exploration and learn of Bazel.
If you are looking for a tutorial about how to use Bazel the right way, you're at the wrong place. Because I'm new to Bazel and I want to use it the wrong or at least the unusual way.
The full power of Bazel comes when you embrace it at a whole with all its requirements for actions (reproducible, hermetic, ...). Those requirements are not compatible with lot of ecosystem (eg downloading dependencies on fly, or caching artifacts under
$HOME/.cache), meaning that actions should be recreated to follow bazel's spirit. That takes times, requires some skills, so it's not an immediate job. Lots of company, who migrate to Bazel, had to create tools and bazel's rules (in name for plugin / toolset like in bazel ecosystem). Also IDE and Editors do not provided a friendly experience for non-first citizen build system (eg incremental build, code completion, find reference, import dependencies, ...).
Can I cheat some requirements and being able to use Bazel as a "better" Make (at the cost/sacrifice of which advantages) ?
That is the purpose of my quest and of the following articles.
So why Bazel?
IMHO, Bazel becomes interesting when you want:
- to coordinate actions by input & output, instead of a list of action names. Declaring this output of action "A" is an input of action "B" is better than declaring action "B" depends of action "A"
- to coordinate a multi-language project
- to share an input/output cache between build run, developers,...
The unusual way (hybrid way) can also become a transitive phase to the right way.
What is planned ?
The roadmap / order is not fully defined, but I would like to experiment and to share my notes about:
- create basic custom action: generate
- bazel & github-action
- bazel & rust (w/o cargo)
- bazel & flutter
- bazel & ml project
To not have zero line of code in this introduction, let's go by creating an empty Bazel
workspace (~ top level project in Bazel's terminology), where we'll add
package (~ sub-modules in the Bazel's terminology).
mkdir sandbox_bazel cd sandbox_bazel touch WORKSPACE.bazel
WORKSPACE.bazel is used to mark the root folder of the workspace, and to include some setup, but we'll ignore this aspect now.
WORKSPACE.bazel can also be named
WORKSPACE. The short name is used in the literature (and on lot of projects), the main advantage of the longer is to be explicit about which build tool is targeted because other build tool also used
WORKSPACE name, legacy from a common father
BUILD.bazel marks the folder as a package. It is used to host rule that defined how to build outputs.
BUILD.bazel can also be named
BUILD. The short name is used in the literature (and on lot of projects), the main advantage of the longer is to be explicit about which build tool is targeted because other build tool also used
BUILD name, legacy from a common father
Blaze. And to avoid conflict/issue with existing system that generates
build folder, and
.gitignore file that ignores it, especially on file system that are not really case sensitive (Windows & Mac OS X). Using or not the
.bazel extension as default is a old discussion in the Bazel's community ;-).
Now we have the minimum to build "nothing" with Bazel. So you need to install Bazel'cli. But I recommend you to install bazelisk, it will take care of installing the latest (or the project specific) version of Bazel. In the following articles, codes when you'll see
bazel ... it could also be replaced by
bazelisk ... (in fact some packaging of Bazel installs bazelisk and create an alias). For this step use your favorite way (distribution package system, download from github, homebrew,...).
To document (also used to configure (optional) bazelisk), add a file
.bazelversion with the version of bazel to use.
echo "4.0.0" >.bazelversion
Time to build everything in the workspace, so nothing currently:
❯ bazel build //... INFO: Analyzed 0 targets (0 packages loaded, 0 targets configured). INFO: Found 0 targets... INFO: Elapsed time: 0.047s, Critical Path: 0.00s INFO: 1 process: 1 internal. INFO: Build completed successfully, 1 total action
... is not something to replace, it's like a wildcard to say
We have to use the sub-command
build because bazel cli can do more stuff that
build, as we'll see later.
❯ ls -a1 11:31:07 ./ ../ bazel-bin@ bazel-out@ bazel-sandbox_bazel@ bazel-testlogs@ .bazelversion BUILD.bazel WORKSPACE.bazel
We'll discover what is
bazel-<workspace_name> in the coming articles (I hope).
Now to store the workspace on git:
curl -o .gitignore https://www.toptal.com/developers/gitignore/api/bazel git init git add . git commit -m ":tada: let's go"
Conclusion of intro 🤔
That's all for this serie's introduction. Thanks for reading until the end, sorry for this first non-technical post. The sandbox_bazel is hosted on github, use tag to have the expected view at end of article:
davidB / sandbox_bazel
explorations of bazel, support for a serie of articles and to experiment stuff on bazel.
I'm learning Bazel, so I'll do mistake, please share your corrections and suggestions, other readers/learners (and I) will "Thank you" in advance.
Top comments (0)