Hacker News new | ask | show | jobs
by hedora 1917 days ago
100% of your assumptions are wrong.

I have years of experience with cmake, and all the other things you mentioned. I work in environments where the correctness of the binaries is important, and cmake fights that at every possible step. The documentation is poorly organized and overly verbose. 99% of the details in the docs are irrelevant 99% of the time, and the important details are missing or relegated to a non-discoverable page elsewhere on their site.

5 comments

Come on... make is a perfectly good choice (and for me, preferable) for any project that is small to medium sized. However if you get to a stage where you have to compile for 3 or more platforms and need to account for different compiler versions & systems that people may be using, 'make' quickly becomes hell to use. The possible build combinations just get out of hand, and you can't if-then-else your way out of every situation. Ultimately you get to a point where makefiles can't deal with the growing complexity of a big project.

That is where CMake really shines - it takes the headache out of managing complex, sprawling builds once you get it setup, and you won't have to keep tweaking the config to manage every other dev's system. I grant that the documentation is not perfect and there is a significant time investment in getting everything 'just so', but the long-term time savings make up for that completely in my experience.

I agree with your opinion of CMake.

Most of my career has been in non-mainstream software development. There's always a ton of rare, unique, or broken stuff that I have no control over. In many situations, adding an extra layer via a generator (such as CMake) adds more work than convenience.

I've also found CMake's documentation to be useless most of the time.

By the time I track down and fix all the issues, I might as well have just written a Makefile (or whatever obscure, ancient build tool they use).

Though I agree with your points, and do not like CMake either (I tend to much prefer autotools or plain make) there has been a time when I saw the use of it: maintaining a software with developers both on Windows using VS and Linux using make.
Please substantiate the claim about how "cmake fights that at every possible step." There's so much hyperbole in your statement that it really does seem like you've spent "years of experience with cmake" futzing around.
So, assume that you need byte-for-byte identical upstream dependencies, and also assume you want to run in a modern CI environment. In make, you build a docker with a line like:

RUN tar -C opt xvf /…/foo-1.2.3.tgz RUN <build the thing if needed>

And a few lines like this in make:

INC += $(wildcard /opt/foo-*)/include LIBS += -L…

This generalizes elegantly to subdirectories. (See “Recursive Make Considered Harmful” for the right way to do it), and (crucially!) it won’t build if you don’t have the build environment set up correctly.

It also lets you prevent the CI build container from talking to the internet, so outages of upstream server infrastructure, or package-manager-du-jour serving bitcoin miners can’t directly break production binaries.

It also generalizes to building in other people’s operating systems, etc.

With cmake, you need to read the documentation for find_foo, which invariably has a different calling convention than find_bar (if it exists at all), and it will try to look places it should not for the library. Adding a library this way takes hours.

Also, the docker + make approach works well with languages other than c/c++; cmake does not, unless cmake happens to include built-in support for the language in question.

You can just add_library a filepath in cmake too. You don't have to use the find module. It isn't idiomatic cmake, but it's 100% possible. It sounds like you have specific niche needs, so it's a reasonable approach for your case. IMO it's unfair to criticise cmake for this, since it can do the exact same thing as make in this instance.
Works well, provided one is on GNU/Linux and nothing else.
I don't know what exactly the poster was dealing with, but I've been trying to get reproducible builds out of cmake and it was a serious pain due to cmake insisting on using absolute file paths.

(Ed.: Also I agree the cmake docs are atrocious.)

> due to cmake insisting on using absolute file paths

????

I can't tell you whether this is/was innate cmake behavior or whether something was wrong with the specific project, but cmake passed all source file names to the compiler using the full file system path rather than a relative path.

This is a serious (though slowly becoming a non-issue) problem since compilers encode source file names into the output binary's debug information and strings (__FILE__). The "-fdebug-prefix-map=old=new" GCC option and its cousins are what is slowly making this a non-issue, but those are a relatively recent addition.

It is generator-specific. Try "Unix Makefiles" vs "Ninja" and you'll see the difference.
I will say with well-defined projects you can turn it over to ide developers and they can turn on and off options and generate release and debug builds in the gui without having to become experts.

But yeah, figuring out what linker options were generated or even how to version a project takes a lot of digging into the bowels of cmake or a couple laps through the documentation.