Re: [CMake] option bug ?

2010-07-27 Thread Michael Hertling
On 07/26/2010 10:29 PM, Alexander Neundorf wrote:
 On Monday 12 July 2010, Michael Hertling wrote:
 On 07/07/2010 09:44 AM, Michael Wild wrote:
 On 7. Jul, 2010, at 9:32 , Michael Hertling wrote:
 On 07/03/2010 01:03 AM, Chris Hillery wrote:
 There's a slightly nicer work-around: Change project A's CMakeLists to
 set PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO
 CACHE BOOLEAN doc). I've tested it locally and it works the way you
 want it to.

 It seems that CMake divides the world of variables into two classes:
 cache variables and non-cache variables. Somewhat unfortunately, the
 same function, SET(), is used to specify values for both kinds, and
 cache variables hide any non-cache variables with the same name. The
 upshot is that the same SET() command will do different things
 depending on what's currently in the cache.

 Further confusion here comes from the fact that when a variable is
 declared as a cache variable (using either option() or set(...CACHE...)
 ), any current value that the non-cache variable with the same name has
 is discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't
 a cache variable until it gets to processing projb's CMakeLists.txt,
 hence the non-cache value you provided gets dropped. The second time,
 it's already a cache variable, so project A's CMakeLists actually sets
 the cache variable, and therefore projb's CMakeLists sees it as you
 expect.

 It's definitely confusing, but I'm not totally sure what the right
 solution is. It probably would have been cleaner if CMake made the
 distinction clear between cache and non-cache variables, but it's far
 too late to change that now. Maybe it would be possible to change it
 such that a cache variable declaration (option() or set(...CACHE...) )
 would allow a current non-cache variable of the same name to override
 the declaration's default value, in the same way that -D on the
 command-line does.

 IMO, things aren't sooo bad. ;-)

 W.r.t. the value of a variable, CMake knows scopes and the cache. A new
 scope is entered by ADD_SUBDIRECTORY() or a function's invocation. When
 referring to a variable's value by the ${} operator you get the value
 from the current scope. At the start of a CMake run, the variables are
 initialized with the values from the cache, provided the latter exists
 and is appropriately populated. The SET() command - that is the actual
 source of confusion along with OPTION() - basically has four flavours:

 (1) SET(VAR xyz) sets the value of VAR in the current scope to xyz,
i.e. ${VAR} yields xyz until the value of VAR is changed anew.
 (2) SET(VAR xyz PARENT_SCOPE) sets the value of VAR in the parent's
scope to xyz, but doesn't affect the current scope or the cache.
 (3) SET(VAR xyz CACHE STRING ... FORCE) sets VAR's value in the
current scope and in the cache to xyz regardless if there's
already a cached value or VAR is defined in the current scope.
 (4) SET(VAR xyz CACHE STRING ...) sets VAR's value in the cache
to xyz unless there's already a cached value for VAR, and the
latter's value in the current scope is set from the cache if
(a) the SET() writes to the cache, or
(b) VAR is undefined in the current scope, or
(c) the type of VAR in the cache is UNINITIALIZED.

 While (4a,b) are quite reasonable, (4c) is somewhat strange as it
 yields different results for apparently equivalent invocations:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(VARS NONE)
 MESSAGE(VAR{1,2}[CACHE]: ${VAR1},${VAR2})
 SET(VAR1 abc)
 SET(VAR2 abc)
 MESSAGE(VAR{1,2}[LOCAL]: ${VAR1},${VAR2})
 UNSET(VAR2)
 SET(VAR1 xyz CACHE STRING )
 SET(VAR2 xyz CACHE STRING )
 MESSAGE(VAR{1,2}[FINAL]: ${VAR1},${VAR2})

 Cmaking from a clean build directory yields, as expected, (4a):

 VAR{1,2}[CACHE]: ,
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: xyz,xyz

 Afterwards, cmake -DVAR1:STRING=pqr -DVAR2:STRING=pqr . yields:

 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: abc,pqr

 So, VAR1 is finally not set from the cache, but VAR2 is as it's
 undefined in the current scope at that moment; this proves (4b).

 Now, cmake -DVAR1=pqr -DVAR2=pqr . reveals (4c):

 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: pqr,pqr

 The parameter -DVAR1=pqr, i.e. without a type, supplies the cache
 with VAR1:UNINITIALIZED=pqr for VAR1, and the subsequent command
 SET(VAR1 xyz CACHE STRING ) changes VAR1's type to STRING, but
 does not touch the cached value; though, the latter is written to
 VAR1 in the current scope. Here, I'm in doubt if this behaviour is
 really intended.

 To summarize: If none of (4a-c) holds, i.e. an already cached value
 for VAR with a type other than UNINITIALIZED and VAR defined in the
 current scope, SET(VAR xyz CACHE STRING ...) just does nothing.

 It's that (4a-c) which causes the confusion in regard to a variable's
 value in the cache and the current scope, and as OPTION(VAR ... ON)
 is, AFAIK, quite the same 

