[CMake] Study of Cache Interaction with If Statements
Hostile Fork
hostilefork at gmail.com
Fri Jun 12 13:31:08 EDT 2009
Hello cmakers,
I have been looking at some unusual ways in which values stored in the
cache interact with the 'if' statement. I'll start with a simple case
that matches typical programming intuition:
set (VAR1 ON)
set (VAR2 OFF)
if (VAR1)
set (VAR2 ON)
message ("VAR2 is ${VAR2}")
endif (VAR1)
This prints "VAR2 is ON". But if we use the cache variation for both
assignments:
set (VAR1 ON)
set (VAR2 OFF CACHE BOOL "Variable 2 Label A")
if (VAR1)
set (VAR2 ON CACHE BOOL "Variable 2 Label B")
message ("VAR2 is ${VAR2}")
endif (VAR1)
...then if doing a fresh make, this will print "VAR2 is OFF". Running
'cmake -DVAR2=ON' causes it to say "VAR2 is ON". Running 'cmake -i'
reveals the label for VAR2 as "Variable 2 Label A".
Looking at a third case:
set (VAR1 ON)
set (VAR2 OFF CACHE BOOL "Variable 2")
if (VAR1)
set (VAR2 ON)
message ("VAR2 is ${VAR2}")
endif (VAR1)
...for a fresh make will print "VAR2 is ON". Running 'cmake -
DVAR2=OFF' does not change this. And just to round out the example
set...
set (VAR1 OFF)
if (VAR1)
set (VAR2 ON CACHE BOOL "Variable 2")
endif (VAR1)
This will give an interactive prompt for "Variable 2" when using
("cmake -i"), even though the value is never needed.
I'll try and guess a few points:
(1) 'if' cannot control whether something is prompted for in the
interactive mode. one or more appearance of a 'CACHE' by an
associated 'set' will trigger a prompt for that variable
(2) it is possible to have multiple cached "set" statements for the
same variable... as well as to mix cached and non-cached variable
assignments. but each cached set will always use the cache value
(3) there is no apparent enforcement of consistency in the cache
defaults or labeling... and which default/label wins may not be a well-
defined behavior
I was disappointed about (1), because I have several options which are
only relevant if another option is set. There are also some options
which cannot be set together. So currently I have checks like this in
the header file:
#if USE_FOO
# if USE_BAR
# error Cannot have USE_BAR=1 when USE_FOO=1
# endif
#else
# if USE_FOO_OPTIMIZATION
# error cannot have USE_FOO_OPTIMIZATION=1 when USE_FOO=0
# endif
#endif
What makes (2) confusing is that when you use CACHE with 'set', it
ceases to have very much in common with set(VAR VAL). Correct me if
I'm wrong, but its semantics seem like "Get From Cache And Ignore Val
Unless Cache Is Empty And Then Maybe Use Val If There Are No Other Set
With Cache Statements Which Supply A Different Val...Otherwise Who
Knows" operator.
This might be helped by breaking 'set' into a few smaller commands,
such as those which define cache values and which fetch them. That
would also mean that CMake could keep people from thinking (1) is
possible by requiring statements which declare cache variables
(option, "definecache(?)") to appear at top scope.
Thoughts? I'm curious if there is any documentation which addresses
these kinds of issues.
Thanks!
---Brian
http://hostilefork.com
More information about the CMake
mailing list