Bazel { fast, correct } choose two Klaus Aehlig August 1920, 2017 - - PowerPoint PPT Presentation

bazel
SMART_READER_LITE
LIVE PREVIEW

Bazel { fast, correct } choose two Klaus Aehlig August 1920, 2017 - - PowerPoint PPT Presentation

Bazel How Bazel Works Extending Bazel Summary Bazel { fast, correct } choose two Klaus Aehlig August 1920, 2017 Bazel How Bazel Works Extending Bazel Summary Bazel What is Bazel? Bazel How Bazel Works Extending Bazel Summary


slide-1
SLIDE 1

Bazel How Bazel Works Extending Bazel Summary

Bazel

{fast, correct} – choose two Klaus Aehlig August 19–20, 2017

slide-2
SLIDE 2

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel?

slide-3
SLIDE 3

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel?

  • Bazel is a build tool

I.e., organizes compiling/creating artifacts (libraries, executables, . . . ) from sources.

slide-4
SLIDE 4

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel?

  • Bazel is a build tool

I.e., organizes compiling/creating artifacts (libraries, executables, . . . ) from sources.

  • open-source since 2015
slide-5
SLIDE 5

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel?

  • Bazel is a build tool

I.e., organizes compiling/creating artifacts (libraries, executables, . . . ) from sources.

  • open-source since 2015
  • . . . but a longer (a decade) history as a Google-internal tool
slide-6
SLIDE 6

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

slide-7
SLIDE 7

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

slide-8
SLIDE 8

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
slide-9
SLIDE 9

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
slide-10
SLIDE 10

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
  • . . . without losing correctness

(i.e., all artifacts as if freshly built from source)

slide-11
SLIDE 11

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
  • . . . without losing correctness

(i.e., all artifacts as if freshly built from source)

  • declarative style of BUILD files
slide-12
SLIDE 12

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
  • . . . without losing correctness

(i.e., all artifacts as if freshly built from source)

  • declarative style of BUILD files
  • separation of concerns

writing code vs choosing correct (cross) compiling strategy

slide-13
SLIDE 13

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
  • . . . without losing correctness

(i.e., all artifacts as if freshly built from source)

  • declarative style of BUILD files
  • separation of concerns

writing code vs choosing correct (cross) compiling strategy

  • central maintenance point for build rules
slide-14
SLIDE 14

Bazel How Bazel Works Extending Bazel Summary

Bazel

What is Bazel? And why yet another *make?

  • Scales to large repos with complex dependencies

(e.g., 104.5 engineers working on 107 files)

  • aggressive parallelism
  • aggressive caching
  • . . . without losing correctness

(i.e., all artifacts as if freshly built from source)

  • declarative style of BUILD files
  • separation of concerns

writing code vs choosing correct (cross) compiling strategy

  • central maintenance point for build rules
  • generic tool

Can bring your own declarative rules for BUILD files

slide-15
SLIDE 15

Bazel How Bazel Works Extending Bazel Summary

An Example

Let’s look at a helloworld example.

slide-16
SLIDE 16

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c

  • main program helloworld.c
slide-17
SLIDE 17

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c

  • main program helloworld.c

#include "lib/hello.h" int main(int argc, char **argv) { greet("world"); return 0; }

slide-18
SLIDE 18

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c

  • main program helloworld.c,

depending on a library

slide-19
SLIDE 19

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

#ifndef HELLO H #define HELLO H void greet(char *); #endif

slide-20
SLIDE 20

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c) #include "hello.h" #include <stdio.h> void greet(char *it) { printf("Hello %s!", it); }

slide-21
SLIDE 21

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c)

slide-22
SLIDE 22

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c WORKSPACE

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c)

  • then we can have an empty WORKSPACE file
slide-23
SLIDE 23

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c WORKSPACE BUILD BUILD

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c)

  • then we can have an empty WORKSPACE file

. . . and the following declarative BUILD files cc binary( name="helloworld", srcs=["helloworld.c"], deps=["//lib:hello"], ) cc library( name="hello", srcs=glob(["*.c"]), hdrs=glob(["*.h"]), )

slide-24
SLIDE 24

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c WORKSPACE BUILD BUILD

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c)

  • then we can have an empty WORKSPACE file

