If you want to upgrade your Bazel dependencies using pinned semver constraints and a lockfile I've made this  for you.
It superseeds http_archive and falls back to git_repository if needed. Just run `bazel sync`. See it working at .
Note: there's an open (and somewhat long standing) issue WRT Bazel fetching from gitlab.
I did my fair share of setting up C and C++ builds in the past and I can tell you: The difference between CMake and Autoconf is marginal, while CMake is of course a bit more versatile in terms of target build-systems, and of course its DSL is not as obscure as autotools toolchain, its no meaningful difference.
What Bazel (or Buck) bring to the table is slightly different, its better control of inter-module dependencies and external dependencies. In a way they are not only build tools but opinionated and effective 'linkers', bundling together your applications and libraries in a way that it is hard to mess up and very reproducible.
The other option would be the nix/guix route, which I think might be better-suited for the open-source model but require you to adapt at least the package managers.
The meaningful difference for me is that I work in a place where most of the developers love their IDEs. CMake is literally the only cross platform build system with first class IDE support on both Windows and Linux. If you use VS Code on macOS, you get it there as well.
After digging into Bazel a bit recently, I really hope they invest significant energy into the IDE story next. That is a huge, gaping hole that is being not-really solved in all the language/IDE ecosystems and is a _massive_ roadblock to adoption.
IDE integration would remove 90% of my hesitation to push it at my company.
I really like Bazel as well. As you said, cross language dependency management in CMake is hilariously annoying. However, I'm at practically a C++ only shop so it rarely comes up.
Where I am we were using CMake 2 for our build system for a long time and it got into bad shape. When we made the decision to rewrite the build system (across a few dozen subprojects), we looked at a few - Meson, Bazel, CMake, etc. CMake was hard to argue against because of the recent work (last few years) by Microsoft to support CMake projects directly (File -> Open Folder). We wanted to try to get away from maintaining separate IDE projects for every platform for every project.
"not much work" is absolutely not the feeling I have about it based on some conference talks about the topic (e.g. the various xcode talks, or the Wix talks on intelliJ), and my own thought experiments on getting it tied into Visual Studio / Visual Studio for Mac.
I think the Bazel team introduced Aspects and punted the rest for a later date. Now they hope each language/IDE community will take that infrastructure and build out the rest of the ecosystem. I think its too important of a piece of the puzzle to leave to the community.
Right, what I meant by developers who love their IDEs is that they complain if they see a console. They just want to open an IDE and click "open folder" or "open project", so not having to use an intermediate IDE project generator is a massive boon.
The meaningful difference for me is I cross compile everything.
Every cmake project I've worked with just works. As in it only takes a couple hours to get it packaged for my custom (stupid...) package system I have to use, almost all of that boilerplate work.
Only 1 in 50 autoconf project I've worked with actually works - in theory autoconf supports this case well, but in practice there is always something broken and so I know I'll spend a couple weeks (full time) getting it packaged.
Autoconf solves the problem of easily porting software to different systems because autodiscovery is its default modus operandi.
Now that we live in a post-innovation world, there is no need to port software: it's either Linux, Mac OS, or Windows.
Except, of course, there is still a lot of innovation going on, and there's a lot of porting and cross-building that happens outside the the web domain, and a heck of a lot of things that are none of the big three development hosts.
CMake is starting to converge towards what the autotools have provided for some decades now, but it's not there yet. When it comes down to it, the only real difference is different domain-specific languages and that just results in tribalism.
Hard dependencies on what? The new BSP release for the next-gen silicon on a new operating system?
Trust me, I was there in the nineties when hard dependencies proved unscalable. The only thing that has really changed since then is the scale (it's gone up orders of magnitude) and the flood of people who have no idea what goes on under the hood.
The problem is autoconf because the problems that autoconf was designed to solve are not the problems we want to solve today. Autoconf does an excellent job of solving the problems that it was designed to solve--configuring a build system on different POSIX-like systems--but times have changed.
My experience using CMake and Autotools and migrating between the two is... the only appreciable benefit to CMake is that it works well enough on Windows, and Autotools sucks on Windows. Whereas Bazel is in a different league, IMO. For people on Windows, the fact that CMake works well on Windows is enough to sing its praises, but I think Bazel will be eating the C and C++ world over the next five years.
In defense of Autotools, it's designed to work on systems which don't have Autotools installed, back in an era where you might download Apache and compile it from source to get a web server running on your system. It will work on a stock install of Linux, Solaris, AIX, or macOS. Almost nobody cares about this use case any more.
One thing however that the autotools do and i do not see any of the other supposedly replacements do is that from the users (be it an application user who wants to compile the code or a developer who wants to compile a library but does not have plans to develop it, so for all intents and purposes the are just a "user" of that library) is that it does not require autotools to be installed unless you want to modify the project structure itself (even simple code changes are most of the time fine without having autotools). It only requires a Make but that is basically a standard and available anywhere, unlike the other systems that they target (and cmake, etc, also need Make anyway).
I always found that annoying because if i just want to compile something (be it a program or a library) from source, i also need to install a bunch of build systems i'm not going to ever use myself. That is just pure and unnecessary bloat for me.
The flip side of this is that it means most projects come with an old version of autotools--and if you need to do something where "old" is equivalent to "broken", it becomes a wonderful world of pain.
A specific example I ran into was compiling random projects with -flto. libtool, in its infinite wisdom, decided long ago that it was a bad idea to pass any -f flags to the linker invocation and so stripped them out, even if you the user manually told it to via LDFLAGS. This of course breaks -flto--so newer versions of libtool got the picture and whitelisted that flag. Except projects haven't updated libtool for a while, so you have to patch their source to get it to work.
AFAICT if you need to modify the build configuration -changing optimization levels is one such things since optimizations can potentially break applications- you are expected to install (and hence, update) autotools as if you were a developer of the program/library.
But TBH my comment was more about the other build tools than autotools... Autotools have many issues and are way more complex than need to be, but i do not see a build tool that does exactly the same thing as autotools do, despite being so many tools out there.
I didn't encounter any problems with vanilla clang on Windows for building projects (installed with "scoop install llvm"), in fact I was surprised that it worked out of the box, even for code that extensively uses Windows APIs). I suspect that it requires a MSVC toolchain installation, or at least the Windows SDK installed, but since everything "just worked" I didn't dive too deeply into what's actually happening under the hood.
I tried vcpkg recently and I was pleasantly surprised!
The Win installation  (assuming VS is already present) was pretty easy. I tested by running `vcpkg install glfw3` and copy-pasted an example from the web into VS2019. The example ran with _zero_ configuration!
Yes, the experience is just as nice on Linux, assuming you're using CMake to generate your Makefile. When you run the cmake generate command, you just need to add one option to specify the location of your vcpkg directory. Of course the same applies on Windows if you're using CMake to generate your Visual Studio project, except that you'll probably want to specify the triplet on the command line too (the default one is 32-bit).
Footnote: If you're doing this on Windows and want static linking then the experience is less smooth. You still need to specify the vcpkg directory and triplet (x64-windows-static), but that doesn't automatically change your application's CRT to the static one (which all your libraries are now assuming). There are a couple of ways round this but the easiest is probably to use MSVC_RUNTIME_LIBRARY CMake property (requires at least CMake 3.15, which is pretty new).
Different strokes for different folks. The solution to your problems is a simple batch file, but that might not be the solution to other peoples problems.
These "get of my grass" comments really miss the point. If you don't understand why you might need a more complex build system than "a simple batch file" then this really isn't software you need. That doesn't mean it's insane.
A lot of the time I see these build systems try to solve a few issues:
1. Dependency handling
2. Single script for multiple platforms
3. Easy for a new user to just "run"
But I have yet to find a build system (for C/C++) that solves all these issues better than simply having a few scripts.
I use just a build.batch, linux_build.sh and osx_build.sh usually and I have never had problems.
A new user can just download those scripts, and as long as they haven't tampered with file/library locations it just works.
If people like their build systems - fine by me - but I just think they are unnecessarily complex a lot of the time. Granted I don't have a huge project with 100's of dependencies, but even then, those dependencies don't come all at once.
Problem is I do tamper with those. I often cross compile software (my day job is embedded linux). Different distributions like to put things in different locations for their own reasons. I have a multi-core computer and I'd like to use more than one of them so my build goes faster.
As a developer I don't want to have to worry about how to make all of the above work. I learned cmake and so I don't have to worry, now that I know it (the learning curve is there) almost all my issues go away because it just works with all the weird stuff people do.
I mean sure, you always need to start with a binary somewhere, but to put this into perspective... the binaries needed to bootstrap all the software on the distro I run on my laptop weigh in at about 60 MiB. An x86_64 build of Bazel alone weighs in at about 27 MiB. As someone who cares about source bootstrappability, that feels like sliding backwards.
I suppose you may be able to find a chain of older versions of Bazel starting with one that doesn't require Bazel itself to build, like the Guix devs did for Rust.
Bazel is written in C++ and Java. The compile.sh (and the root of the repository) uses bash and probably a few other binaries. What are the issues exactly? Please file a bug if you have issues bootstrapping Bazel (it's not a need for most users, so the process might not be perfect).
I'm glad to see this. What people first and foremost forget is Bazel is a package manager/overlay in itself (and a very good one too), which allows for very complex (and yet safe and reproducible) builds.
The learning curve is steep though, but the payoff is so worth it.
I just started using Bazel this weekend for a personal (Rust) project. I understood the concepts which convinced me it was something I wanted to use. The documentation and tutorials definitely make the learning curve steeper than I think it needs to be.
It works so great though, now that I've managed to set it up.
Agreed. I flirted with it a couple times in the past and just couldn't get understand through the docs. This last time I ended up binging the bazelcon videos and things mostly clicked. The main thing to understand is the WORKSPACE/BUILD distinction and then you can mostly get there I think.
Thanks for the feedback! Do you have more specific feedback about the documentation? We can definitely make clearer the distinction between BUILD and WORKSPACE. Are there other concepts to clarify, or specific pages we should revamp?
I don't have any specific example off the top unfortunately, and some of my confusion was likely because I was trying to pick it up along the road of Bazel maturity so things were changing. When I say BUILD vs WORKSPACE distinction, I actually mean it was tough as an outsider who hasn't used a blaze-like system (or Cmake for that matter) to understand what the guardrails in bazel were and how the WORKSPACE provides certain guarantees to the rest of the system. So, it is a conceptual thing that once I understood that role, things clicked.
Depends on how you do it. It's designed first and foremost to work with vendored dependencies in a monorepo, and the external repository support is newer.
Bazel won't pull in transitive dependencies unless you ask it to in the WORKSPACE file, which means that you can use a private mirror for all your dependencies if you like, which is fairly easy in practice (I do it for personal projects).
The experience will vary depending on your preferences and the languages you use. With Go + Bazel, my experience is that the Bazel version will have fewer dependencies than the equivalent "go mod" version, because "go mod" will pull in dependencies more coarsely and Bazel has more fine-grained control. Go mod will pull in dependencies for the entire repo that you depend on, but with Bazel, you only need dependencies for the individual subpackages. As a specific example... suppose you use github.com/jackc/pgx. With "go mod" you end up with "github.com/sirupsen/logrus" in your transitive dependencies, but with Bazel you don't, unless you use the part of pgx that requires logrus.
You can also end up with "half the internet" in your dependencies pretty easily, but I think these days that is just the price of including random libraries in your project.
That's up to you. Bazel can fetch and build core from wherever: local or remote. Also, when fetching from git, it will high encourage you to use commits instead of tags, or when downloading archives from http, use a sha256.
resulting in things like the official tensorflow-distribution needing patching at 2 parts iirc to compile on new glibcs, because tensorflow and some network-dependency both vendor an outdated library overwriting a new glibc-function (some logging thing...). It works, until you want to fix some thing. Good times.
I really wanted Bazel to work for GO (not even C++). I gave up. It's got fine goals --- really nice ones --- but the doc sucks. We get stuck in crummy alley ways between corners of Bazel that does work well.
In the old school Linux distro world, dependency management is handled by the package manager. This way has benefits and drawbacks:
* there is specific version of the library associated with the OS that the developer can develop against - if the OS updates, the developer also has to update their apps - so they don't leave old bugs and vulns open
* there is specific version of the library associated with the OS that the developer has to develop against - if the OS updates, the developer also has to update their apps - which sometimes can be very annoying if the API breaks
There is more to it, but this is the thing that constantly has me changing my opinion on the matter.
> It's probably because I'm not very familiar with C/C++ library distribution, but what exactly does this mean, in the context of this post?
Some vocal part of linux community get extremely angry when packages don't use all the .so's provided by their (often outdated) distro of choice but instead rely on the dev of the app chosing the dependency versions which work best with its software.