Re: [CMake] option bug ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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