. . . and the following declarative BUILD files cc binary( name="helloworld", srcs=["helloworld.c"], deps=["//lib:hello"], ) cc library( name="hello", srcs=glob(["*.c"]), hdrs=glob(["*.h"]), ) Note: CC, link options, host/target architecture, etc, taken care of elsewhere.

slide-25
SLIDE 25

Bazel How Bazel Works Extending Bazel Summary

An Example

helloworld.c lib hello.h hello.c WORKSPACE BUILD BUILD

  • main program helloworld.c,

depending on a library

  • a library with headers (lib/hello.h)

. . . and implementation (lib/hello.c)

  • then we can have an empty WORKSPACE file

. . . and the following declarative BUILD files cc binary( name="helloworld", srcs=["helloworld.c"], deps=["//lib:hello"], ) cc library( name="hello", srcs=glob(["*.c"]), hdrs=glob(["*.h"]), )

slide-26
SLIDE 26

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

slide-27
SLIDE 27

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

  • load the BUILD files (all that are needed)
slide-28
SLIDE 28

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

  • load the BUILD files (all that are needed)
  • analyze dependencies between targets
slide-29
SLIDE 29

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

  • load the BUILD files (all that are needed)
  • analyze dependencies between targets
  • from rules generate action graph
slide-30
SLIDE 30

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

  • load the BUILD files (all that are needed)
  • analyze dependencies between targets
  • from rules generate action graph
  • execute actions (unless already cached)
slide-31
SLIDE 31

Bazel How Bazel Works Extending Bazel Summary

Overview of a bazel build

Have declarative descriptions. What happens at bazel build?

  • load the BUILD files (all that are needed)
  • analyze dependencies between targets
  • from rules generate action graph
  • execute actions (unless already cached)
  • n subsequent builds, update the graphs

(client-server architecture to keep graph in memory)

slide-32
SLIDE 32

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld

command

Now let’s see what happens if we want to build :helloworld. . .

slide-33
SLIDE 33

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld

command target

We look at the target :helloworld

slide-34
SLIDE 34

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld //

command target pkg

We look at the target :helloworld, in package //

slide-35
SLIDE 35

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD

command target pkg file system

We look at the target :helloworld, in package //, in file BUILD

slide-36
SLIDE 36

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c

command target pkg file system

Two declared dependencies

slide-37
SLIDE 37

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c

command target pkg file system

Two declared dependencies . . . and implicit dependency on the C tool chain (not drawn in this diagram)

slide-38
SLIDE 38

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD

command target pkg file system

Two declared dependencies, one in a different package Note: We construct dependency graph over package boundaries! (no recursive calling)

slide-39
SLIDE 39

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"])

command target pkg file system glob

We discover glob expressions

slide-40
SLIDE 40

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

command target pkg file system glob

We discover glob expressions, and read the directory.

slide-41
SLIDE 41

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

command target pkg file system glob

artifact

The rules tell us, which artifacts to build.

slide-42
SLIDE 42

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

BUILD helloworld.c lib/ BUILD hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

file system

artifact

slide-43
SLIDE 43

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Dependencies

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

command target pkg file system glob

artifact

slide-44
SLIDE 44

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

command target pkg file system glob

artifact

slide-45
SLIDE 45

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

command target pkg file system glob

artifact

slide-46
SLIDE 46

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

command target pkg file system glob

artifact

slide-47
SLIDE 47

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

command target pkg file system glob

artifact

slide-48
SLIDE 48

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

command target pkg file system glob

artifact

slide-49
SLIDE 49

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

lib/foo.pic.o

command target pkg file system glob

artifact

slide-50
SLIDE 50

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

lib/foo.pic.o

command target pkg file system glob

artifact

slide-51
SLIDE 51

Bazel How Bazel Works Extending Bazel Summary

Example cont’d: Adding a File

build //:helloworld //:helloworld // BUILD //lib:hello helloworld.c //lib lib/ BUILD glob(["*.c"]) glob(["*.h"]) hello.c hello.h

lib/libhello.{a,so} lib/hello.pic.o helloworld helloworld.pic.o

foo.c

lib/foo.pic.o

command target pkg file system glob

artifact

slide-52
SLIDE 52

Bazel How Bazel Works Extending Bazel Summary

Actions

slide-53
SLIDE 53

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building
slide-54
SLIDE 54

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time

slide-55
SLIDE 55

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