Re: [CMake] option bug ?

2010-07-26 Thread Alexander Neundorf
On Monday 12 July 2010, Michael Hertling wrote:
 On 07/07/2010 09:44 AM, Michael Wild wrote:
  On 7. Jul, 2010, at 9:32 , Michael Hertling wrote:
  On 07/03/2010 01:03 AM, Chris Hillery wrote:
  There's a slightly nicer work-around: Change project A's CMakeLists to
  set PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO
  CACHE BOOLEAN doc). I've tested it locally and it works the way you
  want it to.
 
  It seems that CMake divides the world of variables into two classes:
  cache variables and non-cache variables. Somewhat unfortunately, the
  same function, SET(), is used to specify values for both kinds, and
  cache variables hide any non-cache variables with the same name. The
  upshot is that the same SET() command will do different things
  depending on what's currently in the cache.
 
  Further confusion here comes from the fact that when a variable is
  declared as a cache variable (using either option() or set(...CACHE...)
  ), any current value that the non-cache variable with the same name has
  is discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't
  a cache variable until it gets to processing projb's CMakeLists.txt,
  hence the non-cache value you provided gets dropped. The second time,
  it's already a cache variable, so project A's CMakeLists actually sets
  the cache variable, and therefore projb's CMakeLists sees it as you
  expect.
 
  It's definitely confusing, but I'm not totally sure what the right
  solution is. It probably would have been cleaner if CMake made the
  distinction clear between cache and non-cache variables, but it's far
  too late to change that now. Maybe it would be possible to change it
  such that a cache variable declaration (option() or set(...CACHE...) )
  would allow a current non-cache variable of the same name to override
  the declaration's default value, in the same way that -D on the
  command-line does.
 
  IMO, things aren't sooo bad. ;-)
 
  W.r.t. the value of a variable, CMake knows scopes and the cache. A new
  scope is entered by ADD_SUBDIRECTORY() or a function's invocation. When
  referring to a variable's value by the ${} operator you get the value
  from the current scope. At the start of a CMake run, the variables are
  initialized with the values from the cache, provided the latter exists
  and is appropriately populated. The SET() command - that is the actual
  source of confusion along with OPTION() - basically has four flavours:
 
  (1) SET(VAR xyz) sets the value of VAR in the current scope to xyz,
 i.e. ${VAR} yields xyz until the value of VAR is changed anew.
  (2) SET(VAR xyz PARENT_SCOPE) sets the value of VAR in the parent's
 scope to xyz, but doesn't affect the current scope or the cache.
  (3) SET(VAR xyz CACHE STRING ... FORCE) sets VAR's value in the
 current scope and in the cache to xyz regardless if there's
 already a cached value or VAR is defined in the current scope.
  (4) SET(VAR xyz CACHE STRING ...) sets VAR's value in the cache
 to xyz unless there's already a cached value for VAR, and the
 latter's value in the current scope is set from the cache if
 (a) the SET() writes to the cache, or
 (b) VAR is undefined in the current scope, or
 (c) the type of VAR in the cache is UNINITIALIZED.
 
  While (4a,b) are quite reasonable, (4c) is somewhat strange as it
  yields different results for apparently equivalent invocations:
 
  CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
  PROJECT(VARS NONE)
  MESSAGE(VAR{1,2}[CACHE]: ${VAR1},${VAR2})
  SET(VAR1 abc)
  SET(VAR2 abc)
  MESSAGE(VAR{1,2}[LOCAL]: ${VAR1},${VAR2})
  UNSET(VAR2)
  SET(VAR1 xyz CACHE STRING )
  SET(VAR2 xyz CACHE STRING )
  MESSAGE(VAR{1,2}[FINAL]: ${VAR1},${VAR2})
 
  Cmaking from a clean build directory yields, as expected, (4a):
 
  VAR{1,2}[CACHE]: ,
  VAR{1,2}[LOCAL]: abc,abc
  VAR{1,2}[FINAL]: xyz,xyz
 
  Afterwards, cmake -DVAR1:STRING=pqr -DVAR2:STRING=pqr . yields:
 
  VAR{1,2}[CACHE]: pqr,pqr
  VAR{1,2}[LOCAL]: abc,abc
  VAR{1,2}[FINAL]: abc,pqr
 
  So, VAR1 is finally not set from the cache, but VAR2 is as it's
  undefined in the current scope at that moment; this proves (4b).
 
  Now, cmake -DVAR1=pqr -DVAR2=pqr . reveals (4c):
 
  VAR{1,2}[CACHE]: pqr,pqr
  VAR{1,2}[LOCAL]: abc,abc
  VAR{1,2}[FINAL]: pqr,pqr
 
  The parameter -DVAR1=pqr, i.e. without a type, supplies the cache
  with VAR1:UNINITIALIZED=pqr for VAR1, and the subsequent command
  SET(VAR1 xyz CACHE STRING ) changes VAR1's type to STRING, but
  does not touch the cached value; though, the latter is written to
  VAR1 in the current scope. Here, I'm in doubt if this behaviour is
  really intended.
 
  To summarize: If none of (4a-c) holds, i.e. an already cached value
  for VAR with a type other than UNINITIALIZED and VAR defined in the
  current scope, SET(VAR xyz CACHE STRING ...) just does nothing.
 
  It's that (4a-c) which causes the confusion in regard to a variable's
  value in the cache and the current 

