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

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Mario Emmenlauer

Dear all,

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.

Now my problem: I could not find a way to get the behaviour I'd like. Is it
possible to enforce the default for an option when its not specified by the
user, even if a cache exists?

I tried to unset() the option from the cache but that does not do what I'd
like.

All the best,

    Mario Emmenlauer
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

Roger Leigh
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
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

Eric Noulard
In reply to this post by Mario Emmenlauer



Le mar. 27 nov. 2018 à 14:50, Mario Emmenlauer <[hidden email]> a écrit :

Dear all,

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.

The behavior of option() gained new behavior in CMake 3.13.
May be it could help in your particular case: https://cmake.org/cmake/help/v3.13/policy/CMP0077.html#policy:CMP0077

you'll depend on latest CMake though.
 

Now my problem: I could not find a way to get the behaviour I'd like. Is it
possible to enforce the default for an option when its not specified by the
user, even if a cache exists?

You mean you did not manage to force the cache value?
You can:
set(VAR "default_value" CACHE FORCE)

or the problem is you cannot know whether if a value has been user-provided?


I tried to unset() the option from the cache but that does not do what I'd
like.

All the best,

    Mario Emmenlauer
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake


--
Eric

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

Mario Emmenlauer
On 27.11.18 17:13, Eric Noulard wrote:

> Le mar. 27 nov. 2018 à 14:50, Mario Emmenlauer <[hidden email]
> <mailto:[hidden email]>> a écrit :
>     Dear all,
>
>     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.
>
>
> The behavior of option() gained new behavior in CMake 3.13.
> May be it could help in your particular case:
> https://cmake.org/cmake/help/v3.13/policy/CMP0077.html#policy:CMP0077
>
> you'll depend on latest CMake though.
>
>
>     Now my problem: I could not find a way to get the behaviour I'd like. Is it
>     possible to enforce the default for an option when its not specified by the
>     user, even if a cache exists?
>
>
> You mean you did not manage to force the cache value?
> You can:
> set(VAR "default_value" CACHE FORCE)
>
> or the problem is you cannot know whether if a value has been user-provided?

Sorry, I was not very precise! Your last point is the problem. I fail to know
when the option was user-provided and when it was cache-provided.

So here is what I'd like:

#> grep MYOPT CMakeLists.txt
option(MYOPT "Description" OFF)
#> cmake              # I want the option disabled, this works fine.
#> cmake -DMYOPT=ON   # I want the option enabled, this works fine.
#> cmake              # I want the option disabled (back to default),
                       # but I observe the option taken from cache, enabled.

Is there some way to achieve my desired behaviour? I tried without success
unset(MYOPT), unset(MYOPT CACHE), and set(MYOPT OFF) before option(), but
they all lead to different behaviour.

All the best,

     Mario

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

frodak
On Tue, Nov 27, 2018 at 3:15 PM Mario Emmenlauer <[hidden email]> wrote:

>
> On 27.11.18 17:13, Eric Noulard wrote:
> > Le mar. 27 nov. 2018 à 14:50, Mario Emmenlauer <[hidden email]
> > <mailto:[hidden email]>> a écrit :
> >     Dear all,
> >
> >     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.
> >
> >
> > The behavior of option() gained new behavior in CMake 3.13.
> > May be it could help in your particular case:
> > https://cmake.org/cmake/help/v3.13/policy/CMP0077.html#policy:CMP0077
> >
> > you'll depend on latest CMake though.
> >
> >
> >     Now my problem: I could not find a way to get the behaviour I'd like. Is it
> >     possible to enforce the default for an option when its not specified by the
> >     user, even if a cache exists?
> >
> >
> > You mean you did not manage to force the cache value?
> > You can:
> > set(VAR "default_value" CACHE FORCE)
> >
> > or the problem is you cannot know whether if a value has been user-provided?
>
> Sorry, I was not very precise! Your last point is the problem. I fail to know
> when the option was user-provided and when it was cache-provided.
>
> So here is what I'd like:
>
> #> grep MYOPT CMakeLists.txt
> option(MYOPT "Description" OFF)
> #> cmake              # I want the option disabled, this works fine.
> #> cmake -DMYOPT=ON   # I want the option enabled, this works fine.
> #> cmake              # I want the option disabled (back to default),
>                        # but I observe the option taken from cache, enabled.
>
> Is there some way to achieve my desired behaviour? I tried without success
> unset(MYOPT), unset(MYOPT CACHE), and set(MYOPT OFF) before option(), but
> they all lead to different behaviour.
>

