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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
|
# ~~~
# MacroUtilities - useful macros and functions for generic tasks
#
#
# General
# --------------
# function add_feature(<NAME> <DOCSTRING>)
# Add a feature, whose activation is specified by the
# existence of the variable <NAME>, to the list of enabled/disabled
# features, plus a docstring describing the feature
#
# function print_enabled_features()
# Print enabled features plus their docstrings.
#
# ~~~
# * Include guard
if(__${PROJECT_NAME}_macroutilities_isloaded)
return()
endif()
set(__${PROJECT_NAME}_macroutilities_isloaded YES)
cmake_policy(PUSH)
if(NOT CMAKE_VERSION VERSION_LESS 3.1)
cmake_policy(SET CMP0054 NEW)
endif()
include(CMakeDependentOption)
include(CMakeParseArguments)
# -----------------------------------------------------------------------
# macro safe_remove_duplicates(<list>) ensures remove_duplicates is only called
# if list has values
#
macro(safe_remove_duplicates _list)
if(NOT "${${_list}}" STREQUAL "")
list(REMOVE_DUPLICATES ${_list})
endif(NOT "${${_list}}" STREQUAL "")
endmacro()
# -----------------------------------------------------------------------
# function - capitalize - make a string capitalized (first letter is capital)
# usage: capitalize("SHARED" CShared) message(STATUS "-- CShared is
# \"${CShared}\"") $ -- CShared is "Shared"
function(capitalize str var)
# make string lower
string(TOLOWER "${str}" str)
string(SUBSTRING "${str}" 0 1 _first)
string(TOUPPER "${_first}" _first)
string(SUBSTRING "${str}" 1 -1 _remainder)
string(CONCAT str "${_first}" "${_remainder}")
set(${var}
"${str}"
PARENT_SCOPE)
endfunction()
# -----------------------------------------------------------------------
# GENERAL
# -----------------------------------------------------------------------
# function add_feature(<NAME> <DOCSTRING>) Add a project feature, whose
# activation is specified by the existence of the variable <NAME>, to the list
# of enabled/disabled features, plus a docstring describing the feature
#
function(ADD_FEATURE _var _description)
set(EXTRA_DESC "")
foreach(currentArg ${ARGN})
if(NOT "${currentArg}" STREQUAL "${_var}" AND NOT "${currentArg}" STREQUAL
"${_description}")
set(EXTRA_DESC "${EXTA_DESC}${currentArg}")
endif()
endforeach()
set_property(GLOBAL APPEND PROPERTY PROJECT_FEATURES ${_var})
# set(${_var} ${${_var}} CACHE INTERNAL "${_description}${EXTRA_DESC}")
set_property(GLOBAL PROPERTY ${_var}_DESCRIPTION
"${_description}${EXTRA_DESC}")
endfunction()
# ------------------------------------------------------------------------------#
# function add_option(<OPTION_NAME> <DOCSRING> <DEFAULT_SETTING> [NO_FEATURE])
# Add an option and add as a feature if NO_FEATURE is not provided
#
function(ADD_OPTION _NAME _MESSAGE _DEFAULT)
set(_FEATURE ${ARGN})
option(${_NAME} "${_MESSAGE}" ${_DEFAULT})
if(NOT "${_FEATURE}" STREQUAL "NO_FEATURE")
add_feature(${_NAME} "${_MESSAGE}")
else()
mark_as_advanced(${_NAME})
endif()
endfunction(
ADD_OPTION
_NAME
_MESSAGE
_DEFAULT)
# ------------------------------------------------------------------------------#
# macro CHECKOUT_GIT_SUBMODULE()
#
# Run "git submodule update" if a file in a submodule does not exist
#
# ARGS: RECURSIVE (option) -- add "--recursive" flag RELATIVE_PATH (one value)
# -- typically the relative path to submodule from PROJECT_SOURCE_DIR
# WORKING_DIRECTORY (one value) -- (default: PROJECT_SOURCE_DIR) TEST_FILE (one
# value) -- file to check for (default: CMakeLists.txt) ADDITIONAL_CMDS (many
# value) -- any addition commands to pass
#
function(CHECKOUT_GIT_SUBMODULE)
# parse args
cmake_parse_arguments(
CHECKOUT "RECURSIVE" "RELATIVE_PATH;WORKING_DIRECTORY;TEST_FILE"
"ADDITIONAL_CMDS" ${ARGN})
find_package(Git)
if(NOT Git_FOUND)
message(
WARNING
"Git not found. submodule ${CHECKOUT_RELATIVE_PATH} not checked out")
return()
endif()
if(NOT CHECKOUT_WORKING_DIRECTORY)
set(CHECKOUT_WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
endif(NOT CHECKOUT_WORKING_DIRECTORY)
if(NOT CHECKOUT_TEST_FILE)
set(CHECKOUT_TEST_FILE "CMakeLists.txt")
endif(NOT CHECKOUT_TEST_FILE)
set(_DIR "${CHECKOUT_WORKING_DIRECTORY}/${CHECKOUT_RELATIVE_PATH}")
# ensure the (possibly empty) directory exists
if(NOT EXISTS "${_DIR}")
message(FATAL_ERROR "submodule directory does not exist")
endif(NOT EXISTS "${_DIR}")
# if this file exists --> project has been checked out if not exists --> not
# been checked out
set(_TEST_FILE "${_DIR}/${CHECKOUT_TEST_FILE}")
set(_RECURSE)
if(CHECKOUT_RECURSIVE)
set(_RECURSE --recursive)
endif(CHECKOUT_RECURSIVE)
# if the module has not been checked out
if(NOT EXISTS "${_TEST_FILE}")
# perform the checkout
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY}
RESULT_VARIABLE RET)
# check the return code
if(RET GREATER 0)
set(_CMD "${GIT_EXECUTABLE} submodule update --init ${_RECURSE}
${CHECKOUT_ADDITIONAL_CMDS} ${CHECKOUT_RELATIVE_PATH}")
message(STATUS "macro(CHECKOUT_SUBMODULE) failed.")
message(WARNING "Command: \"${_CMD}\"")
return()
endif()
elseif(NOT SKIP_GIT_UPDATE)
message(
STATUS
"Executing '${GIT_EXECUTABLE} submodule update ${_RECURSE} ${CHECKOUT_RELATIVE_PATH}'... Disable with SKIP_GIT_UPDATE..."
)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update ${_RECURSE}
${CHECKOUT_RELATIVE_PATH}
WORKING_DIRECTORY ${CHECKOUT_WORKING_DIRECTORY})
endif()
endfunction()
# ------------------------------------------------------------------------------#
# function print_enabled_features() Print enabled features plus their
# docstrings.
#
function(print_enabled_features)
set(_basemsg "The following features are defined/enabled (+):")
set(_currentFeatureText "${_basemsg}")
get_property(_features GLOBAL PROPERTY PROJECT_FEATURES)
if(NOT "${_features}" STREQUAL "")
list(REMOVE_DUPLICATES _features)
list(SORT _features)
endif()
foreach(_feature ${_features})
if(${_feature})
# add feature to text
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
# get description
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
# print description, if not standard ON/OFF, print what is set to
if(_desc)
if(NOT "${${_feature}}" STREQUAL "ON" AND NOT "${${_feature}}" STREQUAL
"TRUE")
set(_currentFeatureText
"${_currentFeatureText}: ${_desc} -- [\"${${_feature}}\"]")
else()
string(REGEX REPLACE "^USE_" "" _feature_tmp "${_feature}")
string(TOLOWER "${_feature_tmp}" _feature_tmp_l)
capitalize("${_feature_tmp}" _feature_tmp_c)
foreach(_var _feature_tmp _feature_tmp_l _feature_tmp_c)
set(_ver "${${${_var}}_VERSION}")
if(NOT "${_ver}" STREQUAL "")
set(_desc "${_desc} -- [found version ${_ver}]")
break()
endif()
unset(_ver)
endforeach(_var _feature_tmp _feature_tmp_l _feature_tmp_c)
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
endif()
set(_desc NOTFOUND)
endif(_desc)
# check for subfeatures
get_property(_subfeatures GLOBAL PROPERTY ${_feature}_FEATURES)
# remove duplicates and sort if subfeatures exist
if(NOT "${_subfeatures}" STREQUAL "")
list(REMOVE_DUPLICATES _subfeatures)
list(SORT _subfeatures)
endif()
# sort enabled and disabled features into lists
set(_enabled_subfeatures)
set(_disabled_subfeatures)
foreach(_subfeature ${_subfeatures})
if(${_subfeature})
list(APPEND _enabled_subfeatures ${_subfeature})
else()
list(APPEND _disabled_subfeatures ${_subfeature})
endif()
endforeach()
# loop over enabled subfeatures
foreach(_subfeature ${_enabled_subfeatures})
# add subfeature to text
set(_currentFeatureText
"${_currentFeatureText}\n + ${_subfeature}")
# get subfeature description
get_property(_subdesc GLOBAL
PROPERTY ${_feature}_${_subfeature}_DESCRIPTION)
# print subfeature description. If not standard ON/OFF, print what is
# set to
if(_subdesc)
if(NOT "${${_subfeature}}" STREQUAL "ON" AND NOT "${${_subfeature}}"
STREQUAL "TRUE")
set(_currentFeatureText
"${_currentFeatureText}: ${_subdesc} -- [\"${${_subfeature}}\"]"
)
else()
set(_currentFeatureText "${_currentFeatureText}: ${_subdesc}")
endif()
set(_subdesc NOTFOUND)
endif(_subdesc)
endforeach(_subfeature)
# loop over disabled subfeatures
foreach(_subfeature ${_disabled_subfeatures})
# add subfeature to text
set(_currentFeatureText
"${_currentFeatureText}\n - ${_subfeature}")
# get subfeature description
get_property(_subdesc GLOBAL
PROPERTY ${_feature}_${_subfeature}_DESCRIPTION)
# print subfeature description.
if(_subdesc)
set(_currentFeatureText "${_currentFeatureText}: ${_subdesc}")
set(_subdesc NOTFOUND)
endif(_subdesc)
endforeach(_subfeature)
endif(${_feature})
endforeach(_feature)
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
message(STATUS "${_currentFeatureText}\n")
endif()
endfunction()
# ------------------------------------------------------------------------------#
# function print_disabled_features() Print disabled features plus their
# docstrings.
#
function(print_disabled_features)
set(_basemsg "The following features are NOT defined/enabled (-):")
set(_currentFeatureText "${_basemsg}")
get_property(_features GLOBAL PROPERTY PROJECT_FEATURES)
if(NOT "${_features}" STREQUAL "")
list(REMOVE_DUPLICATES _features)
list(SORT _features)
endif()
foreach(_feature ${_features})
if(NOT ${_feature})
set(_currentFeatureText "${_currentFeatureText}\n ${_feature}")
get_property(_desc GLOBAL PROPERTY ${_feature}_DESCRIPTION)
if(_desc)
set(_currentFeatureText "${_currentFeatureText}: ${_desc}")
set(_desc NOTFOUND)
endif(_desc)
endif()
endforeach(_feature)
if(NOT "${_currentFeatureText}" STREQUAL "${_basemsg}")
message(STATUS "${_currentFeatureText}\n")
endif()
endfunction()
# ------------------------------------------------------------------------------#
# function print_features() Print all features plus their docstrings.
#
function(print_features)
message(STATUS "")
print_enabled_features()
print_disabled_features()
endfunction()
# ------------------------------------------------------------------------------#
function(TOMOPY_ADD_LIBRARY _TARGET)
# basically this makes tomopy_add_library(...) act exactly like
# add_library(...)
add_library(${_TARGET} ${ARGN})
# check the name has the "tomo-" prefix (expected by libtomoConfig.cmake)
if(NOT "${_TARGET}" MATCHES "^(tomo-)")
message(
FATAL_ERROR
"The name of the target passed to tomopy_add_library MUST start with 'tomo-'"
)
endif()
# create an alias library in the build tree. This allows parent projects
# adding tomopy as a submodule to be able to always reference the libtomo
# targets with the libtomo:: namespace
add_library(libtomo::${_TARGET} ALIAS ${_TARGET})
# append to global property. Use the namespaced name because when
# libtomoConfig.cmake imports the targets tomo-accel will not be the name of
# the target, libtomo::tomo-accel will be the name
set_property(GLOBAL APPEND PROPERTY libtomo_TARGETS "libtomo::${_TARGET} ")
endfunction()
cmake_policy(POP)
|