Re: [CMake] option bug ?

2010-07-12 Thread Michael Hertling
On 07/07/2010 09:44 AM, Michael Wild wrote:
 
 On 7. Jul, 2010, at 9:32 , Michael Hertling wrote:
 
 On 07/03/2010 01:03 AM, Chris Hillery wrote:
 There's a slightly nicer work-around: Change project A's CMakeLists to set
 PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO CACHE
 BOOLEAN doc). I've tested it locally and it works the way you want it to.

 It seems that CMake divides the world of variables into two classes: cache
 variables and non-cache variables. Somewhat unfortunately, the same
 function, SET(), is used to specify values for both kinds, and cache
 variables hide any non-cache variables with the same name. The upshot is
 that the same SET() command will do different things depending on what's
 currently in the cache.

 Further confusion here comes from the fact that when a variable is declared
 as a cache variable (using either option() or set(...CACHE...) ), any
 current value that the non-cache variable with the same name has is
 discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't a cache
 variable until it gets to processing projb's CMakeLists.txt, hence the
 non-cache value you provided gets dropped. The second time, it's already a
 cache variable, so project A's CMakeLists actually sets the cache variable,
 and therefore projb's CMakeLists sees it as you expect.

 It's definitely confusing, but I'm not totally sure what the right solution
 is. It probably would have been cleaner if CMake made the distinction clear
 between cache and non-cache variables, but it's far too late to change that
 now. Maybe it would be possible to change it such that a cache variable
 declaration (option() or set(...CACHE...) ) would allow a current non-cache
 variable of the same name to override the declaration's default value, in
 the same way that -D on the command-line does.

 IMO, things aren't sooo bad. ;-)

 W.r.t. the value of a variable, CMake knows scopes and the cache. A new
 scope is entered by ADD_SUBDIRECTORY() or a function's invocation. When
 referring to a variable's value by the ${} operator you get the value
 from the current scope. At the start of a CMake run, the variables are
 initialized with the values from the cache, provided the latter exists
 and is appropriately populated. The SET() command - that is the actual
 source of confusion along with OPTION() - basically has four flavours:

 (1) SET(VAR xyz) sets the value of VAR in the current scope to xyz,
