Buck – A build system developed and used by Facebook
buckbuild.com
buckbuild.com
For example, my use-case is similar to what Mike Bostock described in "Why Use Make" [0] when explaining how he uses Make to build out his data tranformation process. Most of my work is data transformation/small-scale ETL, but I just haven't been able to get into Make beyond trivial work, and I often end up writing things in Rake (Ruby).
So I was wondering if other devs had tried using Buck/Bazel for everyday hobbies and projects, and whether you stuck with the new tool or went back to Make? The portability of Makefiles isn't a high priority for me, and I like experimenting with different systems for my own projects.
Edit to add: here's a specific complaint. To run arbitrary commands and shell scripts, you use genrule(), but in Buck a genrule can only have a single output. I used Buck to preprocess and organize the assets for a game, and that restriction made it very awkward.
It's been a while since I used Buck, and it looks like this has improved a bit -- you can now output a folder of files: https://buckbuild.com/rule/genrule.html
Each subdirectory below the root also has its own BUILD file, where you can see the individual packages being compiled.
When make fails me for personal stuff, I switch to ninja [1]. The Chromium people use it in their Bazel-like build system. A hidden gem I recently discovered is doit [2]. I found this one incredibly helpful when I had a build with tons of 1:N, N:1, N:M dependencies.
[1] https://github.com/ninja-build/ninja [2] http://pydoit.org/
Edit: FWIW, I posted doit to r/python and someone suggestion Snakemake, which also looks excellent and well-maintained: http://snakemake.readthedocs.io/en/stable/
> [2] http://pydoit.org/
Thanks for this! I need a build tool for a Python based data analysis project ("micro ETL"?). Doit looks like it will work nicely, with the bonus of keeping everything in Python.
Anyways, one thing that has always bothered me about make is that it so much depends on file modification dates. Imagine if it would instead use a very optimised hashing algorithm over the input content. Content can be a file or any URI, so it uses wget/curl and ssh as a dependency. Hashing is optimized such that it fails early - e.g. hash in n kB increments, mark as new and return if changed.
Imagine how well this would now suddenly integrate into our modern web service based landscape. You could hook together services quite easily:
all: report.csv
report.csv: ${customers_json_uri} ${earnings_json_uri}
${report_executable} $^ > $@
Has anyone built something like this already?- Don't use modification times and instead do intelligent hashing (see https://buckbuild.com/concept/rule_keys.html)
- Include the compiler and a bunch of other stuff in the hash. This means you can share cached artifacts safely via a http cache (https://buckbuild.com/concept/http_cache_api.html)
- Can refer to remote files (see https://buckbuild.com/rule/remote_file.html)
- Can use any script to do anything as long as it has a single consistent output (see https://buckbuild.com/rule/genrule.html)
Because their model is so much better, you get crazy fast local caching and remote shared caching of artifacts.
Please don't use make, the newer build tools are better in virtually every way.
(disclosure: my team created Buck when I was at FB)
It is a bit unpolished and still a work in progress, but has some features that are useful for data science workflows that most software build tools do not cover:
* Steps can produce multiple named outputs (for example full.csv and summary.csv), dependency graph can branch in both ways,
* Outputs that are directories with many files,
* Built-in input/output file sharding (for example by date or month) and HDFS support,
* Lots of control over which steps to execute: not just "rebuild target X and any required upstream dependencies". Can select a target and all that depend on it downstream (if you know that a remote file changed), skip rebuilding some steps, etc,
* Can put very short (text processing) scripts directly in the Drakefile in Python, Ruby.
* you can specify several inputs & outputs per rule
* you can specify which script interpreter is used ($SHELL), and python can be it. See https://www.gnu.org/software/make/manual/html_node/One-Shell...
* downstream make can indeed be interesting. however you can try to build all ultimate targets ans let make sort out which ones can be avoided
* fs support is best done at the os level (https://wiki.apache.org/hadoop/MountableHDFS, not sure about timestamps)
and
* "everyone" "hates" gnu make, which means everyone knows it.
(edit :format)
On. Every. Single. Run.
Yup.
Often, I write a little test program in C or C++. I name the file "foo.c". Then, to build it I simply type `make foo`.
Sure the rules may be a bit stale, but there isn't much software i use today that I could use in a near identical manner 40 years ago. Make has truly stood the test of time.
The two weak points are: (1) multiple outputs from a compilation step (yytab.c yytab.h from yacc) is not properly supported, and (2) no windows support. Other than that it's the perfect minimalistic make replacement -- what make should have been.
Additionally, there tup[1]. With some assumptions about the build process that usually hold in non-distributed builds, it is the fastest, simplest make replacement; You just write a list of commands that builds your final outputs, and by tracing the processes it figures out exactly what needs to be done next time -- nothing more, and nothing less.
[0] https://github.com/apenwarr/redo [1] http://gittup.org/tup/
https://buckbuild.com/rule/genrule.html
Some other benefits that may or may not be important:
- Use the same build system for iOS/Android/Cxx/Python/D, etc.
- Integrates with editing in IDEs.
- Encourages modularization...more modules = more cache hits = faster builds
https://hackernoon.com/introducing-the-taskfile-5ddfe7ed83bd
https://github.com/topojson/us-atlas/commit/a2a9d4279a125212...
There's also Please, which we wrote as a Buck replacement before Bazel was open sourced: https://github.com/thought-machine/please
(disclaimer: I wrote most of it...)
I have really, really grown to resent this culture of proud and unabashed cargo-culting that we've arrived at in the open source world. Why is this the first sentence describing a new project? Why do we need a Facebook™-approved build system? Does that somehow make it better than the others? And why does Facebook need their own build system? Was the existing ecosystem technically insufficient for them, or was the issue a legal one?
Whenever I make this point in dev circles, someone will reply, "They serve X amount of visitors a day, so they must know something!" Well, they also have a firehose of ad money pointed at them 24/7.
> "x is a build system developed by me as a side-project that I might drop at any time, and its only production use is to compile itself and a hello world app"
Not to say people's side projects aren't useful, but there's only so many hours in a day, and there are thousands and thousands of open source projects, so you need some way to evaluate what's worth looking at. Knowing it has more than one person behind it, some time in field (so it's not 0.0.1 alpha), and is actively being used (you're not writing the first production code using it) goes a long way to separating it from the pack.
I understand the human need to optimize attention, use basal heuristics to weed out unattractive options, and nurture a need to belong, but this is not logic. It's a rationalization.
It's also why this works, and why facebook (and every other major tech player) does it. It's a brilliant marketing and recruiting tool and a way to insert influence under the guise of open benevolence.
Hidden out there is probably a better tool for your needs. But now you'll never find it.
There is an underlying logic though when you frame it in as a time vs reward problem. I could spend a few months evaluating all of the various build tools out there and find the perfect fit for my team. Or I could spend a few days evaluating the projects with the most support (be that large companies, large communities, whatever). I'll concede that I can't guarantee it's the _perfect_ fit, but it's likely good enough when you compare the opportunity costs.
well, by definition your needs are yours, and only you know them, right? perhaps that is your point... but then this question would seem to be malformed, or perhaps disingenuous. why does facebook need to know "your needs" to develop a good build system? maven developers don't know "your needs" anymore than make, cargo and all the rest.
> I'm probably nothing like facebook?
it's not clear what it exactly means to be "like" or "nothing like" facebook, without further context. differences with your understanding of facebook's operational requirements do not necessarily translate to same or similar differences with their software development and build needs and practices.
> Why does George Foreman know how I want my grill?
similarly, the structuring of "my grill" bit seems problematic. also, this seems outright unrelated, unless foreman is in fact a very intensive user of grills and has optimized the grill design over time based on his experiences... and you are also, in some capacity, a professional user of grills.
> It's a brilliant marketing and recruiting tool and a way to insert influence under the guise of open benevolence.
even if we accept the premise of it as a "marketing tool", this doesn't imply that it's not a solid tool proven in real world projects. no obvious mutual exclusivity here. it also doesn't mean it's not-benevolent.
it would seem impossible for any company to avoid this pointed finger of yours if they release an project, because any engineer is going to ask "where did this come from" at one point or another. then, presumably, they will have been victims of villainous marketing.
> Hidden out there is probably a better tool for your needs. But now you'll never find it.
maybe, maybe not. how much better? at best, unknown or unresearched tools would seem to have indeterminate benefit (or lack thereof) relative to what is known and researched.
When you realize that none of these frameworks are even an improvement over jQuery, it becomes clear what the true motivation is.
For example, here is a SQLite playground that I built with a friend https://sql.glitch.me/. The entire frontend is only 100 lines of Javascript thanks to jQuery. I'd love to see what the React implementation looks like.
If you tinker hard enough, you can achieve those with jQuery, but it'll never be as easy as React.
Also, your site doesn't load (project not found)
JavaScript Fatigue inducing media tries to taint jQuery calling it all sorts of things but that hasn't stopped me. Sure you need to learn and use a handful of useful patterns to build with it, but it's the same situation if you want to make proper use of any framework.
And I updated the url for my demo :)
1) This is probably a project I want to check out, if it pertains to my stack, and
2) This is probably going to stick around and not be unsupported very soon.
I would be just as happy if FB hadn't developed it, and instead it was just used by them. (Or any other of maybe a dozen big camps) Or if it was just used by a whole lot of people.
Widespread use is a pretty good metric for what library to choose, when you aren't familiar with the landscape.
On the other hand. I do think you are right. React suffers from this a lot. React is good. It has a lot of strong competition from smaller groups. But, the attitude seems to be "FB will rub so much money against React! That much money and fame will polish anything. Soon it'll be popular because it's popular. Don't fight it."
We've got a couple of Facebook fans at work, which has left us with a number of our systems using different tools to accomplish essentially the same tasks, and no strong case on either side for us to standardise on one of them.
Maybe I'm just being bitter because I've had a bad experience, but it's been a maintenance nightmare for us in the office.
I would argue Buck actually helps to solve what you are concerned about. At Facebook, everything builds with Buck (and Google with Bazel I hear)...which means you learn it once and you know it for your Objective-C library, your Android app, your Cxx service, your python scripts, etc. It really helps to standardize on a build system, and at many companies you can only do that if it supports windows/mac/linux, it supports many languages and platforms, is fast, and is easy to pick up. Buck is all of those things.
Looking at https://github.com/facebook you seem to be using all sorts of build tools...
Facebook uses fbshipit (https://github.com/facebook/fbshipit/) to take slices of their monorepo and publish them to GitHub.
Surely not on Android or Skia teams, unless they internally use something other than what AOSP and Skia use.
I fail to see how the world gets worse from large companies releasing internal tools as open source.
From my years and years at large companies, these things start because they don't want to share anything in the first place, and then it's just pricey to maintain.
Sure when they open source them it further fragments the market and you always get the rush of "Facebook has almost 2 billion users therefore their tools must be the best!" which further exacerbates the issue but I don't blame Facebook for these issues.
It sounds like, in your situation, perhaps there are too many tools being introduced into your projects. Too often I see developers abuse the hell out of npm and the like to just include whatever they need with zero regard for the newly introduced dependency tree and the new tooling that needs to now be maintained.
Too many engineers syndrome comes to mind too.
Saying that Facebook should have improved Make or Maven is like saying Linus should have improved CVS or SVN instead of competing with Git. They're in the same space, but they differ at a very fundamental level.
This doesn't mean that we should disencourage creating new tools fundamentally changing the ways we work with them. You mention Git and I see it as on great such example, I remember with anguish some of the SVN trunks, working with their pseudo tags and the mess which you'd often be introduced to.
What about Waf though?
Buck, Waf, Meson, Bazel....apparently Python is the language for next-gen hash-based build tools :)
Just like Make is in C and the build files are in Make.
Typically they face a problem that few people have ever faced. There may be an existing solution, but not in the open. So they have to roll their own.
Others in this thread say Buck was inspired by Blaze. That seems reasonable and I hardly think Facebook can be blamed for rolling their own when that was the only available option.
You might as well blame Google for fragmenting the Hadoop ecosystem by creating their MapReduce framework.
The funny thing, though, is that keeping up with other web tech, you always have to deal with facebooks API's and sharing and whatnot, and its also, usually a huge pain in the ass.
So, like, what's the benefit of this, switching build systems, other than a tick on the resume for someone who wants to get a job at facebook?
If this did not work in your office, this is most likely a problem of people in your office not communication properly about their choice of tools. Did you have people make a short presentation when they introduced a new tool? Did nobody ever point out that you already have various tools that can (easily/elegantly) accomplish what the next new thing(tm) is introduced for?
> Buck is designed for building multiple deliverables from a single repository (a monorepo) rather than across multiple repositories. It has been Facebook's experience that maintaining dependencies in the same repository makes it easier to ensure that all developers have the correct version of all of the code, and simplifies the process of making atomic commits.
Having been on the "other side" of the monorepo argument where we tried to make do with improving/extending existing build tools etc. in a rapidly growing engineering org, let me say that Facebook (with Buck), Twitter (Pants? I think?) and Google (with Bazel/Blaze) almost certainly built these to deal with the problem of scaling build management with an ever-growing organization.
The popular model of a dozen or so small repositories in GitHub + Jenkins with Maven/NPM/Rake+Bundler/whatever works fine for maybe a few dozen engineers or more, but one day you wake up and realize there hundreds of repositories spread across dozens of _teams_ and hundreds of developers. Obviously you've then got a big ol' dependency graph between repos to deal with, so if you need to fix something near the root suddenly you need to run off bumping version numbers and/or fixing intermediate libraries all the way down the graph. Plus version incompatibilities between the dependencies of different libraries ... it's a total mess, and it doesn't make for an org that can easily "move fast and break things", so to speak.
So then to avoid paralysis your options are basically either to silo up (this team owns their stuff, that team owns their stuff, don't bother with shared dependencies) or you go the monorepo route. If you do, then maybe you go and pull all your hundreds of smaller repos into a monorepo. Having everything in one place makes it easier to police the dependency issues within the org & makes it easier for a single engineer to deal with those sort of "cascading changes" instead of shunting that problem onto the entire organization. But in exchange for this "agility" you've then got the problem that builds take multiple hours & the associated tools are often highly language-centric (Maven+Java, NPM+Node, Ruby+Rake, etc.). They don't typically make any reproducibility guarantees either.
Anyway, to make a short story really long: at the time FB, Google and Twitter were hitting these organizational scaling walls, making these decisions and building these tools internally, there really weren't any great tools out there for the monorepo use case. I think that's why all these tools have appeared as side-by-side alternatives rather than improvements on one another or to tools like Maven et al.
Whether or not consolidation is warranted, for the folks who have the problems that Buck/Bazel/Pants solve, it's likely to save 'em a hell of a lot of time, effort and money IMO. It's a good thing that they have been published, even if the value's maybe not immediately obvious.
When I started the project, Buck had one specific goal: to make Android builds faster (https://youtu.be/CdNw6mRpsDI). At the time, the recommended way of building Android (from Google) was to use Ant. So when someone points to Buck as an example of "creating competing tools more often than persisting with and improving existing ones," I'd like to point out that you can't fix Ant if these are your issues with Ant:
* It is unsound. * Because it is unsound, it is irreparably slow. * It uses XML as a build language.
Yes, in July 2012, there were a number build systems on the market (though Bazel was not one of them, but Pants was), and none of them focused on building Android. And even if they did, few (if any) software companies were building an Android app as large as Facebook, so it was unlikely that anyone else was going to design for our scale.
It also wasn't just about build times, but about how I wanted to see us organize code in our repository. At the time, there was a flat list of folders in the Android repo, each called lib-something. This drives me insane because you inevitably end up with two (or more!) people creating com.facebook.common.StringUtils, each in their own lib-something. (It's also annoying to `ls` this "lib-" directory over time.)
In contrast, Buck/Bazel encourage the use of a unified tree, but still encourage fine-grained modularization (which is key as your build graph gets very large). This has been shown to scale to extremely large monorepos at both Facebook and Google.
Finally, by having total control of the build system, we were able to build in all sorts of cool tricks to build Android very fast, both in the large and in the small: https://youtu.be/Y9MfGS3qfoM. I don't think there is any other build system we could have decided to work with at the time to achieve these gains.
Buck has since evolved to build everything else at Facebook. This is not because the Buck team set out to conquer the world, but because people internally wanted the benefits of Buck for their builds. Building an alternative toolchain to xcodebuild was a mammoth effort (and one for which I take no credit). Having one build language for a heterogeneous collection of programming languages in a monorepo is no small feat.
Finally, to the people who believe "The big guys want developers locked into their ecosystems," I have news for you: the Buck team is not offended if you use Bazel, Gradle, Make, or anything else. Buck is open source because we wanted to share it with the community, not dominate it. Like many of you, people are excited to show their work and learn from others.
Are you a member of the buck team? Your new account only has activity on this submission.
I mean somebody who has actually used both of them (and not read some versus blog posts).
https://buckbuild.com/command/buckd.html
Note the daemon is automatically started when you `buck build`.
(disclosure: my team created Buck when I was at FB)
* It also writes build output to an output directory
* It detects a tty and does the right thing, so on CI you get a linear log
* In the output directory it also includes timeline graphs that can be loaded in Chrome's devtools traceview (https://github.com/catapult-project/catapult/blob/master/tra... and in Chrome proper).
* The tracing can be viewed live https://buckbuild.com/command/server.html
(disclosure: my team created Buck when I was at FB)
Or perhaps write out your individual experiences mentioning:
1) Team size
2) Repo size
3) Repo programming language distribution.
4) development/Testing/build/publishing strategy
5) Of course, the actual experience
It's dizzying.
I wonder if build-system complexity is an artifact of reducible complexity in other areas.
Perhaps the next time we develop a language, it should comprise of it's own build system that doesn't require any configuration, or rather minimal. To the point wherein we didn't need to think that much beyond the obvious.
If you can get by using only go for everything, you'll have a great time. But complexity starts to become unavoidable when requirements move beyond single-language ecosystems. At some point simplicity can end up costing more.
> Buck: A high-performance build tool
And in the title you read "a fast build tool", like yarn, as soon as it was released it was the faster one.
F: let's use yarn/buck G: why? F: cause it is faster G: Did you already tryed it? Did you measured or benchmarked it? F: No, but Facebook claims it is fast, come on!
By the way, sometimes yarn does not work and you need to add a file to manage it. Furthermore facebook is using the npm registry, do they pay for it or support it?
Other than that, thanks to Facebook to bring awesome tools to the public, like React.
As for using the npm registry (by default) so what? Why would the npm folks care, MS uses it as well with vscode ans its automatic resolution.