slide-56
SLIDE 56

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
slide-57
SLIDE 57

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself
slide-58
SLIDE 58

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel

slide-59
SLIDE 59

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel

  • so, no .done foo targets,
  • and only reading declared inputs
slide-60
SLIDE 60

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel

slide-61
SLIDE 61

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

slide-62
SLIDE 62

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

  • isolated environment
  • only declared inputs/tools present
  • only declared outputs copied out
slide-63
SLIDE 63

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

  • isolated environment
  • only declared inputs/tools present
  • only declared outputs copied out
  • depending on OS, different approaches

(none, temp dir, chroot, . . . )

slide-64
SLIDE 64

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

slide-65
SLIDE 65

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

  • bonus: remote execution
slide-66
SLIDE 66

Bazel How Bazel Works Extending Bazel Summary

Actions

  • action do the actual work of building

. . . and hence take the most time particularly interesting to avoid unnecessary actions

  • dependency graph shows if prerequisites changed
  • caching of input/output-relation itself

! requires all inputs/outputs to be known to bazel facilitate correct I/O by running actions in “sandboxes”

  • bonus: remote execution

⇒ enables shared caches. (Several close-by engineers working on the same code base!)

slide-67
SLIDE 67

Bazel How Bazel Works Extending Bazel Summary

Skylark

slide-68
SLIDE 68

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
slide-69
SLIDE 69

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • specialized rules with knowledge about certain languages

cc library, cc binary, java library, java binary, . . .

slide-70
SLIDE 70

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • specialized rules with knowledge about certain languages

cc library, cc binary, java library, java binary, . . .

  • generic ones, in particular genrule

→ just specify a shell command (with $@, $<, . . . ) (basically the only rule available in a Makefile)

slide-71
SLIDE 71

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
slide-72
SLIDE 72

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale
slide-73
SLIDE 73

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

slide-74
SLIDE 74

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • Python-like language (familiar syntax)
  • but restricted to a simple core

without global state, complicated feature, . . . deterministic, hermetic evaluation

slide-75
SLIDE 75

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

slide-76
SLIDE 76

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example
slide-77
SLIDE 77

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example

. . . and step by step develop rules for L

AT

EX

slide-78
SLIDE 78

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example

. . . and step by step develop rules for L

AT

EX

  • typeset pdf files from textual description (*.tex files)
slide-79
SLIDE 79

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example

. . . and step by step develop rules for L

AT

EX

  • typeset pdf files from textual description (*.tex files)
  • the *.tex files can pull in other files

(.sty, images, diagrams, \input other .tex-files)

slide-80
SLIDE 80

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example

. . . and step by step develop rules for L

AT

EX

  • typeset pdf files from textual description (*.tex files)
  • the *.tex files can pull in other files

(.sty, images, diagrams, \input other .tex-files)

  • pdflatex main.tex && ...
slide-81
SLIDE 81

Bazel How Bazel Works Extending Bazel Summary

Skylark

  • Bazel has built-in rules
  • but adding specialized rule for every language doesn’t scale

need ways to expend BUILD language: Skylark

  • To get a feeling for the language, let’s do an example

. . . and step by step develop rules for L

AT

EX

slide-82
SLIDE 82

Bazel How Bazel Works Extending Bazel Summary

Macros

slide-83
SLIDE 83

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach
slide-84
SLIDE 84

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach
  • latex-rule is given by an entry point and a list of source files
slide-85
SLIDE 85

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach
  • latex-rule is given by an entry point and a list of source files
  • have a script to typeset this

(tmpdir, correct number of pdflatex runs, . . . )

slide-86
SLIDE 86

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)
slide-87
SLIDE 87

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): run = str(Label("//rules/latex:runlatex.sh")) native.genrule( name = name + " pdf", srcs = srcs, cmd = ("sh $(location " + run +") $@" + " $(location " + main + ") $(SRCS)",

  • uts = [name + ".pdf"],

tools = [run], )

slide-88
SLIDE 88

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): ... native.genrule(...)

slide-89
SLIDE 89

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): ... native.genrule(...)

  • can be loaded in BUILD files
slide-90
SLIDE 90

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): ... native.genrule(...)

  • can be loaded in BUILD files

load("//rules/latex/latex.bzl", "latex")

slide-91
SLIDE 91

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): ... native.genrule(...)

  • can be loaded in BUILD files

