[CMake] IMPORTANT!! SET CACHE FORCE not wortking with UNINITIALIZED variables

Bill Hoffman bill.hoffman at kitware.com
Tue Nov 11 10:12:30 EST 2008


Eric NOULARD wrote:
> Le Tue, 11 Nov 2008 11:47:20 -0200,
> Fernando Cacciola <fernando.cacciola at gmail.com> a écrit :
>> Hi,
>>
>> Since my last post about this got unnoticed I'm reposting it, this
>> time with additional information.
>>

Sorry, I did see your post, and I am busy...

So, you also mentioned this case:

SET( VAR "321" CACHE STRING "" FORCE )
set(VAR )
message(${VAR})   -> prints out 321

So, this was intentional.   set(var ) removes the value of var, and var 
becomes "unset".  This then re-exposes the cache variable VAR.

> 
> 
>> The culprint is in the following section of the cmake sources:
>>
>>
>> void cmMakefile::AddCacheDefinition(const char* name, const char*
>> value, const char* doc,
>>                                      cmCacheManager::CacheEntryType
>> type) {
>>    const char* val = value;
>>    cmCacheManager::CacheIterator it =
>>      this->GetCacheManager()->GetCacheIterator(name);
>>    if(!it.IsAtEnd() && (it.GetType() ==
>> cmCacheManager::UNINITIALIZED) &&
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>>       it.Initialized())
>>      {
>>
>>      val = it.GetValue();
>>      ^^^^^^^^^^^^^^^^^^^^
>>
>>
>> As you can see, when SET sees an UNINITIALIZED variable it just
>> ignores the value being passed on and just keeps the previous value.
> 
> After some CVS history browsing, the code is there at least since
> CMake 2.4.4 (may be older).
>  
>> IMO this is a bug, and I even wonder if that comparison didn't intend
>> to be != instead  ??
> 
> The bug, if ever this is one should be elsewhere.
> 
>> Fortunately, the variable is nevertheless overwritten into the cache, 
>> with the old (wrong) value but the correct type, hence, the following 
>> works around the bug:
>>
>>
>> SET( VAR "321" CACHE STRING "" FORCE )
>> SET( VAR "321" CACHE STRING "" FORCE )
>> MESSAGE( STATUS "VAR=${VAR}" )
>>
>> That is, the first SET "fixes" the type, allowing the second SET to
>> do what it should.
>>  
>> Shall I add this to the tracker or is this behaviour on purpose??
> 

So, I think this was intentional, sort of...


The issue is that we want the command line to be used.  So, if you have:

cmake -DFOO=456

Then, FOO should be set in the cache to the value 456 and something like 
this:
SET( VAR "123" CACHE STRING ""  )

Should not set VAR to 123, but it should set the type to STRING.  The 
bug seems to be that if you have:
SET( VAR "123" CACHE STRING "" FORCE)

It should do a FORCE and override the command line.

If you can provide a patch that does that, I will apply it, as FORCE 
should always force.  We just need to be careful that we don't break the 
non-force case that should only set the type.

-Bill


More information about the CMake mailing list