Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Maybe it wasn't your intention, but your comment is the most scathing critique I've ever read of cmake.

Boilerplate code and "compiler checks" are strongly negative anti-patterns. Maybe the worst in programming. That cmake makes it easy to do these awful things just shows how evil it is!

People: write simple, portable code!



> People: write simple, portable code!

That isn't always how it works in practice, though. It's useful for your build system (or meta-build system) to be able to check for, say, C++17 support, and cause the build to fail early if this is missing.

Similarly, you can use a tool like CMake to detect libraries. If a library is missing, you might want the build (or, rather the 'configure' stage) to instantly fail, or you might want to build with certain features removed to cope with the library being missing. CMake supports both, as does autotools.

I agree with everyone who says CMake's scripting language is atrocious and that it's often miserable to work with, [0][1] but that's because CMake specifically is terrible. The problem it's solving is a legitimate one.

An example: you can write a desktop application with two different platform-specific front-ends, and have CMake compile the appropriate one given the target platform. This is nicer than relying on the two platform-specific build systems directly.

[0] https://news.ycombinator.com/item?id=24203172

[1] https://news.ycombinator.com/item?id=24565266


>, you can use a tool like CMake to detect libraries. If a library is missing, you might want the build (or, rather the 'configure' stage) to instantly fail, or you might want to build with certain features removed to cope with the library being missing. CMake supports both, as does autotools.

The gp enriquto had a rigid stance on so-called "optional" libraries. If the library is not there, the build should fail and that's it.

I don't know if my previous reply to him explaining the benefits of building even with missing libraries was satisfactory: https://news.ycombinator.com/item?id=25913562


Hey! I remember that interaction (and sorry for my crass language, I was having a hard time by then).

Your explanation was certainly satisfactory. Now I understand a bit the motivation of people who want to compile different programs depending on what happens to be installed at a particular moment in their computers. I still think that it is "an exceptionally bad idea which could only have originated in California" ;)


> People: write simple, portable code!

that does not work as soon as your users are on both windows and a unix-like platform and you are making a non-trivial app (for instance, an app with networking, audio, and video support).

A simple example: how do you share a GPU texture handle across multiple processes portably with a single code that works across windows / mac / linux's graphics APIs ?


Trying to do that is a massive waste of time. It's legitimately easier to maintain separate codebases for each of the different platforms. The code that doesn't need to change can be a library. Or you use some super high level abstraction like Unity, Qt, JVM, Electron, React Native. Portability != cross-platform.


Yeah, now throw game consoles, embedded systems or classical mainframes into that mix as well.


> People: write simple, portable code!

How do you memory map a file, or spawn a subprocess simply and portably? Every way that I've seen it done that doesn't hand the logic off to the build system is an unmaintainable error prone mess.


I'm not sure you understood what I've said at all.

CMake eliminates boilerplate code and compiler checks. They do not exist, at all. With CMake you state that you have a C++11/14/17/20 project, it builds N static/shared libs and M executables, you set dependencies, and you're done.

They do exist in Makefile projects because Makefiles only define the DAG for the build, and don't perform any sanity check at all. So if you have to include dependencies or use specific compilers then you have to manually check each and every single thing yourself, because Makefiles do not handle that at all.

Think about it: why did the entire industry adopted makefile generators such as CMake instead of just using a standard tool like make, which just works and is ubiquitous?

And no, relying on tools and a layer of abstraction to eliminate all janitorial work is not evil or awful. Checking if a lib you depend on already exists in the system is not evil or superfluous. Checking if the compiler you're using supports a specific version of C++ is not evil or superfluous. Do you expect things to just work when you aren't even aware of which compiler you're going to use? Do you want to spend time looking at weird compiler error dumps just because your build machine happens to have a different version of, say, Boost installed?

The main problem of cmake is that some people seem totally oblivious to the problem domain, and what/how much work it takes to get stuff to work reliably given very basic usecases such as... Upgrading a version of a compiler, such as VS. Think about it: How exactly do you think simple, portable code is done? Do you expect code to compile on different platforms by magic?


> Checking if the compiler you're using supports a specific version of C++ is not evil or superfluous.

It is both evil and superfluous. It is evil because you should be writing portable code and do not depend on compiler specificities. It is superfluous because if you do not check, the compilation will still fail, which is precisely the expected behaviour.

> How exactly do you think simple, portable code is done?

By writing it carefully and testing it on different systems. You test with -Wall -Wextra -Werror -pedantic on all systems but you distribute the Makefile without these compiler flags.

> Do you expect code to compile on different platforms by magic?

No, of course. At first you will have a few linuxisms or macOS-isms, that you will gradually remove through a few rounds of multi-platform testing (which is free and easy to do nowadays).


> It is both evil and superfluous. It is evil because you should be writing portable code and do not depend on compiler specificities. It is superfluous because if you do not check, the compilation will still fail, which is precisely the expected behaviour.

But now I get 2 dozen error reports because there is a lot of users who run builds because they're on Linux and that's what $BLOGPOST said to do to have the last version of some software, but have no clue about software development.

> No, of course. At first you will have a few linuxisms or macOS-isms, that you will gradually remove through a few rounds of multi-platform testing (which is free and easy to do nowadays).

So how do you handle that you need to link against Ws2_32 on windows or "-lwebsocket.js -s PROXY_POSIX_SOCKETS=1 -s USE_PTHREADS=1 -s PROXY_TO_PTHREAD=1" on emscripten if you want to use sockets ? Don't use sockets because they're not portable ?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: