diff options
-rw-r--r-- | site/assets/change-garlic.png | bin | 0 -> 12562 bytes | |||
-rw-r--r-- | site/assets/dirty-unmark.png | bin | 0 -> 11577 bytes | |||
-rw-r--r-- | site/assets/dirty.png | bin | 0 -> 13124 bytes | |||
-rw-r--r-- | site/assets/recipe.png | bin | 0 -> 12041 bytes | |||
-rw-r--r-- | site/blog/_posts/2015-07-23-tree-trimming.md | 52 |
5 files changed, 52 insertions, 0 deletions
diff --git a/site/assets/change-garlic.png b/site/assets/change-garlic.png Binary files differnew file mode 100644 index 0000000000..d283d0bd86 --- /dev/null +++ b/site/assets/change-garlic.png diff --git a/site/assets/dirty-unmark.png b/site/assets/dirty-unmark.png Binary files differnew file mode 100644 index 0000000000..0c6df0cd02 --- /dev/null +++ b/site/assets/dirty-unmark.png diff --git a/site/assets/dirty.png b/site/assets/dirty.png Binary files differnew file mode 100644 index 0000000000..7a45144d76 --- /dev/null +++ b/site/assets/dirty.png diff --git a/site/assets/recipe.png b/site/assets/recipe.png Binary files differnew file mode 100644 index 0000000000..4e31044df5 --- /dev/null +++ b/site/assets/recipe.png diff --git a/site/blog/_posts/2015-07-23-tree-trimming.md b/site/blog/_posts/2015-07-23-tree-trimming.md new file mode 100644 index 0000000000..203785aa35 --- /dev/null +++ b/site/blog/_posts/2015-07-23-tree-trimming.md @@ -0,0 +1,52 @@ +--- +layout: posts +title: Trimming your (build) tree +--- + +_Reposted from [@kchodorow's blog](http://www.kchodorow.com/blog/2015/07/23/trimming-the-build-tree-with-bazel/)._ + +[Jonathan Lange](https://twitter.com/mumak) wrote a [great blog +post](https://jml.io/2015/07/bazel-correct-reproducible-fast-builds.html) about +how Bazel caches tests. Basically: if you run a test, change your code, then run +a test again, the test will only be rerun if you changed something that could +actually change the outcome of the test. Bazel takes this concept pretty far to +minimize the work your build needs to do, in some ways that aren't immediately +obvious. + +Let's take an example. Say you're using Bazel to "build" rigatoni arrabiata, +which could be represented as having the following dependencies: + +<img src="/assets/recipe.png"/> + +Each food is a library which depends on the libraries below it. Suppose you +change a dependency, like the garlic: + +<img src="/assets/change-garlic.png"/> + +Bazel will stat the files of the "garlic" library and notice this change, and +then make a note that the things that depend on "garlic" may have also changed: + +<img src="/assets/dirty.png"/> + +The fancy term for this is "invalidating the upward transitive closure" of the +build graph, aka "everything that depends on a thing might be dirty." Note that +Bazel already knows that this change doesn't affect several of the libraries +(rigatoni, tomato-puree, and red-pepper), so they definitely don't have to be +rebuilt. + +Bazel will then evaluate the "sauce" node and figures out if its output has +changed. This is where the secret sauce (ha!) happens: if the output of the +"sauce" node hasn't changed, Bazel knows that it doesn't have to recompile +rigatoni-arrabiata (the top node), because none of its direct dependencies +changed! + +<img src="/assets/dirty-unmark.png"/> + +The sauce node is no longer “maybe dirty” and so its reverse dependencies +(rigatoni-arrabiata) can also be marked as clean. + +In general, of course, changing the code for a library will change its compiled +form, so the "maybe dirty" node will end up being marked as "yes, dirty" and +re-evaluated (and so on up the tree). However, Bazel's build graph lets you +compile the bare minimum for a well-structured library, and in some cases avoid +compilations altogether. |