I've always used 'cmake -UMYOPT'  to remove specific items from the
cache (or edit the cache file directly).
I don't think the notion of user-provided or cache-provided entries
exist because all user defined variables go into the cache.
Then you can test to see if MYOPT is set and then use the default
value when recreating the cache entry.
Also cmake cache variables are persistent between invocations so the
user doesn't need to keep specifying them at the command line every
time cmake needs to run.

Best regards...
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

Petr Kmoch
On Tue, 27 Nov 2018 at 21:42, frodak <[hidden email]> wrote:
On Tue, Nov 27, 2018 at 3:15 PM Mario Emmenlauer <[hidden email]> wrote:
>
> On 27.11.18 17:13, Eric Noulard wrote:
> > Le mar. 27 nov. 2018 à 14:50, Mario Emmenlauer <[hidden email]
> > <mailto:[hidden email]>> a écrit :
> >     Dear all,
> >
> >     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.
> >
> >
> > The behavior of option() gained new behavior in CMake 3.13.
> > May be it could help in your particular case:
> > https://cmake.org/cmake/help/v3.13/policy/CMP0077.html#policy:CMP0077
> >
> > you'll depend on latest CMake though.
> >
> >
> >     Now my problem: I could not find a way to get the behaviour I'd like. Is it
> >     possible to enforce the default for an option when its not specified by the
> >     user, even if a cache exists?
> >
> >
> > You mean you did not manage to force the cache value?
> > You can:
> > set(VAR "default_value" CACHE FORCE)
> >
> > or the problem is you cannot know whether if a value has been user-provided?
>
> Sorry, I was not very precise! Your last point is the problem. I fail to know
> when the option was user-provided and when it was cache-provided.
>
> So here is what I'd like:
>
> #> grep MYOPT CMakeLists.txt
> option(MYOPT "Description" OFF)
> #> cmake              # I want the option disabled, this works fine.
> #> cmake -DMYOPT=ON   # I want the option enabled, this works fine.
> #> cmake              # I want the option disabled (back to default),
>                        # but I observe the option taken from cache, enabled.
>
> Is there some way to achieve my desired behaviour? I tried without success
> unset(MYOPT), unset(MYOPT CACHE), and set(MYOPT OFF) before option(), but
> they all lead to different behaviour.
>

You're forgetting one important aspect of CMake: that it can retrigger itself when a CMake source file changes. Such a run of CMake is indistinguishable from running it manually, and it's (a large part of) why the cache exists in the first place. Imagine the following scenario:

User runs >cmake -DMYOPT=ON
User edits a CMakeLists.txt (or even just a file processed by configure_file()).
User runs >make

As part of this make, CMake triggers to regenerate the buildsystem. If MYOPT exhibited the behaviour you request, it would silently get disabled again, even though this is most definitely not what the user expects. I addressed a similar point in this StackOverflow answer: https://stackoverflow.com/a/41361741/1782465

Petr
 

I've always used 'cmake -UMYOPT'  to remove specific items from the
cache (or edit the cache file directly).
I don't think the notion of user-provided or cache-provided entries
exist because all user defined variables go into the cache.
Then you can test to see if MYOPT is set and then use the default
value when recreating the cache entry.
Also cmake cache variables are persistent between invocations so the
user doesn't need to keep specifying them at the command line every
time cmake needs to run.

Best regards...
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Can an option enforce a default, even if cache is present?

Mario Emmenlauer

On 28.11.18 12:38, Petr Kmoch wrote:

