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.
Unusual way
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
version.txt
- bazel & github-action
- bazel & rust (w/o cargo)
- bazel & flutter
- bazel & ml project
Get started
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
The file WORKSPACE.bazel
is used to mark the root folder of the workspace, and to include some setup, but we'll ignore this aspect now.
The file 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 Blaze
.
touch BUILD.bazel
The file BUILD.bazel
marks the folder as a package. It is used to host rule that defined how to build outputs.
The file 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
The ...
is not something to replace, it's like a wildcard to say everything
.
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-bin
, bazel-out
, bazel-testlogs
, 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: article/0_intro
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)