[CMake] Can an option enforce a default, even if cache is present?

Roger Leigh rleigh at codelibre.net
Tue Nov 27 09:33:40 EST 2018


On 27/11/2018 13:49, Mario Emmenlauer wrote:
> 
> I've just discovered that option() behaves differently than I anticipated.
> After reading the docs and searching with google I'm still confused how to
> achieve my desired behaviour.
> 
> What I've just learned is that unspecified options take their cached value
> and do *not* go back to their default value, if a cache exists. I assumed
> that options take their default when not explicitly specified.

I think this is exactly what happens.  For example, an example I quickly 
dug out is this:

     # Doxygen documentation
     find_package(Doxygen)
     set(DOXYGEN_DEFAULT OFF)
     if (DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
       set (DOXYGEN_DEFAULT ON)
     endif (DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
     option(doxygen "Enable doxygen documentation" ${DOXYGEN_DEFAULT})
     set(BUILD_DOXYGEN ${doxygen})

which causes this to be set in the cache:

     //Enable doxygen documentation
     doxygen:BOOL=ON

In this case, doxygen and dot were installed.  But if one was missing, 
it would default to "OFF" and this would be set in the cache.  If the 
user noticed it was missing, installed it, then re-ran cmake, the cached 
value would not be changed even though the default set with option() 
changed in the meantime.

 From the look of things, there's no metadata in the cache to say "this 
was defaulted; the user did not specify it explicitly".  If such 
metadata did exist, the option() call could check it and overwrite the 
cached value if the user had not explicitly set the option.  This would 
make cmake much more conveniently adaptable.

The cache already stored extra properties for ADVANCED.  Could we add a 
similar extra property for DEFAULTED?  I.e.

     //DEFAULTED property for variable: doxygen
     doxygen-DEFAULTED:INTERNAL=1

Perhaps with a mark_as_defaulted() function to mirror 
mark_as_advanced().  Or a DEFAULT option for set_property() and/or a 
DEFAULT option as the opposite of FORCE for set().  This would only set 
the cache value if unset, plus add the DEFAULTED property.  The 
difference in behaviour would that if DEFAULT is used AND DEFAULTED=ON 
then the value would be overwritten if changed.


Regards,
Roger


More information about the CMake mailing list