1## Utility CMake functions. 2 3# ---------------------------------------------------------------------------- 4## Convert boolean value to 0 or 1 5macro (bool_to_int VAR) 6 if (${VAR}) 7 set (${VAR} 1) 8 else () 9 set (${VAR} 0) 10 endif () 11endmacro () 12 13# ---------------------------------------------------------------------------- 14## Extract version numbers from version string 15function (version_numbers version major minor patch) 16 if (version MATCHES "([0-9]+)(\\.[0-9]+)?(\\.[0-9]+)?(rc[1-9][0-9]*|[a-z]+)?") 17 if (CMAKE_MATCH_1) 18 set (_major ${CMAKE_MATCH_1}) 19 else () 20 set (_major 0) 21 endif () 22 if (CMAKE_MATCH_2) 23 set (_minor ${CMAKE_MATCH_2}) 24 string (REGEX REPLACE "^\\." "" _minor "${_minor}") 25 else () 26 set (_minor 0) 27 endif () 28 if (CMAKE_MATCH_3) 29 set (_patch ${CMAKE_MATCH_3}) 30 string (REGEX REPLACE "^\\." "" _patch "${_patch}") 31 else () 32 set (_patch 0) 33 endif () 34 else () 35 set (_major 0) 36 set (_minor 0) 37 set (_patch 0) 38 endif () 39 set ("${major}" "${_major}" PARENT_SCOPE) 40 set ("${minor}" "${_minor}" PARENT_SCOPE) 41 set ("${patch}" "${_patch}" PARENT_SCOPE) 42endfunction () 43 44# ---------------------------------------------------------------------------- 45## Determine if cache entry exists 46macro (gflags_is_cached retvar varname) 47 if (DEFINED ${varname}) 48 get_property (${retvar} CACHE ${varname} PROPERTY TYPE SET) 49 else () 50 set (${retvar} FALSE) 51 endif () 52endmacro () 53 54# ---------------------------------------------------------------------------- 55## Add gflags configuration variable 56# 57# The default value of the (cached) configuration value can be overridden either 58# on the CMake command-line or the super-project by setting the GFLAGS_<varname> 59# variable. When gflags is a subproject of another project (GFLAGS_IS_SUBPROJECT), 60# the variable is not added to the CMake cache. Otherwise it is cached. 61macro (gflags_define type varname docstring default) 62 # note that ARGC must be expanded here, as it is not a "real" variable 63 # (see the CMake documentation for the macro command) 64 if ("${ARGC}" GREATER 5) 65 message (FATAL_ERROR "gflags_variable: Too many macro arguments") 66 endif () 67 if (NOT DEFINED GFLAGS_${varname}) 68 if (GFLAGS_IS_SUBPROJECT AND "${ARGC}" EQUAL 5) 69 set (GFLAGS_${varname} "${ARGV4}") 70 else () 71 set (GFLAGS_${varname} "${default}") 72 endif () 73 endif () 74 if (GFLAGS_IS_SUBPROJECT) 75 if (NOT DEFINED ${varname}) 76 set (${varname} "${GFLAGS_${varname}}") 77 endif () 78 else () 79 set (${varname} "${GFLAGS_${varname}}" CACHE ${type} "${docstring}") 80 endif () 81endmacro () 82 83# ---------------------------------------------------------------------------- 84## Set property of cached gflags configuration variable 85macro (gflags_property varname property value) 86 gflags_is_cached (_cached ${varname}) 87 if (_cached) 88 # note that property must be expanded here, as it is not a "real" variable 89 # (see the CMake documentation for the macro command) 90 if ("${property}" STREQUAL "ADVANCED") 91 if (${value}) 92 mark_as_advanced (FORCE ${varname}) 93 else () 94 mark_as_advanced (CLEAR ${varname}) 95 endif () 96 else () 97 set_property (CACHE ${varname} PROPERTY "${property}" "${value}") 98 endif () 99 endif () 100 unset (_cached) 101endmacro () 102 103# ---------------------------------------------------------------------------- 104## Modify value of gflags configuration variable 105macro (gflags_set varname value) 106 gflags_is_cached (_cached ${varname}) 107 if (_cached) 108 set_property (CACHE ${varname} PROPERTY VALUE "${value}") 109 else () 110 set (${varname} "${value}") 111 endif () 112 unset (_cached) 113endmacro () 114 115# ---------------------------------------------------------------------------- 116## Configure public header files 117function (configure_headers out) 118 set (tmp) 119 foreach (src IN LISTS ARGN) 120 if (IS_ABSOLUTE "${src}") 121 list (APPEND tmp "${src}") 122 elseif (EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in") 123 configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY) 124 list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 125 else () 126 configure_file ("${PROJECT_SOURCE_DIR}/src/${src}" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" COPYONLY) 127 list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 128 endif () 129 endforeach () 130 set (${out} "${tmp}" PARENT_SCOPE) 131endfunction () 132 133# ---------------------------------------------------------------------------- 134## Configure source files with .in suffix 135function (configure_sources out) 136 set (tmp) 137 foreach (src IN LISTS ARGN) 138 if (src MATCHES ".h$" AND EXISTS "${PROJECT_SOURCE_DIR}/src/${src}.in") 139 configure_file ("${PROJECT_SOURCE_DIR}/src/${src}.in" "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}" @ONLY) 140 list (APPEND tmp "${PROJECT_BINARY_DIR}/include/${GFLAGS_INCLUDE_DIR}/${src}") 141 else () 142 list (APPEND tmp "${PROJECT_SOURCE_DIR}/src/${src}") 143 endif () 144 endforeach () 145 set (${out} "${tmp}" PARENT_SCOPE) 146endfunction () 147 148# ---------------------------------------------------------------------------- 149## Add usage test 150# 151# Using PASS_REGULAR_EXPRESSION and FAIL_REGULAR_EXPRESSION would 152# do as well, but CMake/CTest does not allow us to specify an 153# expected exit status. Moreover, the execute_test.cmake script 154# sets environment variables needed by the --fromenv/--tryfromenv tests. 155macro (add_gflags_test name expected_rc expected_output unexpected_output cmd) 156 set (args "--test_tmpdir=${PROJECT_BINARY_DIR}/Testing/Temporary" 157 "--srcdir=${PROJECT_SOURCE_DIR}/test") 158 add_test ( 159 NAME ${name} 160 COMMAND "${CMAKE_COMMAND}" "-DCOMMAND:STRING=$<TARGET_FILE:${cmd}>;${args};${ARGN}" 161 "-DEXPECTED_RC:STRING=${expected_rc}" 162 "-DEXPECTED_OUTPUT:STRING=${expected_output}" 163 "-DUNEXPECTED_OUTPUT:STRING=${unexpected_output}" 164 -P "${PROJECT_SOURCE_DIR}/cmake/execute_test.cmake" 165 WORKING_DIRECTORY "${GFLAGS_FLAGFILES_DIR}" 166 ) 167endmacro () 168 169# ------------------------------------------------------------------------------ 170## Register installed package with CMake 171# 172# This function adds an entry to the CMake registry for packages with the 173# path of the directory where the package configuration file of the installed 174# package is located in order to help CMake find the package in a custom 175# installation prefix. This differs from CMake's export(PACKAGE) command 176# which registers the build directory instead. 177function (register_gflags_package CONFIG_DIR) 178 if (NOT IS_ABSOLUTE "${CONFIG_DIR}") 179 set (CONFIG_DIR "${CMAKE_INSTALL_PREFIX}/${CONFIG_DIR}") 180 endif () 181 string (MD5 REGISTRY_ENTRY "${CONFIG_DIR}") 182 if (WIN32) 183 install (CODE 184 "execute_process ( 185 COMMAND reg add \"HKCU\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\" /v \"${REGISTRY_ENTRY}\" /d \"${CONFIG_DIR}\" /t REG_SZ /f 186 RESULT_VARIABLE RT 187 ERROR_VARIABLE ERR 188 OUTPUT_QUIET 189 ) 190 if (RT EQUAL 0) 191 message (STATUS \"Register: Added HKEY_CURRENT_USER\\\\Software\\\\Kitware\\\\CMake\\\\Packages\\\\${PACKAGE_NAME}\\\\${REGISTRY_ENTRY}\") 192 else () 193 string (STRIP \"\${ERR}\" ERR) 194 message (STATUS \"Register: Failed to add registry entry: \${ERR}\") 195 endif ()" 196 ) 197 elseif (IS_DIRECTORY "$ENV{HOME}") 198 file (WRITE "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" "${CONFIG_DIR}") 199 install ( 200 FILES "${PROJECT_BINARY_DIR}/${PACKAGE_NAME}-registry-entry" 201 DESTINATION "$ENV{HOME}/.cmake/packages/${PACKAGE_NAME}" 202 RENAME "${REGISTRY_ENTRY}" 203 ) 204 endif () 205endfunction () 206