bytes.zone

buck2 basics

Brian Hicks, August 7, 2023

I just finished an experiment with Buck 2 at work. We didn't end up using it, but it was more for organizational reasons than technical ones. I'll be watching the project to see if it would make sense to use in the future!

One thing that held me back during the early part of the experiment was not having enough learning material around the basics. That makes sense: it's a pretty new project (at least in this iteration) and there are a lot of concepts to learn.

So instead of teaching things from first principles, I want to run head-first into getting something simple set up. We won't have any more functionality than we could get with some simple make rules, but since the person who does the work does the learning I hope this will be helpful! That said, keep in mind that I'm no expert—just some person who learned enough to get stuff done!

The Simplest Possible Rule

We'll start off with the simplest possible thing: a file that says "Hello, World!" We'll use a genrule for this, which lets you say what shell commands to run to produce some file. In the root BUCK file, write this:

genrule(
  name = "some-target",
  out = "target-file",
  cmd = "echo 'Hello, World!' > $OUT",
)

That configures a target named some-target that you can build with buck2 build //:some-target. If you add --show-output to that, it'll tell you where the file is, and if you cat buck-out/v2/gen/root/213ed1b7ab869379/__some-target__/out/target-file (or whatever path Buck gives you) it out it'll say "Hello, World!" First build done. Yay!

So what do all the parts in that rule mean?

More!

Next, let's chain two rules together. Here's another rule in the same file:

genrule(
  name = "yelling-target",
  out = "target-file",
  cmd = "tr '[:lower:]' '[:upper:]' < $(location :some-target) > $OUT",
)

The new thing here is $(location ...), which interpolates the location of some the output of the named target into the command line.

Now if you build everything and go look at the output (using --show-output), you will get a new file that says "HELLO, WORLD!". If you change the original rule, the new one will get built too.

So with these two rules (plus the thing in toolchain), you can:

Try changing things around (for example by changing the message) and seeing what happens. You can also run buck clean to remove the targets to get a fresh build.

Next time, we'll talk about moving these from genrules into a library that we can import and call.

If you'd like me to email you when I have a new post, sign up below and I'll do exactly that!

If you just have questions about this, or anything I write, please feel free to email me!