i.e. ${VAR} yields xyz until the value of VAR is changed anew.
 (2) SET(VAR xyz PARENT_SCOPE) sets the value of VAR in the parent's
scope to xyz, but doesn't affect the current scope or the cache.
 (3) SET(VAR xyz CACHE STRING ... FORCE) sets VAR's value in the
current scope and in the cache to xyz regardless if there's
already a cached value or VAR is defined in the current scope.
 (4) SET(VAR xyz CACHE STRING ...) sets VAR's value in the cache
to xyz unless there's already a cached value for VAR, and the
latter's value in the current scope is set from the cache if
(a) the SET() writes to the cache, or
(b) VAR is undefined in the current scope, or
(c) the type of VAR in the cache is UNINITIALIZED.

 While (4a,b) are quite reasonable, (4c) is somewhat strange as it
 yields different results for apparently equivalent invocations:

 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(VARS NONE)
 MESSAGE(VAR{1,2}[CACHE]: ${VAR1},${VAR2})
 SET(VAR1 abc)
 SET(VAR2 abc)
 MESSAGE(VAR{1,2}[LOCAL]: ${VAR1},${VAR2})
 UNSET(VAR2)
 SET(VAR1 xyz CACHE STRING )
 SET(VAR2 xyz CACHE STRING )
 MESSAGE(VAR{1,2}[FINAL]: ${VAR1},${VAR2})

 Cmaking from a clean build directory yields, as expected, (4a):

 VAR{1,2}[CACHE]: ,
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: xyz,xyz

 Afterwards, cmake -DVAR1:STRING=pqr -DVAR2:STRING=pqr . yields:

 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: abc,pqr

 So, VAR1 is finally not set from the cache, but VAR2 is as it's
 undefined in the current scope at that moment; this proves (4b).

 Now, cmake -DVAR1=pqr -DVAR2=pqr . reveals (4c):

 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: pqr,pqr

 The parameter -DVAR1=pqr, i.e. without a type, supplies the cache
 with VAR1:UNINITIALIZED=pqr for VAR1, and the subsequent command
 SET(VAR1 xyz CACHE STRING ) changes VAR1's type to STRING, but
 does not touch the cached value; though, the latter is written to
 VAR1 in the current scope. Here, I'm in doubt if this behaviour is
 really intended.

 To summarize: If none of (4a-c) holds, i.e. an already cached value
 for VAR with a type other than UNINITIALIZED and VAR defined in the
 current scope, SET(VAR xyz CACHE STRING ...) just does nothing.

 It's that (4a-c) which causes the confusion in regard to a variable's
 value in the cache and the current scope, and as OPTION(VAR ... ON)
 is, AFAIK, quite the same as SET(VAR ON CACHE BOOL ...), the above-
 mentioned considerations apply accordingly. So, the 

Re: [CMake] option bug ?

2010-07-07 Thread Michael Hertling
On 07/03/2010 01:03 AM, Chris Hillery wrote:
 There's a slightly nicer work-around: Change project A's CMakeLists to set
 PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO CACHE
 BOOLEAN doc). I've tested it locally and it works the way you want it to.
 
 It seems that CMake divides the world of variables into two classes: cache
 variables and non-cache variables. Somewhat unfortunately, the same
 function, SET(), is used to specify values for both kinds, and cache
 variables hide any non-cache variables with the same name. The upshot is
 that the same SET() command will do different things depending on what's
 currently in the cache.
 
 Further confusion here comes from the fact that when a variable is declared
 as a cache variable (using either option() or set(...CACHE...) ), any
 current value that the non-cache variable with the same name has is
 discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't a cache
 variable until it gets to processing projb's CMakeLists.txt, hence the
 non-cache value you provided gets dropped. The second time, it's already a
 cache variable, so project A's CMakeLists actually sets the cache variable,
 and therefore projb's CMakeLists sees it as you expect.
 
 It's definitely confusing, but I'm not totally sure what the right solution
 is. It probably would have been cleaner if CMake made the distinction clear
 between cache and non-cache variables, but it's far too late to change that
 now. Maybe it would be possible to change it such that a cache variable
 declaration (option() or set(...CACHE...) ) would allow a current non-cache
 variable of the same name to override the declaration's default value, in
 the same way that -D on the command-line does.

