Better contextual introduction for new users

I’m a moderately advanced GNU Make user new to CMake, and I have some questions I’d expect to find in the FAQ to help me better contextualize what CMake can and can’t do, and what it is and isn’t good at, and understanding what problems it solves. I will try to present these as clearly as possible.

Disclaimer: At this point, I am primarily interested in understanding CMake from the perspective of understanding and improving one particular project (“Blender”) already using CMake.

  • I understand that CMake generally just generates makefiles, build files or project files for whatever environment is being targeted. Can/will it invoke these build tools as well? Or is that typically always done by the user?

  • I understand that many CMake options (like -DVERBOSE=On) are given on the command line, rather than in the project’s configuration. Do these generate stateful differences in the output makefiles? Or simply invoke the build tools such that the generated tooling, that is already sensitive to these running states? Are different variations of these options generally put in distinct out-of-tree build directories so they don’t overwrite each other? Can a user provide default values for some of these command line options in an optional config file that can be .gitignored? How is that done?

  • I know CMake stays aware of it’s version and compatibility. Does it maintain awareness of versions of installed tools that it generates files for? Does it vary the output based on installed versions?

  • POSIX and GNU Make both have many well-documented shortcomings. (i.e. ignoring file content changes and relying on time stamps, ease of corrupting a build state by interrupting a build, difficulties in propagating dependencies properly through recursive makefiles, language readability and parseability. etc…) Some of these can be mitigated by “clever techniques”/hacks to work around some of these. Does CMake optionally, or by default try to implement any of these strategies? Does CMake have any role in avoiding these pitfalls?

Thank you for your patience with my likely-naive questions. If any of these questions is particularly project-specific, please let me know so I can ask within the project.

Thank you in advance for your insights,

Loren Osborn

Yes, see the cmake --build command.

It depends on the option. Usually, if something is specified at configure time, then it will be written into the build files in some way so that the user doesn’t have to re-specify the option at build time.

See the presets feature, you can specify default values for any cache variable.

Yes.

This is better answered by a CMake maintainer, but in my experience it doesn’t really matter, because you rarely need to actually read the Makefile generated by CMake. So you don’t really care what its content is.

1 Like

Only very minor. Obviously, VS 2012 generation is going to differ from VS 2022. However, the Makefiles and Ninja generators have much less variance. I think Makefiles doesn’t care about the impl all that much (CMake uses POSIX make and only adds things to disable extensions like GNU Make’s builtin rules unconditionally). Ninja versions really only unlock features like dyndep; the files themselves are the same otherwise; CMake will call some cleanup commands if available, but that’s about it.

CMake currently only supports timestamp detection at its core. There is work on ninja itself to support other mechanisms, but it’s not merged nor does CMake have a plan to expose it (as what do we do for other generators?).

CMake doesn’t use recursive makefiles for the actual builds. There are recursive makefiles for the “UI” of the target naming and chaining from any directory, but the standard argument doesn’t apply (AFAIK).

The generated files aren’t really meant for human consumption; I wouldn’t worry about it too much. I’ve done some cleanup on generated ninja files to help with perf, but that was on CMake’s side (at its core: stringstreams are slow).

CMake has its own semantics that it just renders into the various implementations. There’s no mechanism to drop raw msbuild, ninja, or Makefile snippets into the files generated, so as long as CMake’s semantics are expected, things should Just Work™.