Bazel Intro

1. What is Bazel?

  • Bazel is a build and test tool built that supports building and testing multiple projects for multiple languages and build outputs

  • What

    • Build and Test tool similar to Make, Maven, Gradle
    • Caches all the previously done work, tests or builds faster everytime
    • Support multi languages, multi platforms,
    • Support large code base across multi repos
    • build, test, and query to trace dependencies in the code
  • Why

    • scales
    • multi platform
  • How

    • Need a BUILD file

2. Concepts

  • Workspace - With WORKSPACE
    • dir contains the source file
    • considered as root
    • a blank text file, which identifies the directory and its content as a Bazel workspace
    • at the root of the project’s directory structure
  • Repos - With WORKSPACE
    • External repos are defined in the WORKSPACE file using workspace rules
  • Packages - With BUILD
    • A package is defined as a directory containing a file named BUILD or BUILD.bazel
    • which reside beneath top level directory in the ws
    • This file has instructions on how to run or build or test the project
  • Rules
    • written using a DSL named Starlark
    • thus are built for certain language already like rules_java, etc.
  • Targets
    • Pkg is container, element of pkg —- target
    • Most targets are files or rules
      • File
        • source files - written by people
        • generated files — generated by build tool
      • rule
        • specify relationship between set of inputs and output
        • output are always generated files

3. Best Practices

  • A project should always be able to run bazel build //... and bazel test //...
  • You may declare third party dependencies
    • either declare them as remote repositories in the WORKSPACE file
    • or put them in a directory called third_party under workspace directory
  • everything should be built from source whenever possible, instead of depending on a library so file, we should create a BUILD file and build so from its sources, then depend on that target
  • for project specific options, use the configuration file under workspace/.bazelrc
  • every directory that contains buildable files should be a package

4. Build a Java Project

4.1 Bazel Jave Basic

  • Refer

  • build rule tells bazel how to build the desired outputs, executable binaries or libraries

    • the java binary rule tells bazel to build a jar file and a wrapper shell script
  • bazel build //:ProjectRunner

    • the // part is the location of our BUILD file relative to the root of the workspace
    • ProjectRunner is the target name we define in the BUILD file
  • we could review our dependency graph by using

    • bazel query --notool_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
// generate graph for class in use, and output as a svg file 
bazel query  --notool_deps --noimplicit_deps "deps(//booking)" --output graph > /Users/lchen1/Documents/ 

dot -Tsvg < > graph.svg

4.2 Specify multiple build targets

  • Package Splits

    • for larger project, we may want to split into multiple targets and packages to allow for fast incremental builds, this could also speed up builds by building multiple parts of a project at once

        name = "ProjectRunner",
        srcs = ["src/main/java/com/example/"],
        main_class = "com.example.ProjectRunner",
        deps = [":greeter"],
        name = "greeter",
        srcs = ["src/main/java/com/example/"],
  • with this configuration, bazel will first build greeter library, then the projectRunner binary
    • deps attribute tells bazel the greeter library is required to build the projectRunner binary

4.3 Use multiple packages

    name = "runner",
    srcs = [""],
    main_class = "com.example.cmdline.Runner",
    deps = ["//:greeter"]
  • To make sure above works, we need to let greeter be visible to cmdline.Runner
    • Let the resource owner set the visibility attribute
    • we need to do this cause Bazel by default makes target only visible to other targets in the same BUILD file
    • bazel uses target visibility to prevent issues such as libraries containing implementation details leaking into public APIs
    name = "greeter",
    srcs = ["src/main/java/com/example/"],
    visibility = ["//src/main/java/com/example/cmdline:__pkg__"],

4.4 Use labels to reference targets

  • Bazel uses target labels to reference targets
    • //:ProjectRunner
    • sync as follow:
      • //path/to/package:target-name
  • when referencing targets within the same BUILD file, we can skip the // workspace root identifier and just use :target_name

5. E.G

  • java_binary
    • pre defined rule telling bazel to create a binary when a target is invoked
        // target name 
    name = "mymain",
        // all source files, passed as glob, inside the fully qualified directory names on classpath 
    srcs = glob(["src/main/java/com/abhi/*.java"]),
        // main runner class 
    main_class = "com.abhi.MyMain",
        // dependent classes/ interfaces to be included, not part of srcs 
    deps = ["//another-dir:animal"]
  • java_library
    • pre-defined to create library as the name suggests
    name = "animal",
    srcs = ["src/main/java/com/abhi/"],
        // if other class is implemented in a different pkg, it has to be visible to main-dir 
    visibility = ["//main-dir:__pkg__"]
  • CLI Reference
    • bazel build //main-dir:mymain
      • // means a valid package name
      • mymain is the target name


  1. Bazel best practice
  2. Bazel Overview
  3. Java Tutorial
  4. How to specify targets to build

Command-Line Reference


文章标题:Bazel Intro


本文作者:Leilei Chen

发布时间:2021-12-22, 10:05:15

最后更新:2021-12-22, 10:07:14


版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。