5 ms·
> It's unfortunate that CMake is the least bad build system we have. With caveats--I've switched to Bazel. Bazel does solve the very real, very hairy problems
by klodolph 6y ago
> It's unfortunate that CMake is the least bad build system we have.
With caveats--I've switched to Bazel. Bazel does solve the very real, very hairy problems of compiling C++ programs for different platforms, on different platforms. It is a damn beautiful thing. There are a few places where Bazel really shines. For example, generated sources, multi-language projects, and building third-party dependencies from source (without monorepos or Git submodules--you can get your third-party sources from HTTP, Git, etc).
If my project does any of these things (third-party dependencies, uses multiple languages, or generated sources), I reach for Bazel immediately.
That said--it is also impossible to give an unqualified recommendation for Bazel. The documentation and community is catching up, and a few simple things (like using pkg-config) are a bit more difficult to get working than they should.
- mehrdadn 6y agoBazel is the least bad build system I've used too. Just wanted to note, though, it is not damn beautiful. Maybe its internal (idealistic) model is beautiful, but the outer parts are something else. It does have awesome features, but it has lots of bugs, rough edges, and weird behavior too. Try specifying your own compilers, or adding your own steps to the build process, getting things working on Windows, etc. and if you don't already know how to do it, you will probably hate your life trying to figure it out. And forget about putting your workspace into a path with spaces, even if your repo path lacks spaces inside it and you use relative paths everywhere -- it simply can't do that (while even Make can). There are lots of random issues with undeclared headers and ungenerated files that come up from time to time that make absolutely no sense and are likely bugs that are incredibly hard to track down. (Of course some of these errors are legitimate too, just painful to track down. I'm saying not all of them are. Some are even nondeterministic.) And good luck if your user name (and hence home directory) has a space in it, which it very well might if you're on Windows. All in all, it might be better than anything else I've used, but not in every case, and that's not an unconditional endorsement.
- klodolph 6y agoWhile Make can deal with spaces, you have to pass them through multiple layers of splitting. I've done it before, but I've given up on anything besides escaping every single space and pasting it into the Makefile (with a script), and not using any of Make's variable expansion functionality. Spaces are how Make separates items in arrays, after all. For example, take this contrived example: foo.c\ bar.c echo $(patsubst %.c,%.h,$@) If Make had some concept of arrays, it would echo "foo.c bar.h", but it does not. While this example is super contrived, it should illustrate the general problem.
- mehrdadn 6y agoNote I was explicitly talking about spaces in the current directory (which is only dependent on where the user clones the repo), not spaces in the workspace (which depends on what's in the repo). Your examples are about the latter. The latter isn't as big of a deal because the repo owner at least has control over the contents and can avoid putting spaces in file names (and use relative paths everywhere). But they can't control where the user clones their repo.
- klodolph 6y agoAh, that makes sense. Maybe I've just suffered abuse from projects that can't be built anywhere for so long that it seems normal--I remember a particular team I worked on where the project needed to be spread across the X:, Y:, and Z: drives with bind mounts.
- xfer 6y agoI was compiling emacs with mingw and its Makefiles broke with spaces in the path. So while Make can, it seems that few people can get it right.
- mehrdadn 6y agoYeah, I don't have a lot of faith in UNIX-oriented tools in getting it right, because they just don't care. But at least it's possible to get it right if you care to; you just use relative paths instead of absolute paths, and avoid spaces in your relative paths (which you can control). With Bazel, it's literally impossible to do that.
- efreak 6y ago> And good luck if your user name (and hence home directory) has a space in it, which it very well might if you're on Windows. I went to great lengths on my recent Windows install to ensure my user profile, which has my real name in it, uses `efreak` as the name for my home folder specifically to deal with software that hates having spaces in filenames. There might well be a way to specify this in Windows, but I'm not aware of it. Instead, I had to recreate my user profile 3 times due to Microsoft syncing; first it wanted 'first last', then it wanted my Microsoft account name. I don't recall how I got it working finally; I may have renamed the account before signing into sync (it keeps my desktop environments together across several computers). Using 8.3 filenames can help too, but that requires remembering what they are. If you've only got a single folder in the path that has a space in it, then I've had success using symlinks (or junction points on windows, since explorer recognizes those and doesn't recognize symlinks as such). Just create a folder c:\mounts or ~/symlinks to work with. And god forbid you ever have to work with the qt build environment in Windows, extracting and deleting the source each take like 10 minutes on my ssd... I really wish it was distributed as a vhd file, or that I could convert it to one easily.
- steeve 6y ago+1 for Bazel. It is most importantly a language independent package overlay. To put it simply, it pretty solves the package/module issues for C++, as well as cross compilation etc... It's beautiful.
- cycloptic 6y ago>generated sources, multi-language projects, and building third-party dependencies from source What is special about how Bazel does these? I have never had a problem doing any of this in CMake, or Meson. In my experience the only reason to pick any over the other is because they tend to vary wildly in supporting certain compiler toolchains for non C/C++ projects.
- gravypod 6y agoBazel generates reproducible builds by default and is very cache friendly. It forces hermetic build and test environments; each build/test gets it's own sandbox that only contains and preserves deps and outputs. It's not magically different than CMake and Meson, it just works in a way that I never every think "maybe make clean will fix this". I can trust it to work regardless of the changes. You can also, out of the box, use remote build/test execution & remote caching shared between Devs and CI. It's also VCS aware and uses that to help prune down change sets to make builds faster.
- jcelerier 6y ago> It forces hermetic build and test environments; how would that ever work if you want to build software to be packaged in a linux distro where your software has to comply with $VERSION of every library provided by the distro ?
- steeve 6y agoIt is focused on producing static (or mostly static) binaries. Obviously not everything can be in the sandbox, but in the Bazel world, it takes over the build of all your dependencies (as it is also a package overlay).
- gravypod 6y agoBazel isn't really designed for dynamic linking applications. You can include system libraries if you need: https://groups.google.com/g/bazel-discuss/c/Ndd820uaq2U https://groups.google.com/g/bazel-discuss/c/Ndd820uaq2U You'd also need to make sure everything is marked as `linkstatic=false`, but I'm not sure if that would work correctly. But, in the end of the day, you're going against the grain of bazel here. Bazel expects to statically link everything to make distribution to heterogeneous environments simpler.
- uep 6y ago> you can get your third-party sources from HTTP, Git Can you elaborate? I assume those projects have to be brought into the Bazel configuration format, or does it have some support for foreign build systems?
- cpgxiii 6y agoIt doesn't, at least not in any form you'd want to rely on. Bazel makes it easier than CMake to pull in externals in source form, but you'll still want to write Bazel build rules for them in most cases. In practice for C/C++ externals being built in a Bazel project, almost all of the build can be captured by a couple cc_library(...) and cc_binary(...) rules.
- uep 6y agoI've had kind of a crazy idea of building an entire Linux-based embedded system using Bazel. Based on your previous comment, I briefly thought they might have had some detection of foreign build systems now. Some part of me still finds the idea kind of interesting. The idea of doing a Linux-from-scratch, but porting each project to Bazel in the process. It's kind of silly and would be a lot of work, but I think about being able to modify a header of any library in the system, and have that change quickly percolate up to every dependent application automatically. The way to do it now is through bitbake, but it (rightly) is just wrappers around every other build system. The goals are a bit different than Bazel's, but it's quite slow.
- steeve 6y agoIt does, via https://github.com/bazelbuild/rules_foreign_cc https://github.com/bazelbuild/rules_foreign_cc, but it's not always the best idea.
- gravypod 6y agoCame here to say just this. It's a marvel of engineering and the slack for the community is really helpful. I hope more people join in the future.
- cpgxiii 6y agoIn my experience with several Bazel projects, when everything works, it's great. But, the case where it doesn't work are way more painful than anything I've encountered from CMake + (make, ninja). Bazel is basically pathologically bad about resource use - if you run out of anything (CPU, memory, disk, inodes) you're totally hosed and probably have to reset the machine. Bazel caching is great, but boy do you pay for it in disk space - the bazel cache on my machine, for a reasonable (but by no means huge) monorepo is probably more than 100GB, and because it absolutely loves creating symlinks to everything it's very easy to run out of inodes on smaller disks even when there's plenty of space otherwise available. Bazel basically feels like the "GC language" of build systems - it behaves like there's nearly infinite resources available and so long as that illusion can be maintained, all is well. For reference, the machines I'm using are plenty beefy (several AMD 16C/32T + 128GB ram + 1TB nvme, and several Intel 28C/56T) - it's really inexcusable that a build system makes the machine hang.
- 0xFFC 6y agoJust curious, what specific project do you compile so that you ran out of resources in that machine?
- cpgxiii 6y agoThe project is our internal monorepo, with probably order ~1000 targets, mostly C++, with reasonably heavy use of templates. GCC needs somewhere on the order of 2-4GB to compile each C++ target.
- efreak 6y ago> inodes Can't you deal with this by using a mounted filesystem?
- cpgxiii 6y agoOh sure, it's fixable and something you can work around, but having your build system responsible for "machine is unresponsive and acts like it's out of disk but you've got >100GB space remaining" is a real pain in the ass. Running out of inodes (and specifically, that you can run out of them well before running out of disk space otherwise) is also really not an obvious failure mode to most people.