load("//rules/latex/latex.bzl", "latex") latex( name = "slides", main = "main.tex", srcs = ["diagram.ps"], )

slide-92
SLIDE 92

Bazel How Bazel Works Extending Bazel Summary

Macros

  • First approach (entry + files; script)

write a macro in rules/latex/latex.bzl def latex(name="", main="", srcs=[]): ... native.genrule(...)

  • can be loaded in BUILD files

load("//rules/latex/latex.bzl", "latex") latex( name = "slides", main = "main.tex", srcs = ["diagram.ps"], ) central maintenance; convenience-targets (xpdf, pdfnup, . . . )

slide-93
SLIDE 93

Bazel How Bazel Works Extending Bazel Summary

File Groups

slide-94
SLIDE 94

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files
slide-95
SLIDE 95

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files

“That slide with all the diagrams belonging to it”

slide-96
SLIDE 96

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files
slide-97
SLIDE 97

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files
  • Built-in rule: filegroup

filegroup(name = "foosection", srcs = ["foosection.tex", ":diagram"]) ... filegroup( name = "barchapter", srcs = ["barchapter.tex", ":foosection", ...])

slide-98
SLIDE 98

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files
  • Built-in rule: filegroup

filegroup(name = "foosection", srcs = ["foosection.tex", ":diagram"]) ... filegroup( name = "barchapter", srcs = ["barchapter.tex", ":foosection", ...])

  • Gives a label to a set of files (with traversal order)

single maintenance point

slide-99
SLIDE 99

Bazel How Bazel Works Extending Bazel Summary

File Groups

  • Start thinking in groups of files
  • Built-in rule: filegroup

filegroup(name = "foosection", srcs = ["foosection.tex", ":diagram"]) ... filegroup( name = "barchapter", srcs = ["barchapter.tex", ":foosection", ...])

  • Gives a label to a set of files (with traversal order)

single maintenance point

  • Can be nested, inserting the entries

(but implemented in a memory-efficient way!)

slide-100
SLIDE 100

Bazel How Bazel Works Extending Bazel Summary

Rules

slide-101
SLIDE 101

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits
slide-102
SLIDE 102

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file)

slide-103
SLIDE 103

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) latex = rule( attrs = { "main" : attr.label(allow files=True), "srcs" : attr.label list(allow files=True), " runlatex": attr.label( cfg="host", allow files=True, default = Label("//rules/latex:runlatex.sh")), },

  • utputs = {"pdf" : "%{name}.pdf"},

implementation = latex impl, )

slide-104
SLIDE 104

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): inputs = depset(ctx.files.srcs) \ | depset(ctx.files.main) inputs file = ctx.new file( ctx.label.name + ".allinputs") ctx.file action( inputs file, "\n".join([f.path for f in inputs]) ) ...

slide-105
SLIDE 105

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... ctx.file action(...) ...

slide-106
SLIDE 106

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... ctx.file action(...)

  • utput = ctx.new file(ctx.label.name + ".pdf")

args = [f.path for f in ctx.files. runlatex] \ + [output.path] \ + [f.path for f in ctx.files.main[:1]] \ + [inputs file.path] ...

slide-107
SLIDE 107

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... ctx.file action(...)

  • utput = ctx.new file(ctx.label.name + ".pdf")

args = ... ...

slide-108
SLIDE 108

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... args = ... ...

slide-109
SLIDE 109

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... args = ... ctx.action( inputs = list(inputs | depset([inputs file]) | depset(ctx.files. runpdflatex)),

  • utputs = [output],

command = ["/bin/sh"] + args, mnemonic = "PdfLatex", progress message = "Typesetting %s as pdf" \ % ctx.label, )

slide-110
SLIDE 110

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... args = ... ctx.action(...)

slide-111
SLIDE 111

Bazel How Bazel Works Extending Bazel Summary

Rules

  • Next: missing argument checking, argv limits Rules

(also changing the script, now expecting an arguments file) def latex impl(ctx): ... args = ... ctx.action(...)

  • Additional benefits
  • Proper quoting for free
  • Meaningful progress messages
slide-112
SLIDE 112

Bazel How Bazel Works Extending Bazel Summary

Providers

slide-113
SLIDE 113

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions
slide-114
SLIDE 114

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
slide-115
SLIDE 115

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
slide-116
SLIDE 116

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action is simple

