CMake не имеет внутренних механизмов для создания переменной только для чтения. Более того, даже автоматические c переменные CMake, такие как CMAKE_SOURCE_DIR
, могут быть изменены.
Но CMake предоставляет механизм для watch переменной - variable_watch . Используя этот механизм, можно эмулировать свойство переменной только для чтения.
Код ниже предоставляет макрос set_readonly
для объявления переменных только для чтения:
# Analogue for 'set' command which defines readonly variable.
#
# Usage:
# set_readonly(FOO value)
macro(set_readonly VAR)
# Set the variable itself
set("${VAR}" "${ARGN}")
# Store the variable's value for restore it upon modifications.
set("_${VAR}_readonly_val" "${ARGN}")
# Register a watcher for a variable
variable_watch("${VAR}" readonly_guard)
endmacro()
# Watcher for a variable which emulates readonly property.
macro(readonly_guard VAR access value current_list_file stack)
if ("${access}" STREQUAL "MODIFIED_ACCESS")
message(WARNING "Attempt to change readonly variable '${VAR}'!")
# Restore a value of the variable to the initial one.
set(${VAR} "${_${VAR}_readonly_val}")
endif()
endmacro()
Пример использования:
# Define readonly variable 'FOO'
set_readonly(FOO "123" "456")
message(STATUS "FOO initial value: ${FOO}")
# Attempt to change the variable's value.
# This will trigger a warning.
set(FOO "456")
message(STATUS "FOO new value: ${FOO}")
В этом примере будет получен следующий вывод:
-- FOO initial value: 123;456
CMake Warning at CMakeLists.txt:6 (message):
Attempt to change readonly variable 'FOO'!
Call Stack (most recent call first):
CMakeLists.txt:9999 (readonly_guard)
CMakeLists.txt:26 (set)
-- FOO new value: 123;456
(Хотя CMakeLists.txt:26
является действительной строкой с командой set(FOO ...)
, CMakeLists.txt:9999
является строкой "magi c" ).