IMO, things aren't sooo bad. ;-)

W.r.t. the value of a variable, CMake knows scopes and the cache. A new
scope is entered by ADD_SUBDIRECTORY() or a function's invocation. When
referring to a variable's value by the ${} operator you get the value
from the current scope. At the start of a CMake run, the variables are
initialized with the values from the cache, provided the latter exists
and is appropriately populated. The SET() command - that is the actual
source of confusion along with OPTION() - basically has four flavours:

(1) SET(VAR xyz) sets the value of VAR in the current scope to xyz,
i.e. ${VAR} yields xyz until the value of VAR is changed anew.
(2) SET(VAR xyz PARENT_SCOPE) sets the value of VAR in the parent's
scope to xyz, but doesn't affect the current scope or the cache.
(3) SET(VAR xyz CACHE STRING ... FORCE) sets VAR's value in the
current scope and in the cache to xyz regardless if there's
already a cached value or VAR is defined in the current scope.
(4) SET(VAR xyz CACHE STRING ...) sets VAR's value in the cache
to xyz unless there's already a cached value for VAR, and the
latter's value in the current scope is set from the cache if
(a) the SET() writes to the cache, or
(b) VAR is undefined in the current scope, or
(c) the type of VAR in the cache is UNINITIALIZED.

While (4a,b) are quite reasonable, (4c) is somewhat strange as it
yields different results for apparently equivalent invocations:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(VARS NONE)
MESSAGE(VAR{1,2}[CACHE]: ${VAR1},${VAR2})
SET(VAR1 abc)
SET(VAR2 abc)
MESSAGE(VAR{1,2}[LOCAL]: ${VAR1},${VAR2})
UNSET(VAR2)
SET(VAR1 xyz CACHE STRING )
SET(VAR2 xyz CACHE STRING )
MESSAGE(VAR{1,2}[FINAL]: ${VAR1},${VAR2})

Cmaking from a clean build directory yields, as expected, (4a):

VAR{1,2}[CACHE]: ,
VAR{1,2}[LOCAL]: abc,abc
VAR{1,2}[FINAL]: xyz,xyz

Afterwards, cmake -DVAR1:STRING=pqr -DVAR2:STRING=pqr . yields:

VAR{1,2}[CACHE]: pqr,pqr
VAR{1,2}[LOCAL]: abc,abc
VAR{1,2}[FINAL]: abc,pqr

So, VAR1 is finally not set from the cache, but VAR2 is as it's
undefined in the current scope at that moment; this proves (4b).

Now, cmake -DVAR1=pqr -DVAR2=pqr . reveals (4c):

VAR{1,2}[CACHE]: pqr,pqr
VAR{1,2}[LOCAL]: abc,abc
VAR{1,2}[FINAL]: pqr,pqr

The parameter -DVAR1=pqr, i.e. without a type, supplies the cache
with VAR1:UNINITIALIZED=pqr for VAR1, and the subsequent command
SET(VAR1 xyz CACHE STRING ) changes VAR1's type to STRING, but
does not touch the cached value; though, the latter is written to
VAR1 in the current scope. Here, I'm in doubt if this behaviour is
really intended.

To summarize: If none of (4a-c) holds, i.e. an already cached value
for VAR with a type other than UNINITIALIZED and VAR defined in the
current scope, SET(VAR xyz CACHE STRING ...) just does nothing.

