The problem I have with CMake & autotools is that every project writes their build process from scratch, and everyone does things slightly differently making their project a snowflake.
Certain platforms, compilers, and dependencies need special handling and workarounds, and this knowledge isn't shared and has to be repeatedly rediscovered by every project.
Rust's Cargo, perhaps accidentally, has found a fantastic solution to this. The build process itself is built out of packages. I don't have to know how configure MSVC compiler, I just use an existing crate for it. I can use existing package to find and configure libpng — the work to handle its own quirky pkg-config replacement has been done once, and now every downstream project can benefit from it.
Package manager in the build system may sound strange, but it's actually fantastic. It works so well that I switched my C projects to Cargo to be able to build them on Windows.
Your critique is fair for autotools but not CMake, which encodes a ton of platform and compiler specific knowledge [1]. cmake modules can also be used to find libraries, e.g. FindPNG for libpng.
The bundled Find* modules are great, but once you go beyond what's included you often run into problems.
In converting a recent project to CMake (so as to use CLion), I encountered all of the following:
- find_package modules that didn't support REQUIRED or VERSION options
- Lack of standardization on whether find_package variables include recursive dependencies
- Some modules supply imported targets, some don't - requires different consumption
The fact is, I can't simply rely on find_package doing what I expect - I have to read each and every Find*.cmake I use.
On top of that, there's a bunch of conflicting information out there - should your source list include header files? Some older blog posts suggest it's necessary for dependency calculation, newer ones don't seem to mention it; I honestly have no idea what the right answer is.
IMO yes. Part of CMakes usefulness is IDE integrations, so listing your headers means they show up in your IDE.
As for your points about find modules not working, that’s not really CMakes fault. I’ve spent days fixing bad autotools/premakr/scons/custom scripts, (not to mention third party code in general).
I agree that it's not CMake's fault, but it does fit the grandparent's statement that "everyone does things slightly differently".
It's also very fixable - a central site for collecting find_package modules and enforcing certain standards should be doable, and would improve CMake's UX significantly.
Yeah agreed, a site of find package modules would go a long way towards helping, but only if they’re vetted in some way, otherwise nothing r ally changes.
> I keep considering that we might want to port Cargo to support other languages... It's better than nearly everything out there that I've ever used.
I don't think that this would solve anything. A big problem for instance is maintainers who insist in keeping compatibility for totally obsolete stuff - see for instance zlib which clings on DOS compatibility, or Nethack which just started to use ANSI C features in the latest release ; before this they were on K&R C. As a result build sytems are terrible since they have to handle so many edge cases for obsolete compiler vendors, Watcom C & friends for instance. Rust code doesn't have this kind of legacy to handle.
For C it’s not as obvious how this could be accomplished, but it would be possible. There are lots of Rust projects that embed C today, and add C flags for the LLVM.
The language I was really thinking of was Java, where Cargo is far superior to maven. I’ve never had time, but what I’ve thought would be neat is to take a Cargo.toml file as input, and then generate the maven files from that, like Cargo.lock files in Rust.
Certain platforms, compilers, and dependencies need special handling and workarounds, and this knowledge isn't shared and has to be repeatedly rediscovered by every project.
Rust's Cargo, perhaps accidentally, has found a fantastic solution to this. The build process itself is built out of packages. I don't have to know how configure MSVC compiler, I just use an existing crate for it. I can use existing package to find and configure libpng — the work to handle its own quirky pkg-config replacement has been done once, and now every downstream project can benefit from it.
Package manager in the build system may sound strange, but it's actually fantastic. It works so well that I switched my C projects to Cargo to be able to build them on Windows.