Skip to content

Policy CMP0077 docs misrepresent the OLD and NEW behavior

Demonstrator Project Example

cmake_minimum_required(VERSION 3.11)

if(POLICY CMP0077)
    cmake_policy(SET CMP0077 NEW)
endif()

get_property(cacheValue CACHE SOMEVAR PROPERTY VALUE)
get_property(cacheType  CACHE SOMEVAR PROPERTY TYPE)
message("Before: value = ${cacheValue}, type = ${cacheType}")

set(SOMEVAR NO)
message("Non-cache SOMEVAR set to: ${SOMEVAR}")

option(SOMEVAR "" OFF)

get_property(cacheValue CACHE SOMEVAR PROPERTY VALUE)
get_property(cacheType  CACHE SOMEVAR PROPERTY TYPE)
message("After:  value = ${cacheValue}, type = ${cacheType}")
message("Final var: ${SOMEVAR}")

project(Foo LANGUAGES NONE)

Results

Running cmake for the first time with three different command line options results in the following sets of output:

CASE 1: No SOMEVAR set on command line

cmake ...

Original output                           | Output with !2155 (policy NEW)
------------------------------------------|-------------------------------
Before: value = , type =                  | Before: value = , type = 
Non-cache SOMEVAR set to: NO              | Non-cache SOMEVAR set to: NO
After:  value = OFF, type = BOOL          | After:  value = , type =
Final var: OFF                            | Final var: NO

CASE 2: With SOMEVAR set on command line, but without type

cmake -DSOMEVAR=YES ...

Original output                           | Output with !2155 (policy NEW)
------------------------------------------|-------------------------------
Before: value = YES, type = UNINITIALIZED | Before: value = YES, type = UNINITIALIZED
Non-cache SOMEVAR set to: NO              | Non-cache SOMEVAR set to: NO
After:  value = YES, type = BOOL          | After:  value = YES, type = UNINITIALIZED
Final var: YES                            | Final var: NO

CASE 3: With SOMEVAR set on command line, including type

cmake -DSOMEVAR:BOOL=YES ...

Original output                           | Output with !2155 (policy NEW)
------------------------------------------|-------------------------------
Before: value = YES, type = BOOL          | Before: value = YES, type = BOOL
Non-cache SOMEVAR set to: NO              | Non-cache SOMEVAR set to: NO
After:  value = YES, type = BOOL          | After:  value = YES, type = BOOL
Final var: NO                             | Final var: NO

Observations

The docs for the CMP0077 policy introduced in !2155 (merged) state that:

The OLD behavior for this policy is to clear any existing normal variables with the same name.

This is not an accurate description of the OLD behavior. As demonstrated by the results of the different cases above, the OLD behavior is much more complex:

  • If a cache variable of the specified name exists and has been given a type, then the option() command changes nothing.
  • If a cache variable of the specified name exists but has NOT been given a type, the option() command will change the type to BOOL and will remove any non-cache variable of the same name. The cached value is not changed.
  • If a cache variable of the specified name does not exist at all, the option() command will add a new cache variable of type BOOL and will remove any non-cache variable of the same name.

Similarly, the NEW behavior is also not accurately documented:

The NEW behavior for this policy is to not create a cache entry or modify any existing normal variables if a normal variable with the same name already exists.

It should really say something more like:

The NEW behavior for this policy is to not create or modify a cache entry or modify any existing normal variables if a normal variable or a cache variable with the same name already exists.

The single line summary for CMP0077 is probably also an over-simplification:

option() honors normal variables

Perhaps it could be more accurately described as something like "option() does nothing if variable already defined"? This doesn't limit the statement to "normal variables", but instead allows for cache variables that might or might not have a type too.

Ultimately, the NEW behavior is indeed desirable and more intuitive, we should just make the docs align with the OLD and NEW behavior more accurately.

Edited by Craig Scott
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information