[Cmake] Setting variables breaks the cache for SUBDIRS?

William A. Hoffman billlist at nycap.rr.com
Wed, 14 Apr 2004 13:14:22 -0400


Your original post was about include directories.   In that case, I would
say that the that include directory should be specified in the highest
level cmake list file where it is needed, that is what most of our projects
do.  

However, if your really want to have the sub dirs specify project inclues,
I don't think we need to add more complexity to the cache variables.   
Perhaps you could do what you want using more than one variable.

The behavior is due to the way cmake is parsed.   Each subdir reads the
parent cmakelist files and executes all inherited commands, so the SET
at the top gets done for subdir foo and bar, and the last one to execute
is the one that ends up in the cache.


Something like this might work for you:

SET(INCLUDES "${B_INCLUDES};${A_INCLUDES}" CACHE INTERNAL "")
INCLUDE_DIRECTORIES(${INCLUDES})
SUBDIRS(a b)

directory b:
SET(B_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "")

directory a:
SET(A_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE INTERNAL "")


However, it still does require that the top level cmake file know about
the subdir variable names.   I would still say that the top level
cmakelist file should specify relevant include directories.

-Bill
 
At 12:31 PM 4/14/2004, Zachary Pincus wrote:
>Bill,
>
>I explained more fully my intention with these cache variables in a separate email I sent to the CMake list immediately prior to the one under current discussion (Re: [Cmake] variables set in SUBDIRS() available to top-level CMakeList?). The thumbnail is thus: I wanted to have information gathered by CMakeLists caled via SUBDIRS() somehow percolate to the top-level CMakeList, and I tried to follow your suggestion of using cache variables, which turned out to be a bit problematic.
>
>Regardless, I brought up this matter separately because I thought that the behavior was sufficiently odd that it might warrant a general discussion of how CMake should operate.
>
>Specifically, the fact that "set" variables shadow the cache, and prevent cmake from looking for a variable value in the cache, leads to strange behavior when different CMakeLists called via SUBDIRS() attempt to read from and write to a particular cache variable. This behavior vis a vis cached variables seems imminently reasonable and works well most of the time, but can lead to the sort of seemingly counter-intuitive behaviors I demonstrated earlier.
>
>There seem to be three possible solutions: one is to say that different CMakeLists called via SUBDIRS() *must not* attempt lateral communication via cache variables. The second solution is to somehow automatically decide whether the cached variable is "fresher" than the variable that a CMakeList inherits from it's parent environment, and then to use the "fresher" value. The third solution is to have an explicit "refresh from cache" command so that the default shadowing behavior can be overridden.
>
>The first is easy, but perhaps limiting. The second is hard and will undoubtedly lead to other unexpected quirks. The third is perhaps workable, but bizarre.
>
>So I guess that just saying that different "sibling" CMakeLists should not try to get and set the same cache variable is reasonable -- if there is either (A) the clear understanding that these CMakeLists should never need to communicate or (B) a different or better method for such communication.
>
>Any thoughts?
>
>Thanks,
>Zach
>
>On Apr 14, 2004, at 5:33 AM, William A. Hoffman wrote:
>
>>Perhaps if you were to describe what you are trying to accomplish, there is
>>another solution.
>>
>>-Bill
>>
>>
>>At 12:06 AM 4/14/2004, Zachary Pincus wrote:
>>>Hello,
>>>
>>>I've run into a strange problem with the cache and SUBDIRS.
>>>
>>>Here's the setup: I have a variable that I want to add to from various different CMakeLists in subdirectories, called from a SUBDIRS() command.
>>>
>>>This works fine:
>>>
>>>--------------
>>>Top CMakeList
>>>--------------
>>>SUBDIRS(foo bar)
>>>
>>>--------------
>>>Foo CMakeList
>>>--------------
>>>SET(VAR "${VAR} foo" CACHE INTERNAL "add foo")
>>>
>>>--------------
>>>Bar CMakeList
>>>--------------
>>>SET(VAR "${VAR} bar" CACHE INTERNAL "add bar")
>>>
>>>
>>>Now, as you would expect, after this all runs, the cache contains VAR=" foo bar"
>>>
>>>However, if we change the top level CMakeList to look like this:
>>>--------------
>>>Top CMakeList
>>>--------------
>>>SET(VAR "top" CACHE INTERNAL "add top")
>>>SUBDIRS(foo bar)
>>>
>>>then instead of VAR="top foo bar" as you would expect, we just get "top bar"
>>>
>>>It looks to me like *if* there is no variable set in the top-level CMakeList, the CMakeLists called from the SUBDIRS command can load cached variables. However, if such a variable has already been set in the top-level CMakeList, this prevents the subdir-CMakeLists from actively reading from the cache each time. When "child" CMakeList sets the cached variable thinking it is appending to it, it actually overwrites the variable because the CMakeList never read in the latest version (cached by a "sibling" CMakeList) because the version of the variable inherited from the parent "shadows" this.
>>>
>>>SO: Is there a way to force a CMakeList to refresh the cache? Is this behavior a bug?
>>>
>>>Zach Pincus
>>>
>>>Department of Biochemistry and Program in Biomedical Informatics
>>>Stanford University School of Medicine
>>>
>>>_______________________________________________
>>>Cmake mailing list
>>>Cmake at www.cmake.org
>>>http://www.cmake.org/mailman/listinfo/cmake
>>
>>_______________________________________________
>>Cmake mailing list
>>Cmake at www.cmake.org
>>http://www.cmake.org/mailman/listinfo/cmake