It's that (4a-c) which causes the confusion in regard to a variable's
value in the cache and the current scope, and as OPTION(VAR ... ON)
is, AFAIK, quite the same as SET(VAR ON CACHE BOOL ...), the above-
mentioned considerations apply accordingly. So, the rule of thumb is
to differentiate cleanly between variables to be used with the cache
and variables to be used as usual, or in other words: If one wants 

Re: [CMake] option bug ?

2010-07-07 Thread Chris Hillery
On Wed, Jul 7, 2010 at 12:32 AM, Michael Hertling mhertl...@online.dewrote:

 IMO, things aren't sooo bad. ;-)

 [100 lines of explanation of how SET() behaves in 6 different ways elided]


I think you've just proven my point. Thanks! :)

Ceej
aka Chris Hillery
___
Powered by www.kitware.com

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

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

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

Re: [CMake] option bug ?

2010-07-07 Thread Michael Wild

On 7. Jul, 2010, at 9:32 , Michael Hertling wrote:

 On 07/03/2010 01:03 AM, Chris Hillery wrote:
 There's a slightly nicer work-around: Change project A's CMakeLists to set
 PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO CACHE
 BOOLEAN doc). I've tested it locally and it works the way you want it to.
 
 It seems that CMake divides the world of variables into two classes: cache
 variables and non-cache variables. Somewhat unfortunately, the same
 function, SET(), is used to specify values for both kinds, and cache
 variables hide any non-cache variables with the same name. The upshot is
 that the same SET() command will do different things depending on what's
 currently in the cache.
 
 Further confusion here comes from the fact that when a variable is declared
 as a cache variable (using either option() or set(...CACHE...) ), any
 current value that the non-cache variable with the same name has is
 discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't a cache
 variable until it gets to processing projb's CMakeLists.txt, hence the
 non-cache value you provided gets dropped. The second time, it's already a
 cache variable, so project A's CMakeLists actually sets the cache variable,
 and therefore projb's CMakeLists sees it as you expect.
 
 It's definitely confusing, but I'm not totally sure what the right solution
 is. It probably would have been cleaner if CMake made the distinction clear
 between cache and non-cache variables, but it's far too late to change that
 now. Maybe it would be possible to change it such that a cache variable
 declaration (option() or set(...CACHE...) ) would allow a current non-cache
 variable of the same name to override the declaration's default value, in
 the same way that -D on the command-line does.
 
 IMO, things aren't sooo bad. ;-)
 
 W.r.t. the value of a variable, CMake knows scopes and the cache. A new
 scope is entered by ADD_SUBDIRECTORY() or a function's invocation. When
 referring to a variable's value by the ${} operator you get the value
 from the current scope. At the start of a CMake run, the variables are
 initialized with the values from the cache, provided the latter exists
 and is appropriately populated. The SET() command - that is the actual
 source of confusion along with OPTION() - basically has four flavours:
 
 (1) SET(VAR xyz) sets the value of VAR in the current scope to xyz,
i.e. ${VAR} yields xyz until the value of VAR is changed anew.
 (2) SET(VAR xyz PARENT_SCOPE) sets the value of VAR in the parent's
scope to xyz, but doesn't affect the current scope or the cache.
 (3) SET(VAR xyz CACHE STRING ... FORCE) sets VAR's value in the
current scope and in the cache to xyz regardless if there's
already a cached value or VAR is defined in the current scope.
 (4) SET(VAR xyz CACHE STRING ...) sets VAR's value in the cache