> On Tue, 27 Nov 2018 at 21:42, frodak <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On Tue, Nov 27, 2018 at 3:15 PM Mario Emmenlauer <[hidden email] <mailto:[hidden email]>> wrote:
>     >
>     > On 27.11.18 17:13, Eric Noulard wrote:
>     > > Le mar. 27 nov. 2018 à 14:50, Mario Emmenlauer <[hidden email] <mailto:[hidden email]>
>     > > <mailto:[hidden email] <mailto:[hidden email]>>> a écrit :
>     > >     Dear all,
>     > >
>     > >     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.
>     > >
>     > >
>     > > The behavior of option() gained new behavior in CMake 3.13.
>     > > May be it could help in your particular case:
>     > > https://cmake.org/cmake/help/v3.13/policy/CMP0077.html#policy:CMP0077
>     > >
>     > > you'll depend on latest CMake though.
>     > >
>     > >
>     > >     Now my problem: I could not find a way to get the behaviour I'd like. Is it
>     > >     possible to enforce the default for an option when its not specified by the
>     > >     user, even if a cache exists?
>     > >
>     > >
>     > > You mean you did not manage to force the cache value?
>     > > You can:
>     > > set(VAR "default_value" CACHE FORCE)
>     > >
>     > > or the problem is you cannot know whether if a value has been user-provided?
>     >
>     > Sorry, I was not very precise! Your last point is the problem. I fail to know
>     > when the option was user-provided and when it was cache-provided.
>     >
>     > So here is what I'd like:
>     >
>     > #> grep MYOPT CMakeLists.txt
>     > option(MYOPT "Description" OFF)
>     > #> cmake              # I want the option disabled, this works fine.
>     > #> cmake -DMYOPT=ON   # I want the option enabled, this works fine.
>     > #> cmake              # I want the option disabled (back to default),
>     >                       # but I observe the option taken from cache, enabled.
>     >
>     > Is there some way to achieve my desired behaviour? I tried without success
>     > unset(MYOPT), unset(MYOPT CACHE), and set(MYOPT OFF) before option(), but
>     > they all lead to different behaviour.
>     >
>
>
> You're forgetting one important aspect of CMake: that it can retrigger itself when a CMake source file changes. Such a run of CMake is indistinguishable from
> running it manually, and it's (a large part of) why the cache exists in the first place. Imagine the following scenario:
>
> User runs >cmake -DMYOPT=ON
> User edits a CMakeLists.txt (or even just a file processed by configure_file()).
> User runs >make
>
> As part of this make, CMake triggers to regenerate the buildsystem. If MYOPT exhibited the behaviour you request, it would silently get disabled again, even
> though this is most definitely not what the user expects. I addressed a similar point in this StackOverflow answer: https://stackoverflow.com/a/41361741/1782465
>
> Petr
>  
>
>
>     I've always used 'cmake -UMYOPT'  to remove specific items from the
>     cache (or edit the cache file directly).
>     I don't think the notion of user-provided or cache-provided entries
>     exist because all user defined variables go into the cache.
>     Then you can test to see if MYOPT is set and then use the default
>     value when recreating the cache entry.
>     Also cmake cache variables are persistent between invocations so the
>     user doesn't need to keep specifying them at the command line every
>     time cmake needs to run.
>
>     Best regards...
Both of you make perfectly valid remarks, thanks for the explanation!
And I understand now that this is currently build deeply into cmake,
and I do not think my request is important enough to change it!

Still, if this would be re-evaluated at some point, then my personal
vote would be to change this behaviour. My user story is a variable that
can enable and disable packaging with cpack. I configure cmake for build,
run the build, run tests, and only then I configure for packaging. When
some time later the next build runs, it will actually execute packaging,
not building!

This was *not* requested, but happens due to caching. Since I re-run
configuration, it was not intuitive to me that it would not use *only*
the options I give, but additionally the ones I omitted but gave before.

I do not think that other configuration systems do this. In my example
from yesterday, I expect a configuration system to give the same result
when I invoke (1) or (3), since they are the same call:
  #> cmake              # I want the option disabled, this works fine.
  #> cmake -DMYOPT=ON   # I want the option enabled, this works fine.
  #> cmake              # I want the option disabled (back to default).


All the best,

    Mario Emmenlauer
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake