DEV Community

Cover image for Experimentations on Bazel: intro
David Bernard
David Bernard

Posted on • Updated on

Experimentations on Bazel: intro

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
git init
git add .
git commit -m ":tada: let's go"
Enter fullscreen mode Exit fullscreen mode

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

GitHub logo 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)