0

I have been messing around with CMake for a while now, trying to learn the tool as much as possible. I have to admit that the concept of single configuration environments (Makefiles, Ninja) versus multi-configuration environments (Visual Studio, XCode, others) and generator expressions really confuses me. So, here is my question in a short format:

In CMake is it a good idea to have checks (such as: if conditions) to see what environment we are dealing with and proceed with specific commands from there? (For example, check if we are dealing with a multi-configuration environment, and use generator expressions only then)

Or is it possible and better to use generator expressions for both of them regardless of what we are dealing with?

starball
  • 20,030
  • 7
  • 43
  • 238
Default
  • 61
  • 1
  • 5

1 Answers1

1

Or is it possible and better to use generator expressions for both of them regardless of what we are dealing with?

Usually, yes. And I'd advise to do that as much as possible. If you support multi-config generators, you usually just get single-config generator support for free.

In CMake is it a good idea to have checks (such as: if conditions) to see what environment we are dealing with and proceed with specific commands from there? (For example, check if we are dealing with a multi-configuration environment, and use generator expressions only then)

In light of what I just said above, I'd expect this to just result in useless duplication, reduced readability, and maintenance burden. I'd suggest doing this only if you have no choice but to do it to achieve some particular functionality. Ex. If you wanted to generate some file to a per-configuration subdirectory for multi-config, but not add that additional intermediate subdirectory for single-config (I can't think of why one might want to do this, so it's probably not a great example, but it's what I thought of).

See also https://stackoverflow.com/a/73562787/11107541, which talks about the global property called GENERATOR_IS_MULTI_CONFIG.

Okay, for interest purposes, I went through one of my own projects and searched for where I use GENERATOR_IS_MULTI_CONFIG, and I use it in three places (I'm not saying I know best here and am doing the smartest thing- there could be better ways of getting what I want that I just don't know about- just trying to come up with some more realistic examples):

  • to define "default values" for variables like CMAKE_RUNTIME_OUTPUT_DIRECTORY and its friends such that there's an intermediate subdirectory for each config to separate their outputs, but not for single-config generators.

  • to only define the docstring and STRINGS property for CMAKE_BUILD_TYPE if the generator is single-config (just a quality of life thing for my users to avoid the common confusion of whether CMAKE_BUILD_TYPE is meaningful for multi-config generators (it isn't)).

  • to define a variable matching the directory where CMake will put object files for a target, which has an intermediate directory only for multi-config. Note that it's a pretty weird thing to care about where CMake will configure object files to be put. I needed it for -fprofile-prefix-path for a custom PGO build configuration.

starball
  • 20,030
  • 7
  • 43
  • 238
  • 1
    An possible example I can think of would be setting up+building separate cmake a project using the same generator/compiler during configuration/via custom target and for some reason not using the FetchContent stuff. It's extremely rare though and it's probably obvious you need different logic in both scenarios... – fabian Aug 27 '23 at 11:19
  • Thank you for the honest and straightforward answer. I was studying the book called "Professional CMake a practical guide" and when I came up to the generator expressions section I was so amazed by how great they are that I really did not understand why we would use anything else. Again thanks for the answer. – Default Aug 27 '23 at 17:57