to xyz unless there's already a cached value for VAR, and the
latter's value in the current scope is set from the cache if
(a) the SET() writes to the cache, or
(b) VAR is undefined in the current scope, or
(c) the type of VAR in the cache is UNINITIALIZED.
 
 While (4a,b) are quite reasonable, (4c) is somewhat strange as it
 yields different results for apparently equivalent invocations:
 
 CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
 PROJECT(VARS NONE)
 MESSAGE(VAR{1,2}[CACHE]: ${VAR1},${VAR2})
 SET(VAR1 abc)
 SET(VAR2 abc)
 MESSAGE(VAR{1,2}[LOCAL]: ${VAR1},${VAR2})
 UNSET(VAR2)
 SET(VAR1 xyz CACHE STRING )
 SET(VAR2 xyz CACHE STRING )
 MESSAGE(VAR{1,2}[FINAL]: ${VAR1},${VAR2})
 
 Cmaking from a clean build directory yields, as expected, (4a):
 
 VAR{1,2}[CACHE]: ,
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: xyz,xyz
 
 Afterwards, cmake -DVAR1:STRING=pqr -DVAR2:STRING=pqr . yields:
 
 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: abc,pqr
 
 So, VAR1 is finally not set from the cache, but VAR2 is as it's
 undefined in the current scope at that moment; this proves (4b).
 
 Now, cmake -DVAR1=pqr -DVAR2=pqr . reveals (4c):
 
 VAR{1,2}[CACHE]: pqr,pqr
 VAR{1,2}[LOCAL]: abc,abc
 VAR{1,2}[FINAL]: pqr,pqr
 
 The parameter -DVAR1=pqr, i.e. without a type, supplies the cache
 with VAR1:UNINITIALIZED=pqr for VAR1, and the subsequent command
 SET(VAR1 xyz CACHE STRING ) changes VAR1's type to STRING, but
 does not touch the cached value; though, the latter is written to
 VAR1 in the current scope. Here, I'm in doubt if this behaviour is
 really intended.
 
 To summarize: If none of (4a-c) holds, i.e. an already cached value
 for VAR with a type other than UNINITIALIZED and VAR defined in the
 current scope, SET(VAR xyz CACHE STRING ...) just does nothing.
 
 It's that (4a-c) which causes the confusion in regard to a variable's
 value in the cache and the current scope, and as OPTION(VAR ... ON)
 is, AFAIK, quite the same as SET(VAR ON CACHE BOOL ...), the above-
 mentioned considerations apply accordingly. So, the rule of thumb is
 to 

Re: [CMake] option bug ?

2010-07-07 Thread Michael Hertling
On 07/07/2010 09:40 AM, Chris Hillery wrote:
 On Wed, Jul 7, 2010 at 12:32 AM, Michael Hertling mhertl...@online.dewrote:
 
 IMO, things aren't sooo bad. ;-)

 [100 lines of explanation of how SET() behaves in 6 different ways elided]

 
 I think you've just proven my point. Thanks! :)

Actually, I intended to disprove your point to a certain extend. ;)

SET() works as expected except for SET(VAR ... CACHE TYPE ...) and
the related OPTION() in some cases. If VAR does not have an entry in the
cache or in the current scope SET() behaves reasonable: Afterwards, both
entries exist and are equal. If VAR already has both entries SET() does
not trade off the cache for the current scope which could be considered
as reasonable, too. Nevertheless, the UNINITIALIZED thing is pretty
weird, indeed.

Regards,

Michael
___
Powered by www.kitware.com

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

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

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


Re: [CMake] option bug ?

2010-07-04 Thread Gaspard Bucher
Hi Chris,

Thanks for the detailed information. SET( CACHE ...) is effectively a
good workaround.

Gaspard

