1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
#
# CMake Extensions
# ----------------
# macro set_ifnot(<var> <value>)
# If variable var is not set, set its value to that provided
#
# function enum_option(<option>
# VALUES <value1> ... <valueN>
# TYPE <valuetype>
# DOC <docstring>
# [DEFAULT <elem>]
# [CASE_INSENSITIVE])
# Declare a cache variable <option> that can only take values
# listed in VALUES. TYPE may be FILEPATH, PATH or STRING.
# <docstring> should describe that option, and will appear in
# the interactive CMake interfaces. If DEFAULT is provided,
# <elem> will be taken as the zero-indexed element in VALUES
# to which the value of <option> should default to if not
# provided. Otherwise, the default is taken as the first
# entry in VALUES. If CASE_INSENSITIVE is present, then
# checks of the value of <option> against the allowed values
# will ignore the case when performing string comparison.
#
#
# - Include guard
if(__macroutilities_isloaded)
return()
endif()
set(__macroutilities_isloaded YES)
#-----------------------------------------------------------------------
# CMAKE EXTENSIONS
#-----------------------------------------------------------------------
# macro set_ifnot(<var> <value>)
# If variable var is not set, set its value to that provided
#
macro(set_ifnot _var _value)
if(NOT ${_var})
set(${_var} ${_value})
endif()
endmacro()
#-----------------------------------------------------------------------
# function enum_option(<option>
# VALUES <value1> ... <valueN>
# TYPE <valuetype>
# DOC <docstring>
# [DEFAULT <elem>]
# [CASE_INSENSITIVE])
# Declare a cache variable <option> that can only take values
# listed in VALUES. TYPE may be FILEPATH, PATH or STRING.
# <docstring> should describe that option, and will appear in
# the interactive CMake interfaces. If DEFAULT is provided,
# <elem> will be taken as the zero-indexed element in VALUES
# to which the value of <option> should default to if not
# provided. Otherwise, the default is taken as the first
# entry in VALUES. If CASE_INSENSITIVE is present, then
# checks of the value of <option> against the allowed values
# will ignore the case when performing string comparison.
#
function(enum_option _var)
set(options CASE_INSENSITIVE)
set(oneValueArgs DOC TYPE DEFAULT)
set(multiValueArgs VALUES)
cmake_parse_arguments(_ENUMOP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# - Validation as needed arguments
if(NOT _ENUMOP_VALUES)
message(FATAL_ERROR "enum_option must be called with non-empty VALUES\n(Called for enum_option '${_var}')")
endif()
# - Set argument defaults as needed
if(_ENUMOP_CASE_INSENSITIVE)
set(_ci_values )
foreach(_elem ${_ENUMOP_VALUES})
string(TOLOWER "${_elem}" _ci_elem)
list(APPEND _ci_values "${_ci_elem}")
endforeach()
set(_ENUMOP_VALUES ${_ci_values})
endif()
set_ifnot(_ENUMOP_TYPE STRING)
set_ifnot(_ENUMOP_DEFAULT 0)
list(GET _ENUMOP_VALUES ${_ENUMOP_DEFAULT} _default)
if(NOT DEFINED ${_var})
set(${_var} ${_default} CACHE ${_ENUMOP_TYPE} "${_ENUMOP_DOC} (${_ENUMOP_VALUES})")
else()
set(_var_tmp ${${_var}})
if(_ENUMOP_CASE_INSENSITIVE)
string(TOLOWER ${_var_tmp} _var_tmp)
endif()
list(FIND _ENUMOP_VALUES ${_var_tmp} _elem)
if(_elem LESS 0)
message(FATAL_ERROR "Value '${${_var}}' for variable ${_var} is not allowed\nIt must be selected from the set: ${_ENUMOP_VALUES} (DEFAULT: ${_default})\n")
else()
# - convert to lowercase
if(_ENUMOP_CASE_INSENSITIVE)
set(${_var} ${_var_tmp} CACHE ${_ENUMOP_TYPE} "${_ENUMOP_DOC} (${_ENUMOP_VALUES})" FORCE)
endif()
endif()
endif()
endfunction()
|