6 ms·
CMake is a hell for medium/large projects. Builds are not hermetic/reproducible. When doing deep change of CMake files, the only reliable way to verify it is c
by lightgreen 6y ago
CMake is a hell for medium/large projects.
Builds are not hermetic/reproducible. When doing deep change of CMake files, the only reliable way to verify it is correct is to clean and rebuild everything.
CMake is very very slow. A minor change in CMake file results in CMake re-evaluation which is very slow for large projects.
CMake language is just pain.
And CMake does not have cache. CCache helps a little, but it’s still much worse than cache of proper modern build system.
I would probably recommend Bazel for building C++. Works like magic. Although if you hit Bazel limitations (likely you won’t but still), you don’t have many options how to deal with it. You never need to clean Bazel cache whatever you are doing (unless you are intentionally trying to break it of course).
- enriquto 6y ago> CMake is a hell for medium/large projects. I agree. And if you let me, I want to add that for small projects it is ridiculous overkill. This leaves no reasonable use case for cmake (except maybe building itself solipsistically for all eternity). And I like it that way.
- lightgreen 6y agoCMake was a big improvement over make and autoconf years ago, but now it’s time to admit that it was a step to a wrong direction, dead end, cannot be fixed. CMake model is wrong. CMake just need to retire.
- pmezard 6y agoWhat is the good model?
- lightgreen 6y agoBazel’s: * each build file is independent (unlike CMake where the project is one big script with global scope and side effects) * build script evaluation is hermetic (cannot read time for example) and strictly reproducible * target is rebuilt not by timestamp changes (which is unreliable for several reasons), but instead all dependencies must be declared, and target is rebuilt when the hash of dependencies change
- barumi 6y ago> each build file is independent (unlike CMake where the project is one big script with global scope and side effects) I don't understand your point. CMake projects specify build targets per module, and it's up to the developer to choose what he thinks should be a module. What value do you see in specifying build targets per file?
- lightgreen 6y agoI'm not saying about specifying build target per file. I say when cmake file includes another cmake file, all variables are inherited, and in certain cases cmake file can define variable in outer cmake file scope. Thus build files are dependent on each other. Inclusion order is important, and when project refactoring/restructuring, it's a common error, that resulting project is incorrect because for example, some file relied on the fact that when it is included, certain variables or macros are already set by someone else. This makes large project maintenance quite inconvenient. Especially because CMake does not guarantee that error will be revealed unless it is full clean rebuild.
- barumi 6y ago> I say when cmake file includes another cmake file, all variables are inherited, and in certain cases cmake file can define variable in outer cmake file scope. This is not true at all. You only "inherit" variables that you intentionally want to pass to downstream projects. You need to explicitly and intentionally declare your variables with PARENT_SCOPE to access variables from other files. That's an explicit decision from the developer.
- lightgreen 6y ago> You only "inherit" variables that you intentionally want to pass to downstream projects Yep, most project variables, except for some locals. > You need to explicitly and intentionally declare your variables with PARENT_SCOPE to access variables from other files. No you don't. PARENT_SCOPE is needed to write variables into parent scope, but not read. > That's an explicit decision from the developer. Even so. Yes, when working very carefully, when you are a single developer writing on a small projects, and enforce code style, it is possible to keep the mess manageable. When at least 100 people work on the project, if a project is several years old, if half of the team changed, CMake project is always a mess. (Source: I worked in two very different large companies which were using CMake; both of them eventually migrated away from CMake). Someone might blame developers for making that mess. I'd prefer blaming CMake, as I see the same developer keep projects in good shape when using Bazel (or another build system with similar model).
- endgame 6y ago> CMake was a big improvement over make and autoconf years ago I would not even grant this, and I spent a lot of time wrangling both CMake and autotools many years ago.
- andi999 6y agoWhat is the model of CMake. Probably I could use it better if I knew (I couldnt figure it out).
- lightgreen 6y agoBasically it is one big script (with globals and side effects) which generates makefiles. (Even if it does not generate makefiles, the project model is makefiles: targets, file names, timestamps.)
- andi999 6y agoSo the globals and side effects are the problem or the generating makefiles part?
- lightgreen 6y agoBoth are the problems. Because of side effects, when single cmake file modified, the whole project need to be regenerated. Also, because of side effects, project files become too frigile, for example, changing the order of two includes may result in incorrect project definition. And makefile generation part is problematic: using timestamps to check if something need to be rebuilt is unreliable (may result in not rebuilding something when project is actually changed).
- andi999 6y agoIsnt the makefile generation the only reason one uses cmake?
- lightgreen 6y agoIt is also used to generate project files for various ides. Also, (but I’m not sure), cmake have some built in make which does the build like mske would do but without generating makefiles and invoking real make.
- krapp 6y ago>I agree. And if you let me, I want to add that for small projects it is ridiculous overkill. I don't think it is. On Windows at least, it's still easier to build a VS project links with libraries and everything linked by editing a text file than it is to go through the GUI, and VS is worth using as a debugger if nothing else.
- enriquto 6y agoI concede that cmake makes windows/VS portability easier. But that's probably the only advantage I can see, to be weighted against all the other shitty stuff. Anyhow, for C programmers this is a non-issue since VS does not compile C.
- scatters 6y ago> VS does not compile C That's out of date; VS is adding C11 and C17. https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/ https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-...
- enriquto 6y agoNo complex numbers and no vla. That's not what many C programmers call C nowadays.
- xvilka 6y agoSpinning up JVM just to build a C/C++ project? No thanks. At least CMake is lean enough and native.
- lightgreen 6y agoIs this is your only argument against Bazel, I consider your comment a praise of that build system.
- MaxBarraclough 6y agoIs it possible to use Graal's ahead-of-time compilation with Bazel? Or perhaps something like Nailgun? ( http://www.martiansoftware.com/nailgun/background.html http://www.martiansoftware.com/nailgun/background.html )
- lightgreen 6y agoIt already does that. On first run, Bazel spawns a background process, which does all the work. In particular, it caches all the state (e. g. file hashes, parsed build files etc.)
- MaxBarraclough 6y agoThanks for the reply. How does its package-detection stack up against CMake? One of CMake's advantages is that there's a Find module for most well-known libraries.
- lightgreen 6y agoI don't know much about it, because I believe dependency on installed in system libraries lead to non-reproducible builds (each machine is configured differently). Quick googling shows there is a lot of external rules for pkg-config https://github.com/cherrry/bazel_pkg_config https://github.com/cherrry/bazel_pkg_config or rules for building third-parties with cmake https://github.com/bazelbuild/rules_foreign_cc https://github.com/bazelbuild/rules_foreign_cc for example.