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
- WORKSPACE
- 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
- File
3. Best Practices
- A project should always be able to run
bazel build //...
andbazel 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 https://docs.bazel.build/versions/1.2.0/tutorial/java.html
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
- the
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/bookingGraph.in
dot -Tsvg < bookingGraph.in > 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
java_binary( name = "ProjectRunner", srcs = ["src/main/java/com/example/ProjectRunner.java"], main_class = "com.example.ProjectRunner", deps = [":greeter"], ) java_library( name = "greeter", srcs = ["src/main/java/com/example/Greeting.java"], )
- 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
java_binary(
name = "runner",
srcs = ["Runner.java"],
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
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
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
java_binary(
// 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
java_library(
name = "animal",
srcs = ["src/main/java/com/abhi/Animal.java"],
// 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
Reference
- Bazel best practice https://docs.bazel.build/versions/main/best-practices.html
- Bazel Overview https://docs.bazel.build/versions/1.2.0/bazel-overview.html
- Java Tutorial https://docs.bazel.build/versions/1.2.0/tutorial/java.html
- How to specify targets to build https://docs.bazel.build/versions/main/guide.html#target-patterns
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 stone2paul@gmail.com
文章标题:Bazel Intro
文章字数:918
本文作者:Leilei Chen
发布时间:2021-12-22, 10:05:15
最后更新:2021-12-22, 10:07:14
原始链接:https://www.llchen60.com/Bazel-Intro/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。