includefile = rule(...) def includefile impl(ctx):

  • utput = ctx.new file(ctx.label.name + ".tex")

deps = depset(ctx.files.srcs) includes = ["\\input{%s}\n" % f.short path for f in deps] ctx.file action(output = output, content = "".join(includes))

slide-117
SLIDE 117

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action

includefile = rule(...) def includefile impl(ctx):

  • utput = ctx.new file(ctx.label.name + ".tex")

deps = depset(ctx.files.srcs) includes = ["\\input{%s}\n" % f.short path for f in deps] ctx.file action(output = output, content = "".join(includes)) Using this new file implicitly depends on the sources!

slide-118
SLIDE 118

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

LtxInfo = provider() includefile = rule(...) def includefile impl(ctx):

  • utput = ctx.new file(ctx.label.name + ".tex")

deps = depset(ctx.files.srcs) includes = ["\\input{%s}\n" % f.short path for f in deps] ctx.file action(output = output, content = "".join(includes)) return [LtxInfo(refd = depset([output])|deps)] Using this new file implicitly depends on the sources!

slide-119
SLIDE 119

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

LtxInfo = provider() includefile = rule(...) def includefile impl(ctx):

  • utput = ctx.new file(ctx.label.name + ".tex")

deps = depset(ctx.files.srcs) includes = ["\\input{%s}\n" % f.short path for f in deps] ctx.file action(output = output, content = "".join(includes)) return [LtxInfo(refd = depset([output])|deps)] Using this new file implicitly depends on the sources!

slide-120
SLIDE 120

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

LtxInfo = provider() includefile = rule(...) def includefile impl(ctx):

  • utput = ctx.new file(ctx.label.name + ".tex")

deps = depset(ctx.files.srcs) includes = ["\\input{%s}\n" % f.short path for f in deps] ctx.file action(output = output, content = "".join(includes)) return [LtxInfo(refd = depset([output])|deps)]

slide-121
SLIDE 121

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

... def includefile impl(ctx): ... return [LtxInfo(refd = depset([output])|deps)]

slide-122
SLIDE 122

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

def includefile impl(ctx): ... return [LtxInfo(refd = depset([output])|deps)]

slide-123
SLIDE 123

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

def includefile impl(ctx): ... return [LtxInfo(refd = depset([output])|deps)]

  • Consuming rules can use it

def latex impl(ctx): inputs = depset(ctx.files.srcs) \ | depset(ctx.files.main) ...

slide-124
SLIDE 124

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

def includefile impl(ctx): ... return [LtxInfo(refd = depset([output])|deps)]

  • Consuming rules can use it

def latex impl(ctx): inputs = depset(ctx.files.srcs) \ | depset(ctx.files.main) for i in ctx.attr.srcs: if LtxInfo in i: inputs = inputs | i[LtxInfo].refd ...

slide-125
SLIDE 125

Bazel How Bazel Works Extending Bazel Summary

Providers

  • Start to collect macro definitions, organized in file groups
  • Want to \input such a file group. . .
  • file action plus provider

def includefile impl(ctx): ... return [LtxInfo(refd = depset([output])|deps)]

  • Consuming rules can use it

def latex impl(ctx): inputs = depset(ctx.files.srcs) \ | depset(ctx.files.main) for i in ctx.attr.srcs: if LtxInfo in i: inputs = inputs | i[LtxInfo].refd ...

slide-126
SLIDE 126

Bazel How Bazel Works Extending Bazel Summary

Summary

  • declarative BUILD files
  • generic tool: can bring your own rules

(Python-like extension language; can start easy)

  • all dependencies tracked correctness

(sandboxes to ensure all I/O is known)

  • full knowledge enables fast builds

(caching of actions, remote execution, parallelism, . . . )

  • open-source
slide-127
SLIDE 127

Bazel How Bazel Works Extending Bazel Summary

Try Bazel

Try Bazel yourself.

  • Homepage https://bazel.build/
  • Mailing lists
  • bazel-discuss@googlegroups.com
  • bazel-dev@googlegroups.com
  • Repository and issue tracker

https://github.com/bazelbuild/bazel

  • IRC #bazel on irc.freenode.net
  • Release key fingerprint

71A1 D0EF CFEB 6281 FD04 37C9 3D59 19B4 4845 7EE0 Thanks for your attention. Questions?