Search code examples
cmakebuild

A cmake option that automatically specifies new values for other cmake options


Currently my CMakeLists.txt file contains lots of little options for including or excluding particular pieces of functionality from the build; by default everything is built, but the user remove a feature from the build by passing an argument like -DWITH_FEATURE_X=OFF on the command line:

option(WITH_FEATURE_X "Enable feature X" ON)
if (WITH_FEATURE_X)
   file(GLOB FEATURE_X_SRCS "${TOP_DIR}/feature_x/*.cpp")
   list(APPEND ALL_SRCS ${FEATURE_X_SRCS})
else ()
   message("CMake:  -DWITH_FEATURE_X=OFF argument was specified:  building without feature X.")
   add_definitions(-DAVOID_FEATURE_X)
endif ()

... this works fine, but it's a little tedious in some cases where the caller has to specify a dozen -DWITH_FEATURE_X=OFF type arguments on the command line.

Since I know in advance of several common uses-cases where the user would like to specify a known set of features to be disabled, I'd like to be able to specify that with a single argument, something like this:

cmake -DWITH_MINIMAL_CONFIGURATION=ON ..

.... and have the CMakeLists.file act as if the user had specified:

cmake -DWITH_FEATURE_X=OFF -DWITH_FEATURE_Y=OFF -DWITH_FEATURE_Z=OFF [...and so on...] ..

Is there a way to do that, that won't overcomplicate the implementation of the CMakeLists.txt file?


Solution

  • CMake presets (since version 3.19) could be a good option here.

    You could have a minimal_configuration configuration preset that would set those variables as cacheVariables. And then a minimal_configuration build preset that would use the minimal_configuration configuration preset.

      "configurePresets": [
        {
          "name": "minimal_configuration",
          ...
          "cacheVariables": {
            "WITH_FEATURE_X": "OFF",
            "WITH_FEATURE_Y": "OFF",
            "WITH_FEATURE_Z": "OFF",
            ...
          },
        }
      ],
      "buildPresets": [
        {
          "name": "minimal_configuration",
          "configurePreset": "minimal_configuration"
        }
      ]
    

    Notice you can define a hierarchy of configuration presets, and let each level of that hierarchy manage different settings. For example, you could have a common_config first level, a windows_config and unixlike_config second level, a windows_debug_config, windows_release_config (and so on) third level...

    In order to run CMake for a given preset, just pass it as a command line option:

    ~/your_project> cmake --preset minimal_configuration
    ~/your_project> cmake --build --preset minimal_configuration