c++cmakeconfigurationconfigcmake-gui

Dependent options caching in cmake via ccmake


Im working on a project with multiple OPTION commands in the cmake hierarchy.
If one option is enabled (OPTION_A=ON), than other options (OPTION_B) are added via newly included subdirectory into the cmake cache:

CMakeLists.txt:

OPTION(OPTION_A "Do such and such" OFF)
IF(OPTION_A)
    add_subdirectory(subdir)
ENDIF(OPTION_A)

subdir/CMakeLists.txt:

OPTION(OPTION_B "Do this and that" OFF)
IF(OPTION_B)
    add_subdirectory(subsubdir)
ENDIF(OPTION_B)

subdir/subsubdir/CMakeLists.txt:

OPTION(OPTION_C "Do foo then bar" OFF)
IF(OPTION_C)
    <...>
ENDIF(OPTION_C)

This is nice, since when working with ccmake for example, I'm not disturbed with OPTION_B/C unless OPTION_A/B was configured ON, thus generating OPTION_B/C in the CMakeCache.txt

The problem is in the reverse direction:
when disabling OPTION_A, OPTION_B & OPTION_C cached variables still show up in ccmake.

I've come up with three solutions:

  1. Unset every option I know isn't going to be used from the external file.
    This solution breaks quickly for "deep" projects since ELSE(OPTION_A) now needs to unset(... CACHE) both OPTION_B, OPTION_C, and all other cached variables of their respective subdirectories.
  2. Clean the CMakeCache and start configuring from scratch.
    This solution breaks for "wide" projects, since to clean one option field I'm forced to clear his co-directories cache variables.
  3. Modify cmake to have an "opaque" cache, for variables saved but not accessed in generation stage.
    Modify ccmake to grey-out/hide the "opaque" cache, presenting only accessed cached variables.
    Shouldn't disturb automatic cmake usage, and since ccmake is a GUI I think this is not a breaking change to it either.

Is there a one-for-all solution for both "wide" and "deep" cmake hierarchies that will not require modifying cmake? Is this a common issue worth the entailed effort?


Solution

  • What Tsyvarev mentioned in a comment, you can make options that are dependent on other options using CMakeDependentOption.

    Here OPTION_B becomes available and defaults to ON only if OPTION_A is ON, otherwise it'll be set to OFF. You can set its default to OFF too but I made it ON here to make it clear which is which:

    OPTION(OPTION_A "Do such and such" OFF)
    
    CMAKE_DEPENDENT_OPTION(OPTION_B "Do this and that" ON
                           "OPTION_A" OFF)