Global maps
A global map models an association between a name and one or more [key, value] pairs. In the implementation, these pairs are saved by the calls to
set_property(GLOBAL PROPERTY ${prefix}${key} ${value})
A prefix usually identifies a program context, so that different global maps separate different contexts. A global map maintains an index of the keys it stores, which can be used to find out whether a property is in the map or not. A map can also be cleared with the help of its index. It’s possible to set, unset, or append to a property using syntax similar to that of usual variables:
# set(variable value)
global_set(context variable value)
# get_property(GLOBAL PROPERTY variable value)
global_set(context variable value)
# unset(variable)
global_unset(context variable)
# list(APPEND variable value)
global_append(context variable value)
The first argument is always a map name; it limits the scope of the operation to a certain context. It’s convenient to think of this argument as of a map name, although in implementation it’s just a prefix of the stored keys.
When to use
Sometimes, a CMake function or a module can have a complex state. In such cases, writing something like
get_property(value GLOBAL PROPERTY property)
set_property(GLOBAL PROPERTY property ${value} ${additional_value})
just to append a value to an existing property becomes a tedious, error-prone task.
Write functions
- global_set
global_set(map_name property value)
Stores the [property
, value
] pair in the global map map_name
.
The value can be retrieved later using
read functions.
Example:
function(setup_test value)
global_set(test conf_key ${value})
endfunction()
function(run_test)
global_get(test conf_key value)
message(STATUS "run the test with the conf_key = ${value}")
# run the test ...
endfunction()
setup_test(conf_value)
# ...
run_test()
- global_set_if_empty
global_set_if_empty(map_name property value)
If the global map map_name
does not contain the key property
,
stores the [property
, value
] pair in that map. Otherwise,
raises an error (SEND_ERROR) without updating the map.
Example:
foreach(key ${keys})
# require key uniqueness
global_set_if_empty(unique keys ${key})
endforeach()
- global_append
global_append(map_name property value)
If the property property
exists, it is treated as a list, and
the value of value
is appended to it. Otherwise, the property
property
is created and set to the given value.
Example:
# filter out the list into a new list for later use
function(filter_interface_targets)
foreach(_target ${_targets})
get_target_property(_type ${_target} TYPE)
if (_type STREQUAL INTERFACE_LIBRARY)
global_append(interface_targets ${_target})
endif()
endforeach()
endfunction()
add_library(target1 INTERFACE)
add_library(target2 INTERFACE)
add_library(target3 tests/test1.cpp)
filter_interface_targets(target1 target2 target3)
# ...
global_get(interface_targets targets)
# prints: target1;target2
print("INTERFACE targets: ${targets}")
- global_unset
global_unset(map_name property)
Removes the property property
from the global map map_name
.
Example:
global_set(test key1 value1)
global_set(test key2 value2)
global_set(test key3 value3)
# ...
global_unset(test)
global_get(test key1 value)
assert_empty("${value}")
global_get(test key2 value)
assert_not_empty("${value}")
- global_clear
global_clear(map_name)
Clears all the properties previously set in the global map map_name
by
the calls to global_set
and global_append
.
Example:
global_set(test key1 value1)
global_set(test key2 value2)
global_set(test key3 value3)
# ...
global_clear(test)
global_get(test key1 value)
assert_empty("${value}")
global_get(test key2 value)
assert_empty("${value}")
global_get(test key3 value)
assert_empty("${value}")
Read functions
- global_get
global_get(map_name property out_var)
Stores the value of the property property
into the output variable
designated by out_var
. If the requested property is not found,
sets out_var
to an empty string.
Example See the example for global_set.
- global_get_or_fail
global_get_or_fail(map_name property out_var)
Searches the property property
in the given global map map_name
.
If found, the output variable out_var
is updated to store
the property’s value. Otherwise, fatal error is raised.
Example
if(condition)
unset(var)
endif()
global_set(test property ${var})
# this will raise the fatal error - condition was not expected to work
global_get_or_fail(test property value)