So the answer IMHO to “when to use Bazel” is “never” :)
So the answer IMHO to “when to use Bazel” is “never” :)
Also, Google tooling knowledge doesn't transfer very well to outside projects. Everything is special on the inside there. They use an internal version of Bazel called Blaze that's totally integrated with everything, with entire teams dedicated to the tooling, and only a few officially supported programming languages, so of course it works smoothly.
I understood some of the design decisions and tradeoffs for why it works the way it does, but I didn't like it. I certainly wouldn't reach for it for a personal project. Possibly I still just didn't "get it". I've used dozens* of build systems at this point, but hey.
* possibly exaggerating
A good number of their open source projects fall apart in real-world use. If you visit their repositories you'll often get the sense that beyond working on interesting problems, their engineers have no desire to properly maintain these projects for the next few years. The gamble of relying on a Google product unfortunately also applies to their open source projects.
What about Golang? Angular? Dart? Even the bigger stuff like Chrome and Android while a bear to deal with are integrated with every day by a lot of companies.
What is some Google OSS that has failed in the way you mention?
Sure it wasn't great, but the few projects I did with Angular 6,7,8 was kinda nice. I still have an AngularJS project in production which is also nice :)
Of course any new JS project is now done in Svelte (nothing simpler) or as nice
PS. It's nice to be nice :D
and there still no guarantee of no such regressions one month later.
I assume it's OK if it's your only platform—though I got my programming start on Windows, with open-source languages, and distinctly recall how managing the same tools and builds got way easier and more reliable when I switched to Linux. Luckily WSL2 is getting semi-decent and can call out to Windows tools, so it's getting easier to standardize on one or another unixy scripting language for glue, even if some of your tools on Windows are native.
Part of the trouble with it, though, is that there are multiple ways to end up with some kind of linux-ish environment on it, and that all of them introduce quirks or oddities. You end up having to wrestle with stupid questions like "which copy of OpenSSH is this tool using?" It's probably less-bad if you're in a position to strictly dictate what Windows dev machines have installed on them, I suppose. Git is installed, but only with options X, Y, and Z checked, no other configurations allowed; WSL2 is installed and has packages A, B, and C installed; and so on, crucially preventing the installation of other things that might try to pile on more weirdness and unpredictability.
Those kinds of messes are possible on macOS or Linux or FreeBSD or what have you, but generally don't happen. I think it happens on Windows because every tool's trying to vendor in various Linux-compat dependencies rather than force a particular system configuration on users, or having to try to deal with whatever maybe-not-actually-compatible similar tools the user has installed. So they vendor them in to reduce friction and the rate of spurious bug reports. Basically, the authors of these tools are seeing the same problems as anyone trying to configure cross-platform development with Windows in the mix, and are throwing up their hands and vendoring in their deps, which compounds the problem for anyone trying to coordinate several such tools because there's a tendency for everything to end up with weird configurations that don't play well together.
Unpopular opinion but I think the Unix approach of lots of little tools with arcane configuration files all blaming each other sucks. I get why it exists, why it became popular, and why it remains popular in some scenarios, but I don’t feel beholden to it.
If we are talking about stuff like backend web development then I'd say no, it's actually a pain to work with - few people bother deploying to Windows these days, many libraries/frameworks treat it like a second class citizen, tooling doesn't translate well (or at all).
Even frontend webdev is very unixy due to node/npm and popularity of Macs in that space.
When you're talking about OpenCV, GPU related things, game dev then the situation is reversed.
So it highly depends on what you're developing.
Obviously this isn't a deal breaker in most situations, but it is a bit annoying. I've observed similar performance problems running Webpack on Windows in the past.
Also take a look at this talk on NTFS, file system speed, and how the presenter optimized the Rust installer: https://youtu.be/qbKGw8MQ0i8 . There is an awful lot that can be done to tools that deal with lots of files to perform well under Windows too.
No. It was the VFS design. They have lots hooks and extension points for 3rd party, there is no way to improve without breaking backward compatibility. It was the reason why many antivirus was broken in the first few releases of windows 10.
The only time I see Windows frontend devs is full-stack .NET shops or low cost outsourcing centers. If nothing else then just for practicality - you need to test on Safari and iOS so might as well get Mac devices.
OTOH, in practice, if you're using a lot of open source tools and have developers working on every single halfway-plausible OS except windows, things are probably pretty OK, but then you throw Windows in the mix and suddenly the time you spend supporting your builds & tools shoots way up. That makes it feel like it's Windows' fault.
$ file -L /usr/lib/git-core/git-rebase
/usr/lib/git-core/git-rebase: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=95d963a593ffeeb306e8525aacce02f1cbc7dabd, for GNU/Linux 3.2.0, strippedIt was a complete waste of Mercurial developer's time that would have been better spent creating a GitHub equivalent.
If it doesn't come from Microsoft, Windows developers don't care.
Learn that lesson or repeat the mistake.
In my experience, most software development tools don't work on it, at least not as well as on Unix-like systems. But I'm not a game dev.
There's a standard find_package/find_library macro and definitions for OpenCV (which is your use case here). Then use either Microsoft's C++ package manger or Conan to actually install the libraries.
IMHO, Bazel is a classic example of Conway's law[0], and it falls squarely in the "big corp" class of software. You have to be running into issues like 6+ digit CI compute costs or latency SLOs in hundreds-of-teams monorepos before Bazel really starts to make sense as a potential technical solution.
But where it does work well, is when you have a large complex codebase in a monorepo, and you need reliable caching to keep build times down.
> I just `find . -name "*.h"`
That sounds like it would cause problems with not triggering a build if a .h file is deleted. And would trigger unnecessary builds if any .h file is modified. But if your builds are that fast, maybe that isn't a problem.
ccache is going to be as fast as any checksum dependency tracker --- otherwise you're relying on a timestamp, which isn't any better than "bare" Make. We use `*.d` rules from the `-MD` flag to prevent the "deleted header" case.
Considering the brevity of the Makefile (it looks like a "basic" build), performance, and the practical robustness, it's in a pretty great trade-off space.
2. Make lets you define inputs and outputs, but doesn't enforce them. Bazel sandboxes build actions; if you try to import a dependency that you haven't listed as a direct or transitive dependency, the build will fail. This is leads to users never (or at least very rarely) having to run `bazel clean`.
To take it a step further. I never left the "comfort" of bash-build and bash-deploy scripts.
In most of my projects (pro and personal) there is a deploy-aws-prod.sh and deploy-aws-dev.sh (or some variation)
None is longer than a 10-20 bash commands.
These "projects" are webservice, ml-models, batch-processing(think distributed clusters)
It's ugly and perfect-enough at the same time.
YMMV
This is becoming more and more of a pet peeve of mine, about to become an outright annoyance; the adding or changing of tools without things actually improving, or the purported improvement not actually being relevant or even close to the most important thing that time should be spent on.
https://mcfunley.com/choose-boring-technology is a good starting point for moving away from this mindset.
I had a Go project up until earlier this year, I could set it up myself. I picked makefiles to build it (not bazel, that would be overkill; not mage, that would mean more coding), and it worked just fine. I never had a compelling reason to move away from it.
Actually it was more than fine, it was a relief; my previous experience with tools like that had been Maven (where everything is XML and you need a plugin to do basic things like move or remove a file) and the Javascript ecosystem, from before everything was merged into package.json / nodejs-style. Dependency management too.
Boring technologies are easier for people better and making due with what they have and accepting sometimes very large limitations.
ADHD makes boring tasks harder for instance, and boring technologies give you no escape from the tedium.
With a little fancier technology though, you at least have hope ;)
I will never use bazel again. Not worth the effort required, and doesn’t work out of the box as advertised.
Get back to me when you work for a company with a monorepo that has to build and test everything in CI for every change (taking something like 200 CPU hours) because they didn't have the foresight to use Bazel.
In practical terms, the makefile or whatever is usually good enough.
Bazel isn't designed to make things easy. It isn't even designed to make things fast (though it is easy to add that on due to repeatable builds). Bazel is designed to prevent you from shooting yourself in the foot; providing strong controls on project dependencies, both dependencies of your project as well as other projects' dependence on your project.
That means in 99% of companies the answer is no. You're better off with CMake or something thing like that.
That's a very rare occurrence in software. Honestly it's probably about as common as in housing. You can rebuild parts of a piece of software but the build system is generally really foundational and almost never changes in my experience. Especially if the software isn't a library so nobody except the main developers has to interact with the build system.
What's often impossible to replace without a full rewrite is a backend's DBMS, and people tend to underestimate how tight of a coupling that is. Only gets worse with abstraction.
That smells like covering up an architecture problem (tight coupling) with a build tool. Not a recipe for success.
CI tooling is orthogonal; your CI tooling can invoke Bazel or Makefile+custom caching, it wouldn't really matter. But the problem in CI is that you lack state; whereas a developer's machine might e.g., have a bunch of .o files from a previous build, CI will be starting from a clean slate¹. So builds take longer. My understanding of Bazel is that it has decent support for caching and can thus makes those rebuilds a lot faster, which it has b/c it understands exactly the inputs to the steps at hand. (Which, if you write your own caching layer, you'd have to figure out.)
… but … I've also seen the same thing the top commenter has, with Bazel: endless suggestions to use Bazel … but migrating a large existing codebase is pain, and if you're not willing to put your work where your mouth is … then the status quo prevails.
¹While here CI lacking state is a sort of negative b/c of the time we need to rebuild it, normally, I think this is a good thing: it means you're constantly verifying you can build from scratch. Or, at least, something close to scratch, modulo things like vendoring. (I.e., if you do an "apt-get" from Ubuntu's servers in your CI pipeline … well … your build obviously isn't quite from scratch.)
It makes more sense when you realize it was really built to deal with statically linked C++ - there's no guarantee of ABI, so you really need to ensure that all your dependencies are built the same way as your project to ensure compatibility (and the dependency graphs in monorepos get DEEP).
For any language with a stable ABI that utilizes dynamic linking, the complexity is far more then the benefit. The whole monorepo concept and all the tooling that goes with it really makes more sense when you think of it in that context of statically linked code that can't easily be packaged into something as portable as a JAR, so it's critical to build it all the same way.
That's a perfectly fine choice if you have bodies to throw at the problem and can deal with the consequences of that choice, but most people can't. Google can and so it does. If it wasn't as successful as it is, it probably would have collapsed under the strain of the people and systems required to manage that code.
Other tooling decisions place a burden on every SWE. Their config language is a weird trash that everyone has to sorta learn. Their deployment and integration testing tooling have similar qualities, and it's not cause of the monorepo. One consequence is that many teams cannot feasibly deploy microservices, even though it'd often make sense to, which is even worse if they're using C++.
I’m really glade that Meson and Ninja exist however. I hate GNU Make like few things in my toolbox. M4 really is an awful language.
Specifically, Bazel is really at home with Java/C++ and Linux. Sure, it kinda works elsewhere, but you should be considering other options.