On Sat, Jul 3, 2010 at 1:03 AM, Chris Hillery chillery-cm...@lambda.nuwrote:

 There's a slightly nicer work-around: Change project A's CMakeLists to set
 PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO CACHE
 BOOLEAN doc). I've tested it locally and it works the way you want it to.

 It seems that CMake divides the world of variables into two classes: cache
 variables and non-cache variables. Somewhat unfortunately, the same
 function, SET(), is used to specify values for both kinds, and cache
 variables hide any non-cache variables with the same name. The upshot is
 that the same SET() command will do different things depending on what's
 currently in the cache.

 Further confusion here comes from the fact that when a variable is declared
 as a cache variable (using either option() or set(...CACHE...) ), any
 current value that the non-cache variable with the same name has is
 discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't a cache
 variable until it gets to processing projb's CMakeLists.txt, hence the
 non-cache value you provided gets dropped. The second time, it's already a
 cache variable, so project A's CMakeLists actually sets the cache variable,
 and therefore projb's CMakeLists sees it as you expect.

 It's definitely confusing, but I'm not totally sure what the right solution
 is. It probably would have been cleaner if CMake made the distinction clear
 between cache and non-cache variables, but it's far too late to change that
 now. Maybe it would be possible to change it such that a cache variable
 declaration (option() or set(...CACHE...) ) would allow a current non-cache
 variable of the same name to override the declaration's default value, in
 the same way that -D on the command-line does.

 Ceej
 aka Chris Hillery

 On Fri, Jul 2, 2010 at 2:52 PM, Gaspard Bucher gasp...@teti.ch wrote:

 I have two projects: A and B. A depends on B but should set some settings
 for the proper compilation of B when included in A.

  CMakeLists.txt  (project A)

 set(PROJB_OPENCV_LINK NO)

 add_subdirectory(vendor/projb)

  vendor/projb/CMakeLists.txt === (project B)

 option (PROJB_OPENCV_LINK Set this to NO to link opencv alloc later.
 YES)

 

 The local value PROJB_OPENCV_LINK is overwritten by the option on the
 first run. If you run cmake a second time, the cached value is seen and
 takes over so the option does not overwrite.

 I do not see any reason why an option setting should overwrite a defined
 variable.

 build  cmake .. == fail

 build  cmake .. || cmake .. == works. This is absurd.

 Gaspard


 PS: I know there is a workaround by using IF(DEFINED...).

 ___
 Powered by www.kitware.com

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

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

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



___
Powered by www.kitware.com

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

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

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

Re: [CMake] option bug ?

2010-07-02 Thread Chris Hillery
There's a slightly nicer work-around: Change project A's CMakeLists to set
PROJB_OPENCV_LINK as a cache variable, ie, SET(PROJB_OPENCV_LINK NO CACHE
BOOLEAN doc). I've tested it locally and it works the way you want it to.

It seems that CMake divides the world of variables into two classes: cache
variables and non-cache variables. Somewhat unfortunately, the same
function, SET(), is used to specify values for both kinds, and cache
variables hide any non-cache variables with the same name. The upshot is
that the same SET() command will do different things depending on what's
currently in the cache.

Further confusion here comes from the fact that when a variable is declared
as a cache variable (using either option() or set(...CACHE...) ), any
current value that the non-cache variable with the same name has is
discarded. So the first time you run cmake, PROJB_OPENCV_LINK isn't a cache
variable until it gets to processing projb's CMakeLists.txt, hence the
non-cache value you provided gets dropped. The second time, it's already a
cache variable, so project A's CMakeLists actually sets the cache variable,
and therefore projb's CMakeLists sees it as you expect.

It's definitely confusing, but I'm not totally sure what the right solution
is. It probably would have been cleaner if CMake made the distinction clear
between cache and non-cache variables, but it's far too late to change that
now. Maybe it would be possible to change it such that a cache variable
declaration (option() or set(...CACHE...) ) would allow a current non-cache
variable of the same name to override the declaration's default value, in
the same way that -D on the command-line does.

Ceej
aka Chris Hillery

On Fri, Jul 2, 2010 at 2:52 PM, Gaspard Bucher gasp...@teti.ch wrote:

 I have two projects: A and B. A depends on B but should set some settings
 for the proper compilation of B when included in A.

  CMakeLists.txt  (project A)

 set(PROJB_OPENCV_LINK NO)

 add_subdirectory(vendor/projb)

  vendor/projb/CMakeLists.txt === (project B)

 option (PROJB_OPENCV_LINK Set this to NO to link opencv alloc later. YES)

 

 The local value PROJB_OPENCV_LINK is overwritten by the option on the
 first run. If you run cmake a second time, the cached value is seen and
 takes over so the option does not overwrite.

 I do not see any reason why an option setting should overwrite a defined
 variable.

 build  cmake .. == fail

 build  cmake .. || cmake .. == works. This is absurd.

 Gaspard


 PS: I know there is a workaround by using IF(DEFINED...).

 ___
 Powered by www.kitware.com

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

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

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

___
Powered by www.kitware.com

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

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

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