Austin Schuh | 1eb16d1 | 2015-09-06 17:21:56 -0700 | [diff] [blame] | 1 | ## Utility CMake functions. |
| 2 | |
| 3 | # ---------------------------------------------------------------------------- |
| 4 | ## Convert boolean value to 0 or 1 |
| 5 | macro (bool_to_int VAR) |
| 6 | if (${VAR}) |
| 7 | set (${VAR} 1) |
| 8 | else () |
| 9 | set (${VAR} 0) |
| 10 | endif () |
| 11 | endmacro () |
| 12 | |
| 13 | # ---------------------------------------------------------------------------- |
Austin Schuh | 8fec4f4 | 2018-10-29 21:52:32 -0700 | [diff] [blame^] | 14 | ## Extract version numbers from version string |
Austin Schuh | 1eb16d1 | 2015-09-06 17:21:56 -0700 | [diff] [blame] | 15 | function (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) |
| 42 | endfunction () |
| 43 | |
| 44 | # ---------------------------------------------------------------------------- |
Austin Schuh | 8fec4f4 | 2018-10-29 21:52:32 -0700 | [diff] [blame^] | 45 | ## Determine if cache entry exists |
| 46 | macro (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 () |
| 52 | endmacro () |
| 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. |
| 61 | macro (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 () |
| 81 | endmacro () |
| 82 | |
| 83 | # ---------------------------------------------------------------------------- |
| 84 | ## Set property of cached gflags configuration variable |
| 85 | macro (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) |
| 101 | endmacro () |
| 102 | |
| 103 | # ---------------------------------------------------------------------------- |
| 104 | ## Modify value of gflags configuration variable |
| 105 | macro (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) |
| 113 | endmacro () |
| 114 | |
| 115 | # ---------------------------------------------------------------------------- |
Austin Schuh | 1eb16d1 | 2015-09-06 17:21:56 -0700 | [diff] [blame] | 116 | ## Configure public header files |
| 117 | function (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) |
| 131 | endfunction () |
| 132 | |
| 133 | # ---------------------------------------------------------------------------- |
| 134 | ## Configure source files with .in suffix |
| 135 | function (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) |
| 146 | endfunction () |
| 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. |
| 155 | macro (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 | ) |
| 167 | endmacro () |
Austin Schuh | 8fec4f4 | 2018-10-29 21:52:32 -0700 | [diff] [blame^] | 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. |
| 177 | function (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 () |
| 205 | endfunction () |