<style>
.reveal *:not(pre) > code:not([class]) {
background: #3e3d3280;
border-radius: 5px;
}
.reveal pre > code:not([class]) {
background: #272822;
}
code.inline {
background: #3e3d3280;
border-radius: 20px;
padding-top: 0.5%;
padding-right: 2%;
padding-bottom: 0.5%;
padding-left: 2%;
}
code.bazel {
background: #272822;
}
pre.graphviz {
background: none;
box-shadow: none;
}
.subtext {
font-size:0.6em;
font-style:italic;
}
</style>
<!-- .slide: data-background="https://i.imgur.com/dJHBYEB.png" data-background-repeat="no-repeat" data-background-color="#fff" data-background-size="1000px" data-background-opacity=1 -->
slide: https://hackmd.io/p/S1frKIJo4#/
<div style="font-size: medium; font-style: italic;">
Danny Chang
</div>
----
## Who am I ?
張嘉軒
Danny Chang
_Danny.Chang@dlinkcorp.com_
---
<style>
.reveal section img.thissec {
margin: 0px;
background: none;
border: none;
box-shadow: none;
}
</style>
# Bazel
A open-source build and test tool.
<br>
_makefile_ <img src="https://maven.apache.org/images/maven-logo-black-on-white.png" alt="Maven" height="86" width="340" class="thissec" > <img src="https://upload.wikimedia.org/wikipedia/en/e/ed/Gradle_Logo.png" alt="Gradle" height="148" width="428" class="thissec" >
----
# Why Bazel ?
----
- High-level build language
- Fast and Reliable
- Multi-Platform
- Scalable
- Extensible
---
# Walkthrough
---
# C++
----
## Stage 1:Simple Build
----
## Stage 1:File structure
------
```
examples
└── cpp-tutorial
└── stage1 <---- Current Working Directory
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
```
https://github.com/bazelbuild/examples/
----
## <code class="inline">WORKSPACE</code>
-----
A blank file that defines a project's root.
----
## <code class="inline">BUILD</code>
-----
Tells Bazel how to build.
A `BUILD` file defines a _package_ .
----
_cpp-tutorial/stage1/main/BUILD_
```bazel
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
```
----
<style>
span.subtext {
font-size:0.6em;
font-style:italic;
}
</style>
### <code class="inline">cc_binary</code> is a <span style="color:red;">_target_</span> of type <span style="color:red;">_**Rule**_</span>
-----
Defines the actions perform on inputs.
<span class="subtext">cc_binary、cc_import、cc_library、cc_proto_library、fdo_prefetch_hints、fdo_profile、cc_test、cc_toolchain、cc_toolchain_suite<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
### Dig into <code class="inline">BUILD</code>
```
cc_binary( # <------------ Rule
name = "hello-world", # <---- Target name
srcs = ["hello-world.cc"], # <---- File to be processed
)
```
----
### Build the project
```sh
$ bazel build //main:hello-world
```
<code style="font-size:0.8em; background: #3e3d3280; border-radius: 5px;">//main:hello-world</code><!-- .element: class="fragment" data-fragment-index="1" --> <span style="font-size:0.8em;">is a</span> <!-- .element: class="fragment" data-fragment-index="1" --> <i style="color:red; font-size:0.8em;"> label </i> <!-- .element: class="fragment" data-fragment-index="1" --><span style="font-size:0.8em;">.</span> <!-- .element: class="fragment" data-fragment-index="1" -->
----
### Build the project
```sh
$ bazel build //main:hello-world
```
Build output
<!-- .element: class="fragment" data-fragment-index="1" -->
```sh
Starting local Bazel server and connecting to it...
INFO: Analysed target //main:hello-world (9 packages loaded, 63 targets configured).
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 7.009s, Critical Path: 0.58s
INFO: 2 processes: 2 linux-sandbox.
INFO: Build completed successfully, 4 total actions
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
### Run
```sh
$ bazel-bin/main/hello-world
```
Output
<!-- .element: class="fragment" data-fragment-index="1" -->
```
Hello world
Sun Apr 28 16:49:15 2019
```
<!-- .element: class="fragment" data-fragment-index="1" -->
----
## Stage 2:Multiple Targets
----
## Stage 2:File structure
------
```
examples
└── cpp-tutorial
└── stage2 <---- Current Working Directory
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
└── WORKSPACE
```
----
_cpp-tutorial/stage2/main/BUILD_
```bazel
cc_library( # <------------ Target 1
name = "hello-greet", # <---- Target name
srcs = ["hello-greet.cc"], # <---- File to be processed
hdrs = ["hello-greet.h"], # <---- Header file
)
cc_binary( # <------------ Target 2
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [ # <------------- Dependent libraries
":hello-greet",
],
)
```
----
<style>
.reveal section dd.lowertext {
font-size: 0.6em !important;
}
dd > code {
}
</style>
## Labels
```
//path/to/package:target-name
```
`//` means workspace directory.
<dl>
<dt style="font-size: 0.7em;">skipping:</dt><!-- .element: class="fragment" data-fragment-index="1" -->
<dd class="lowertext">- Targets within same package, skip path.<!-- .element: class="fragment" data-fragment-index="1" --></li>
<dd class="lowertext">- Targets within same <code>BUILD</code> file, skip <code>//</code>. <!-- .element: class="fragment" data-fragment-index="1" --></dt>
</dl>
```bazel
deps = [ <------------- Dependent libraries
":hello-greet",
],
```
<!-- .element: class="fragment" data-fragment-index="1" -->
---
# Java
----
## Stage 1:Simple Build
----
## Stage 1:File structure
------
```
java-tutorial <---- Current Working Directory
├── BUILD <---- First Package
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD <---- Second Package
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java <---- main
└── WORKSPACE
```
----
_java-tutorial/BUILD_
```bazel
java_binary( # <------------ Java Rule
name = "ProjectRunner",
srcs = glob(["src/main/java/com/example/*.java"]),
)
```
`glob` is a helper function to pass a set of files.
----
#### Build
```sh
$ bazel build //:ProjectRunner
```
#### Build Output
<!-- .element: class="fragment" data-fragment-index="1" -->
```sh
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 0.568s, Critical Path: 0.28s
INFO: 1 process: 1 worker.
INFO: Build completed successfully, 5 total actions
```
<!-- .element: class="fragment" data-fragment-index="1" -->
#### Run
<!-- .element: class="fragment" data-fragment-index="2" -->
```sh
$ bazel-bin/ProjectRunner // Output: Hi!
```
<!-- .element: class="fragment" data-fragment-index="2" -->
----
#### Dependency Graph
-----
```graphviz
digraph mygraph {
graph [color="#232323" bgcolor="#232323"]
node [fillcolor=white style=filled shape=box]
edge [color=white]
"//:ProjectRunner"
"//:ProjectRunner" -> "//:src/main/java/com/example/Greeting.java\n//:src/main/java/com/example/ProjectRunner.java"
"//:src/main/java/com/example/Greeting.java\n//:src/main/java/com/example/ProjectRunner.java"
}
```
<span class="subtext" style="text-align:left;">
pros:Sufficient for small projects
<br>cons:Slow incremental builds and lack of extensibility.
</span>
----
## Stage 2:Refined Build
----
_java-tutorial/BUILD_
```bazel
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"],
)
```
----
#### Dependency Graph
-----
```graphviz
digraph mygraph {
graph [color="#232323" bgcolor="#232323"]
node [fillcolor=white style=filled shape=box]
edge [color=white]
"//:ProjectRunner"
"//:ProjectRunner" -> "//:greeter"
"//:ProjectRunner" -> "//:src/main/java/com/example/ProjectRunner.java"
"//:greeter"
"//:greeter" -> "//:src/main/java/com/example/Greeting.java"
"//:src/main/java/com/example/Greeting.java"
"//:src/main/java/com/example/ProjectRunner.java"
}
```
----
## Stage 3:File structure
------
```
java-tutorial <---- Current Working Directory
├── BUILD <---- First Package
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD <---- Second Package
│ │ └── Runner.java <---- main
│ ├── Greeting.java
│ └── ProjectRunner.java
└── WORKSPACE
```
----
<span style="font-size:0.7em;">_java-tutorial/src/main/java/com/example/cmdline/BUILD_</span>
```bazel
java_binary(
name = "runner",
srcs = ["Runner.java"],
main_class = "com.example.cmdline.Runner", # <---- Class of entry point
deps = ["//:greeter"]
)
```
<span style="font-size:0.8em;">`main_class` specifies the class contains main.</span>
----
_java-tutorial/BUILD_
```bazel
java_library (
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
```
<span style="font-size:0.8em;">'Cause targets are only accessible within same `BUILD`, we need to add `visibility` attribute.</span>
----
#### Dependency Graph
-----
```graphviz
digraph mygraph {
graph [color="#232323" bgcolor="#232323"]
node [fillcolor=white style=filled shape=box]
edge [color=white]
"//src/main/java/com/example/cmdline:runner"
"//src/main/java/com/example/cmdline:runner" -> "//src/main/java/com/example/cmdline:Runner.java"
"//src/main/java/com/example/cmdline:runner" -> "//:greeter"
"//:greeter"
"//:greeter" -> "//:src/main/java/com/example/Greeting.java"
"//:src/main/java/com/example/Greeting.java"
"//src/main/java/com/example/cmdline:Runner.java"
}
```
----
#### Build
```sh
$ bazel build //src/main/java/com/example/cmdline:runner
```
#### Build Output
<!-- .element: class="fragment" data-fragment-index="1" -->
```sh
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner.jar
bazel-bin/src/main/java/com/example/cmdline/runner
INFO: Elapsed time: 0.217s, Critical Path: 0.00s
INFO: 0 processes.
INFO: Build completed successfully, 1 total action
```
<!-- .element: class="fragment" data-fragment-index="1" -->
#### Run
<!-- .element: class="fragment" data-fragment-index="2" -->
```sh
$ bazel-bin/src/main/java/com/example/cmdline/runner // Output: Hi!
```
<!-- .element: class="fragment" data-fragment-index="2" -->
---
### Step into Bazel output directory
```sh
$ ll
total 40
drwxrwxr-x ./
drwxrwxr-x ../
lrwxrwxrwx bazel-bin -> /home/chdontu18/.cache/bazel/_bazel_chdontu18/613107f5ff7df42ab30d11644f0cbc5d/execroot/__main__/bazel-out/k8-fastbuild/bin/
lrwxrwxrwx bazel-genfiles -> /home/chdontu18/.cache/bazel/_bazel_chdontu18/613107f5ff7df42ab30d11644f0cbc5d/execroot/__main__/bazel-out/k8-fastbuild/genfiles/
lrwxrwxrwx bazel-java-tutorial -> /home/chdontu18/.cache/bazel/_bazel_chdontu18/613107f5ff7df42ab30d11644f0cbc5d/execroot/__main__/
lrwxrwxrwx bazel-out -> /home/chdontu18/.cache/bazel/_bazel_chdontu18/613107f5ff7df42ab30d11644f0cbc5d/execroot/__main__/bazel-out/
lrwxrwxrwx bazel-testlogs -> /home/chdontu18/.cache/bazel/_bazel_chdontu18/613107f5ff7df42ab30d11644f0cbc5d/execroot/__main__/bazel-out/k8-fastbuild/testlogs/
-rw-rw-r-- BUILD
drwxrwxr-x src/
-rw-rw-r-- WORKSPACE
```
----
### Bazel output directory layout
```
- <workspace-name>/ <== The workspace directory
- bazel-my-project => <...my-project> <== Symlink to execRoot
- bazel-out => <...bin> <== Convenience symlink to outputPath
- bazel-bin => <...bin> <== Convenience symlink to most recent written bin dir $(BINDIR)
- bazel-genfiles => <...genfiles> <== Convenience symlink to most recent written genfiles dir $(GENDIR)
```
---
# End
{"metaMigratedAt":"2023-06-14T21:23:16.668Z","metaMigratedFrom":"YAML","title":"Bazel Intro","breaks":true,"description":"View the slide with \"Slide Mode\".","disqus":"techackmd","slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"2e1c4ed4-9c0b-4e1d-9f92-325b614fc8fc\",\"add\":20108,\"del\":9835}]"}