ProjectTools.cmake
Go to the documentation of this file.
00001 ############################################################################## 00002 # @file ProjectTools.cmake 00003 # @brief Definition of main project tools. 00004 # 00005 # Copyright (c) 2011, 2012, 2013 University of Pennsylvania. All rights reserved.<br /> 00006 # See https://www.cbica.upenn.edu/sbia/software/license.html or COPYING file. 00007 # 00008 # Contact: SBIA Group <sbia-software at uphs.upenn.edu> 00009 ############################################################################## 00010 00011 # ============================================================================ 00012 # meta-data 00013 # ============================================================================ 00014 00015 # ---------------------------------------------------------------------------- 00016 ## @brief Check meta-data and set defaults. 00017 # 00018 # @sa basis_project() 00019 # @sa basis_slicer_module() 00020 macro (basis_project_check_metadata) 00021 # PROJECT_AUTHOR 00022 if (PROJECT_AUTHORS AND PROJECT_AUTHOR) 00023 message (FATAL_ERROR "Options AUTHOR and AUTHORS are mutually exclusive!") 00024 endif () 00025 if (PROJECT_AUTHOR) 00026 set (PROJECT_AUTHORS "${PROJECT_AUTHOR}") 00027 endif () 00028 if (NOT PROJECT_AUTHORS AND PROJECT_IS_MODULE) 00029 set (PROJECT_AUTHORS "${BASIS_PROJECT_AUTHORS}") 00030 endif () 00031 if (NOT PROJECT_IS_MODULE) 00032 set (BASIS_PROJECT_AUTHORS "${PROJECT_AUTHORS}") 00033 endif () 00034 # PROJECT_NAME or PROJECT_SUBPROJECT 00035 if (PROJECT_SUBPROJECT AND PROJECT_NAME) 00036 message (FATAL_ERROR "Options SUBPROJECT and NAME are mutually exclusive!") 00037 elseif (PROJECT_SUBPROJECT) 00038 set (PROJECT_NAME "${PROJECT_SUBPROJECT}") 00039 set (PROJECT_IS_SUBPROJECT TRUE) 00040 else () 00041 set (PROJECT_IS_SUBPROJECT FALSE) 00042 endif () 00043 unset (PROJECT_SUBPROJECT) 00044 if (NOT PROJECT_NAME) 00045 message (FATAL_ERROR "Project name not specified!") 00046 endif () 00047 if (NOT PROJECT_NAME MATCHES "^([a-z][a-z0-9]*|[A-Z][a-zA-Z0-9]*)") 00048 message (FATAL_ERROR "Invalid project name: ${PROJECT_NAME}!\n\n" 00049 "Please choose a project name with either only captial " 00050 "letters in case of an acronym or a name with mixed case, " 00051 "but starting with a captial letter.\n\n" 00052 "Note that numbers are allowed, but not as first character. " 00053 "Further, do not use characters such as '_' or '-' to " 00054 "separate parts of the project name. Instead, use the " 00055 "upper camel case notation " 00056 "(see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms).") 00057 endif () 00058 string (TOLOWER "${PROJECT_NAME}" PROJECT_NAME_L) 00059 string (TOUPPER "${PROJECT_NAME}" PROJECT_NAME_U) 00060 if (NOT PROJECT_IS_MODULE) 00061 set (BASIS_PROJECT_NAME "${PROJECT_NAME}") 00062 set (BASIS_PROJECT_NAME_L "${PROJECT_NAME_L}") 00063 set (BASIS_PROJECT_NAME_U "${PROJECT_NAME_U}") 00064 endif () 00065 # PROJECT_PACKAGE 00066 if (NOT PROJECT_PACKAGE) 00067 if (PROJECT_IS_MODULE) 00068 set (PROJECT_PACKAGE "${BASIS_PROJECT_PACKAGE}") 00069 else () 00070 if (PROJECT_IS_SUBPROJECT) 00071 message (FATAL_ERROR "Missing PACKAGE option for SUBPROJECT ${PROJECT_NAME}!" 00072 " Note that the PACKAGE option is required for subprojects" 00073 " in order to enable the independent build. It should be" 00074 " set to the name of the top-level project this subproject" 00075 " belongs to. Otherwise, the subproject can only be build" 00076 " as part of the package it belongs to.") 00077 endif () 00078 set (PROJECT_PACKAGE "${PROJECT_NAME}") 00079 endif () 00080 endif () 00081 if (NOT PROJECT_PACKAGE MATCHES "^([a-z][a-z0-9]*|[A-Z][a-zA-Z0-9]*)") 00082 message (FATAL_ERROR "Project ${PROJECT_NAME} declares invalid package name: ${PROJECT_PACKAGE}!\n\n" 00083 "Please choose a package name with either only captial " 00084 "letters in case of an acronym or a name with mixed case, " 00085 "but starting with a captial letter.\n\n" 00086 "Note that numbers are allowed, but not as first character. " 00087 "Further, do not use characters such as '_' or '-' to " 00088 "separate parts of the package name. Instead, use the " 00089 "upper camel case notation " 00090 "(see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms).") 00091 endif () 00092 string (TOLOWER "${PROJECT_PACKAGE}" PROJECT_PACKAGE_L) 00093 string (TOUPPER "${PROJECT_PACKAGE}" PROJECT_PACKAGE_U) 00094 if (NOT PROJECT_IS_MODULE) 00095 set (BASIS_PROJECT_PACKAGE "${PROJECT_PACKAGE}") 00096 set (BASIS_PROJECT_PACKAGE_L "${PROJECT_PACKAGE_L}") 00097 set (BASIS_PROJECT_PACKAGE_U "${PROJECT_PACKAGE_U}") 00098 endif () 00099 # PROJECT_PACKAGE_VENDOR 00100 if (PROJECT_PROVIDER AND PROJECT_PACKAGE_VENDOR) 00101 message (FATAL_ERROR "Options PROVIDER and PACKAGE_VENDOR are mutually exclusive!") 00102 endif () 00103 if (PROJECT_PROVIDER) 00104 set (PROJECT_PACKAGE_VENDOR "${PROJECT_PROVIDER}") 00105 endif () 00106 if (NOT PROJECT_PACKAGE_VENDOR) 00107 if (PROJECT_IS_MODULE) 00108 set (PROJECT_PACKAGE_VENDOR "${BASIS_PROJECT_PACKAGE_VENDOR}") 00109 else () 00110 set (PROJECT_PACKAGE_VENDOR "${BASIS_PACKAGE_VENDOR}") 00111 endif () 00112 endif () 00113 string (TOLOWER "${PROJECT_PACKAGE_VENDOR}" PROJECT_PACKAGE_VENDOR_L) 00114 string (TOUPPER "${PROJECT_PACKAGE_VENDOR}" PROJECT_PACKAGE_VENDOR_U) 00115 if (NOT PROJECT_IS_MODULE) 00116 set (BASIS_PROJECT_PACKAGE_VENDOR "${PROJECT_PACKAGE_VENDOR}") 00117 set (BASIS_PROJECT_PACKAGE_VENDOR_L "${PROJECT_PACKAGE_VENDOR_L}") 00118 set (BASIS_PROJECT_PACKAGE_VENDOR_U "${PROJECT_PACKAGE_VENDOR_U}") 00119 endif () 00120 # PROJECT_VERSION 00121 if (PROJECT_VERSION) 00122 if (NOT PROJECT_VERSION MATCHES "^[0-9]+(\\.[0-9]+)?(\\.[0-9]+)?(rc[0-9]+|[a-z])?$") 00123 message (FATAL_ERROR "Project ${PROJECT_NAME} has invalid version: ${PROJECT_VERSION}!") 00124 endif () 00125 if (PROJECT_IS_MODULE) 00126 if (PROJECT_VERSION MATCHES "^0+(\\.0+)?(\\.0+)?$") 00127 set (PROJECT_VERSION "${BASIS_PROJECT_VERSION}") 00128 endif () 00129 else () 00130 set (BASIS_PROJECT_VERSION "${PROJECT_VERSION}") 00131 endif () 00132 else () 00133 if (PROJECT_IS_MODULE) 00134 set (PROJECT_VERSION "${BASIS_PROJECT_VERSION}") 00135 else () 00136 message (FATAL_ERROR "Project version not specified!") 00137 endif () 00138 endif () 00139 # PROJECT_DESCRIPTION 00140 if (PROJECT_DESCRIPTION) 00141 basis_list_to_string (PROJECT_DESCRIPTION ${PROJECT_DESCRIPTION}) 00142 else () 00143 set (PROJECT_DESCRIPTION "") 00144 endif () 00145 # PROJECT_COPYRIGHT 00146 if (NOT PROJECT_COPYRIGHT) 00147 if (PROJECT_IS_MODULE) 00148 set (PROJECT_COPYRIGHT "${BASIS_PROJECT_COPYRIGHT}") 00149 else () 00150 set (PROJECT_COPYRIGHT "${BASIS_COPYRIGHT}") 00151 endif () 00152 endif () 00153 if (NOT PROJECT_IS_MODULE) 00154 set (BASIS_PROJECT_COPYRIGHT "${PROJECT_COPYRIGHT}") 00155 endif () 00156 # PROJECT_LICENSE 00157 if (NOT PROJECT_LICENSE) 00158 if (PROJECT_IS_MODULE) 00159 set (PROJECT_LICENSE "${BASIS_PROJECT_LICENSE}") 00160 else () 00161 set (PROJECT_LICENSE "${BASIS_LICENSE}") 00162 endif () 00163 endif () 00164 if (NOT PROJECT_IS_MODULE) 00165 set (BASIS_PROJECT_LICENSE "${PROJECT_LICENSE}") 00166 endif () 00167 # PROJECT_CONTACT 00168 if (NOT PROJECT_CONTACT) 00169 if (PROJECT_IS_MODULE) 00170 set (PROJECT_CONTACT "${BASIS_PROJECT_CONTACT}") 00171 else () 00172 set (PROJECT_CONTACT "${BASIS_CONTACT}") 00173 endif () 00174 endif () 00175 if (NOT PROJECT_IS_MODULE) 00176 set (BASIS_PROJECT_CONTACT "${PROJECT_CONTACT}") 00177 endif () 00178 # let basis_project_impl() know that basis_project() was called 00179 set (BASIS_basis_project_CALLED TRUE) 00180 endmacro () 00181 00182 # ---------------------------------------------------------------------------- 00183 ## @brief Define project meta-data, i.e., attributes. 00184 # 00185 # Any BASIS project has to call this macro in the file BasisProject.cmake 00186 # located in the top level directory of the source tree in order to define 00187 # the project attributes required by BASIS to setup the build system. 00188 # Moreover, if the BASIS project is a module of another BASIS project, this 00189 # file and the variables set by this macro are used by the top-level project to 00190 # identify its modules and the dependencies among them. 00191 # 00192 # @par Project version: 00193 # The version number consists of three components: the major version number, 00194 # the minor version number, and the patch number. The format of the version 00195 # string is "<major>.<minor>.<patch>", where the minor version number and patch 00196 # number default to "0" if not given. Only digits are allowed except of the two 00197 # separating dots. 00198 # @n 00199 # - A change of the major version number indicates changes of the softwares 00200 # @api (and @abi) and/or its behavior and/or the change or addition of major 00201 # features. 00202 # - A change of the minor version number indicates changes that are not only 00203 # bug fixes and no major changes. Hence, changes of the @api but not the @abi. 00204 # - A change of the patch number indicates changes only related to bug fixes 00205 # which did not change the softwares @api. It is the least important component 00206 # of the version number. 00207 # 00208 # @par Dependencies: 00209 # Dependencies on other BASIS projects, which can be subprojects of the same 00210 # BASIS top-level project, as well as dependencies on external packages such as ITK 00211 # have to be defined here using the @p DEPENDS argument option. This will be used 00212 # by a top-level project to ensure that the dependencies among its subprojects are 00213 # resolved properly. For each external dependency, the BASIS functions 00214 # basis_find_package() and basis_use_package() are invoked by 00215 # basis_project_initialize(). If an external package is not CMake aware and 00216 # additional CMake code shall be executed to include the settings of the external 00217 # package (which is usually done in a so-called <tt>Use<Pkg>.cmake</tt> file 00218 # if the package would be CMake aware), such code should be added to the 00219 # <tt>Settings.cmake</tt> file of the project. 00220 # 00221 # @param [in] ARGN This list is parsed for the following arguments: 00222 # @par 00223 # <table border="0"> 00224 # <tr> 00225 # @tp @b NAME name @endtp 00226 # <td>The name of the project.</td> 00227 # </tr> 00228 # <tr> 00229 # @tp @b SUBPROJECT name @endtp 00230 # <td>Use this option instead of @c NAME to indicate that this project is a 00231 # subproject of the package @c PACKAGE. This results, for example, in target 00232 # UIDs such as "<package>.<name>.<target>" instead of "<package>.<target>". 00233 # Moreover, the libraries and shared files of a subproject are installed 00234 # in subdirectores whose name equals the name of the subproject. This option 00235 # should only be used for projects which are modules of another BASIS project, 00236 # where these modules should reside in their own sub-namespace rather than 00237 # on the same level as the top-level project.</td> 00238 # </tr> 00239 # <tr> 00240 # @tp @b PACKAGE pkg @endtp 00241 # <td>Name of the package this project (module) belongs to. Defaults to the 00242 # name of the (top-level) project. This option can further be used in case 00243 # of a top-level project to specify a different package name for the installation. 00244 # In case of a subproject which is a module of another BASIS project, setting 00245 # the package name explicitly using this option enables the build of the 00246 # subproject as separate project while preserving the directory structure 00247 # and other namespace settings. Therefore, this option is required if the 00248 # @c SUBPROJECT option is given and the project shall be build independently 00249 # as stand-alone package. (default: name of top-level package)</td> 00250 # </tr> 00251 # <tr> 00252 # @tp @b PACKAGE_VENDOR vendor @endtp 00253 # <td>The vendor of this package, used for packaging and installation. 00254 # (default: vendor of top-level project or empty string)</td> 00255 # </tr> 00256 # <tr> 00257 # @tp @b PROVIDER vendor @endtp 00258 # <td>This option can be used as an alternative to @c PACKAGE_VENDOR.</td> 00259 # </tr> 00260 # <tr> 00261 # @tp @b VERSION major[.minor[.patch]] @endtp 00262 # <td>Project version string. (default: 1.0.0)</td> 00263 # </tr> 00264 # <tr> 00265 # @tp @b DESCRIPTION description @endtp 00266 # <td>Package description, used for packing. If multiple arguments are given, 00267 # they are concatenated using one space character as delimiter.</td> 00268 # </tr> 00269 # <tr> 00270 # @tp @b DEPENDS name[, name] @endtp 00271 # <td>List of dependencies, i.e., either names of other BASIS (sub)projects 00272 # or names of external packages.</td> 00273 # </tr> 00274 # <tr> 00275 # @tp @b OPTIONAL_DEPENDS name[, name] @endtp 00276 # <td>List of dependencies, i.e., either names of other BASIS (sub)projects 00277 # or names of external packages which are used only if available.</td> 00278 # </tr> 00279 # <tr> 00280 # @tp @b TEST_DEPENDS name[, name] @endtp 00281 # <td>List of dependencies, i.e., either names of other BASIS (sub)projects 00282 # or names of external packages which are only required by the tests.</td> 00283 # </tr> 00284 # <tr> 00285 # @tp @b OPTIONAL_TEST_DEPENDS name[, name] @endtp 00286 # <td>List of dependencies, i.e., either names of other BASIS (sub)projects 00287 # or names of external packages which are used only by the tests if available.</td> 00288 # </tr> 00289 # </table> 00290 # 00291 # @returns Sets the following non-cached CMake variables: 00292 # @retval PROJECT_NAME @c NAME argument. 00293 # @retval PROJECT_PACKAGE @c PACKAGE argument. 00294 # @retval PROJECT_PACKAGE_VENDOR @c PACKAGE_VENDOR argument. 00295 # @retval PROJECT_VERSION @c VERSION argument. 00296 # @retval PROJECT_DESCRIPTION @c DESCRIPTION argument. 00297 # @retval PROJECT_DEPENDS @c DEPENDS arguments. 00298 # @retval PROJECT_OPTIONAL_DEPENDS @c OPTIONAL_DEPENDS arguments. 00299 # @retval PROJECT_TEST_DEPENDS @c TEST_DEPENDS arguments. 00300 # @retval PROJECT_OPTIONAL_TEST_DEPENDS @c OPTIONAL_TEST_DEPENDS arguments. 00301 # @retval PROJECT_IS_SUBPROJECT @c TRUE if @c IS_SUBPROJECT option given or @c FALSE otherwise. 00302 # 00303 # @ingroup CMakeAPI 00304 macro (basis_project) 00305 CMAKE_PARSE_ARGUMENTS ( 00306 PROJECT 00307 "${BASIS_METADATA_LIST_SWITCH}" 00308 "${BASIS_METADATA_LIST_SINGLE}" 00309 "${BASIS_METADATA_LIST_MULTI}" 00310 ${ARGN} 00311 ) 00312 basis_project_check_metadata () 00313 endmacro () 00314 00315 00316 ## @addtogroup CMakeUtilities 00317 # @{ 00318 00319 00320 # ============================================================================ 00321 # initialization 00322 # ============================================================================ 00323 00324 # ---------------------------------------------------------------------------- 00325 ## @brief Ensure certain requirements on build tree. 00326 # 00327 # Requirements: 00328 # - Root of build tree must not be root of source tree. 00329 # 00330 # @param [in] ARGN Not used. 00331 # 00332 # @returns Nothing. 00333 function (basis_buildtree_asserts) 00334 string (TOLOWER "${CMAKE_SOURCE_DIR}" SOURCE_ROOT) 00335 string (TOLOWER "${CMAKE_BINARY_DIR}" BUILD_ROOT) 00336 basis_sanitize_for_regex (SOURCE_ROOT_RE "${SOURCE_ROOT}") 00337 if (BUILD_ROOT MATCHES "^${SOURCE_ROOT_RE}$") 00338 message(FATAL_ERROR "This project should not be configured & build in the " 00339 "source directory:\n" 00340 " ${CMAKE_SOURCE_DIR}\n" 00341 "You must run CMake in a separate build directory.") 00342 endif() 00343 endfunction () 00344 00345 # ---------------------------------------------------------------------------- 00346 ## @brief Ensure certain requirements on install tree. 00347 # 00348 # Requirements: 00349 # - Prefix must be an absolute path. 00350 # - Install tree must be different from source and build tree. 00351 # 00352 # @param [in] ARGN Not used. 00353 # 00354 # @returns Nothing. 00355 function (basis_installtree_asserts) 00356 if (NOT IS_ABSOLUTE "${CMAKE_INSTALL_PREFIX}") 00357 message (FATAL_ERROR "CMAKE_INSTALL_PREFIX must be an absolute path!") 00358 endif () 00359 string (TOLOWER "${CMAKE_SOURCE_DIR}" SOURCE_ROOT) 00360 string (TOLOWER "${CMAKE_BINARY_DIR}" BUILD_ROOT) 00361 string (TOLOWER "${CMAKE_INSTALL_PREFIX}" INSTALL_ROOT) 00362 basis_sanitize_for_regex (INSTALL_ROOT_RE "${INSTALL_ROOT}") 00363 if (BUILD_ROOT MATCHES "^${INSTALL_ROOT_RE}$" OR SOURCE_ROOT MATCHES "^${INSTALL_ROOT_RE}$") 00364 message (FATAL_ERROR "The current CMAKE_INSTALL_PREFIX points at the source or build tree:\n" 00365 " ${CMAKE_INSTALL_PREFIX}\n" 00366 "This is not permitted by this project. " 00367 "Please choose another installation prefix." 00368 ) 00369 endif() 00370 endfunction () 00371 00372 # ---------------------------------------------------------------------------- 00373 ## @brief Initialize project modules. 00374 # 00375 # Most parts of this macro were copied from the ITK4 project 00376 # (http://www.vtk.org/Wiki/ITK_Release_4), in particular, the top-level 00377 # CMakeLists.txt file. This file does not state any specific license, but 00378 # the ITK package itself is released under the Apache License Version 2.0, 00379 # January 2004 (http://www.apache.org/licenses/). 00380 # 00381 # @attention At this point, the project-specific variables have not been 00382 # set yet. For example, use @c CMAKE_CURRENT_SOURCE_DIR instead of 00383 # @c PROJECT_SOURCE_DIR. 00384 macro (basis_project_modules) 00385 # -------------------------------------------------------------------------- 00386 # reset variables 00387 set (PROJECT_MODULES) 00388 set (PROJECT_MODULES_ENABLED) 00389 set (PROJECT_MODULES_DISABLED) 00390 00391 # -------------------------------------------------------------------------- 00392 # load module DAG 00393 00394 # glob BasisProject.cmake files in modules subdirectory 00395 file ( 00396 GLOB 00397 MODULE_INFO_FILES 00398 RELATIVE 00399 "${CMAKE_CURRENT_SOURCE_DIR}" 00400 "${CMAKE_CURRENT_SOURCE_DIR}/modules/*/BasisProject.cmake" 00401 ) 00402 00403 # use function scope to avoid overwriting of this project's variables 00404 function (basis_module_info F) 00405 set (PROJECT_IS_MODULE TRUE) 00406 set (BASIS_basis_project_CALLED FALSE) 00407 include ("${CMAKE_CURRENT_SOURCE_DIR}/${F}") 00408 # make sure that basis_project() was called 00409 if (NOT BASIS_basis_project_CALLED) 00410 message (FATAL_ERROR "basis_module_info(): Missing basis_project() command in ${F}!") 00411 endif () 00412 # remember dependencies 00413 foreach (V IN ITEMS DEPENDS OPTIONAL_DEPENDS TEST_DEPENDS OPTIONAL_TEST_DEPENDS) 00414 set (${V}) 00415 foreach (D ${PROJECT_${V}}) 00416 basis_tokenize_dependency ("${D}" PKG VER CMP) 00417 list (APPEND ${V} "${PKG}") 00418 endforeach () 00419 endforeach () 00420 set (${PROJECT_NAME}_DEPENDS "${DEPENDS}" PARENT_SCOPE) 00421 set (${PROJECT_NAME}_OPTIONAL_DEPENDS "${OPTIONAL_DEPENDS}" PARENT_SCOPE) 00422 set (${PROJECT_NAME}_TEST_DEPENDS "${TEST_DEPENDS}" PARENT_SCOPE) 00423 set (${PROJECT_NAME}_OPTIONAL_TEST_DEPENDS "${OPTIONAL_TEST_DEPENDS}" PARENT_SCOPE) 00424 set (${PROJECT_NAME}_DECLARED TRUE PARENT_SCOPE) 00425 # remember if module depends on Slicer - used by basis_find_packages() 00426 if (PROJECT_IS_SLICER_MODULE) 00427 foreach (_D IN LISTS BASIS_SLICER_METADATA_LIST) 00428 if (DEFINED PROJECT_${_D}) 00429 set (${PROJECT_NAME}_${_D} "${PROJECT_${_D}}" PARENT_SCOPE) 00430 endif () 00431 endforeach () 00432 set (${PROJECT_NAME}_IS_SLICER_MODULE TRUE PARENT_SCOPE) 00433 else () 00434 set (${PROJECT_NAME}_IS_SLICER_MODULE FALSE PARENT_SCOPE) 00435 endif () 00436 # do not use MODULE instead of PROJECT_NAME in this function as it is not 00437 # set in the scope of this function but its parent scope only 00438 set (MODULE "${PROJECT_NAME}" PARENT_SCOPE) 00439 endfunction () 00440 00441 set (PROJECT_MODULES) 00442 foreach (F IN LISTS MODULE_INFO_FILES) 00443 basis_module_info (${F}) 00444 list (APPEND PROJECT_MODULES ${MODULE}) 00445 get_filename_component (${MODULE}_BASE ${F} PATH) 00446 set (MODULE_${MODULE}_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${${MODULE}_BASE}") 00447 # use module name as subdirectory name such that the default package 00448 # configuration file knows where to find the module configurations 00449 set (MODULE_${MODULE}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/modules/${MODULE}") 00450 # help modules to find each other using basis_find_package() 00451 set (${MODULE}_DIR "${MODULE_${MODULE}_BINARY_DIR}") 00452 endforeach() 00453 unset (MODULE) 00454 00455 # validate the module DAG to identify cyclic dependencies 00456 macro (basis_module_check MODULE NEEDED_BY STACK) 00457 if (${MODULE}_DECLARED) 00458 if (${MODULE}_CHECK_STARTED AND NOT ${MODULE}_CHECK_FINISHED) 00459 # we reached a module while traversing its own dependencies recursively 00460 set (MSG "") 00461 foreach (M ${STACK}) 00462 set (MSG " ${M} =>${MSG}") 00463 if ("${M}" STREQUAL "${MODULE}") 00464 break () 00465 endif () 00466 endforeach () 00467 message (FATAL_ERROR "Module dependency cycle detected:\n ${MSG} ${MODULE}") 00468 elseif (NOT ${MODULE}_CHECK_STARTED) 00469 # traverse dependencies of this module 00470 set (${MODULE}_CHECK_STARTED TRUE) 00471 foreach (D IN LISTS ${MODULE}_DEPENDS) 00472 basis_module_check (${D} ${MODULE} "${MODULE};${STACK}") 00473 endforeach () 00474 set (${MODULE}_CHECK_FINISHED TRUE) 00475 endif () 00476 endif () 00477 endmacro () 00478 00479 foreach (MODULE ${PROJECT_MODULES}) 00480 basis_module_check ("${MODULE}" "" "") 00481 endforeach () 00482 00483 # -------------------------------------------------------------------------- 00484 # determine list of enabled modules 00485 00486 # provide an option for all modules 00487 if (PROJECT_MODULES) 00488 option (BUILD_ALL_MODULES "Request to build all modules." OFF) 00489 endif () 00490 00491 # provide an option for each module 00492 foreach (MODULE ${PROJECT_MODULES}) 00493 option (MODULE_${MODULE} "Request building module ${MODULE}." OFF) 00494 if (${MODULE}_EXCLUDE_FROM_ALL) 00495 set (${MODULE}_IN_ALL FALSE) 00496 else () 00497 set (${MODULE}_IN_ALL ${BUILD_ALL_MODULES}) 00498 endif () 00499 endforeach () 00500 00501 # follow dependencies 00502 macro (basis_module_enable MODULE NEEDED_BY) 00503 if (${MODULE}_DECLARED) 00504 if (NOT "${NEEDED_BY}" STREQUAL "") 00505 list (APPEND ${MODULE}_NEEDED_BY "${NEEDED_BY}") 00506 endif () 00507 if (NOT ${MODULE}_ENABLED) 00508 if ("${NEEDED_BY}" STREQUAL "") 00509 set (${MODULE}_NEEDED_BY) 00510 endif () 00511 set (${MODULE}_ENABLED TRUE) 00512 foreach (D IN LISTS ${MODULE}_DEPENDS) 00513 basis_module_enable (${D} ${MODULE}) 00514 endforeach () 00515 endif () 00516 endif () 00517 endmacro () 00518 00519 foreach (MODULE ${PROJECT_MODULES}) 00520 if (MODULE_${MODULE} OR ${MODULE}_IN_ALL) 00521 basis_module_enable ("${MODULE}" "") 00522 endif () 00523 endforeach () 00524 00525 # build final list of enabled modules 00526 set (PROJECT_MODULES_ENABLED "") 00527 set (PROJECT_MODULES_DISABLED "") 00528 foreach (MODULE ${PROJECT_MODULES}) 00529 if (${MODULE}_DECLARED) 00530 if (${MODULE}_ENABLED) 00531 list (APPEND PROJECT_MODULES_ENABLED ${MODULE}) 00532 else () 00533 list (APPEND PROJECT_MODULES_DISABLED ${MODULE}) 00534 endif () 00535 endif () 00536 endforeach () 00537 list (SORT PROJECT_MODULES_ENABLED) # Deterministic order. 00538 list (SORT PROJECT_MODULES_DISABLED) # Deterministic order. 00539 00540 # order list to satisfy dependencies 00541 include (${BASIS_MODULE_PATH}/TopologicalSort.cmake) 00542 topological_sort (PROJECT_MODULES_ENABLED "" "_DEPENDS") 00543 00544 # remove external dependencies 00545 set (L) 00546 foreach (MODULE ${PROJECT_MODULES_ENABLED}) 00547 if (${MODULE}_DECLARED) 00548 list (APPEND L "${MODULE}") 00549 endif () 00550 endforeach () 00551 set (PROJECT_MODULES_ENABLED "${L}") 00552 unset (L) 00553 00554 # report what will be built 00555 if (PROJECT_MODULES_ENABLED) 00556 message (STATUS "Enabled modules [${PROJECT_MODULES_ENABLED}].") 00557 endif () 00558 00559 # turn options ON for modules that are required by other modules 00560 foreach (MODULE ${PROJECT_MODULES}) 00561 if (DEFINED MODULE_${MODULE} # there was an option for the user 00562 AND NOT MODULE_${MODULE} # user did not set it to ON themself 00563 AND NOT ${MODULE}_IN_ALL # BUILD_ALL_MODULES was not set ON 00564 AND ${MODULE}_NEEDED_BY) # module is needed by other module(s) 00565 set (MODULE_${MODULE} ON CACHE BOOL "Request building module ${MODULE}." FORCE) 00566 message ("Enabled module ${MODULE}, needed by [${${MODULE}_NEEDED_BY}].") 00567 endif () 00568 endforeach () 00569 endmacro () 00570 00571 # ---------------------------------------------------------------------------- 00572 ## @brief Configure public header files. 00573 function (basis_configure_public_headers) 00574 # -------------------------------------------------------------------------- 00575 # settings 00576 00577 # log file which lists the configured header files 00578 set (CMAKE_FILE "${BINARY_INCLUDE_DIR}/${PROJECT_NAME}PublicHeaders.cmake") 00579 # considered extensions (excl. .in suffix) 00580 set ( 00581 EXTENSIONS 00582 ".h" 00583 ".hh" 00584 ".hpp" 00585 ".hxx" 00586 ".inl" 00587 ".txx" 00588 ".inc" 00589 ) 00590 # considered include directories 00591 basis_get_relative_path (INCLUDE_DIR "${PROJECT_SOURCE_DIR}" "${PROJECT_INCLUDE_DIR}") 00592 set (INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/${INCLUDE_DIR}") 00593 00594 # -------------------------------------------------------------------------- 00595 # clean up last run before the error because a file was added/removed 00596 file (REMOVE "${CMAKE_FILE}.tmp") 00597 file (REMOVE "${CMAKE_FILE}.updated") 00598 if (EXISTS "${CMAKE_FILE}") 00599 # required to be able to remove now obsolete files from the build tree 00600 file (RENAME "${CMAKE_FILE}" "${CMAKE_FILE}.tmp") 00601 endif () 00602 00603 # -------------------------------------------------------------------------- 00604 # configure public header files 00605 message (STATUS "Configuring public header files...") 00606 00607 execute_process ( 00608 COMMAND "${CMAKE_COMMAND}" ${COMMON_ARGS} 00609 -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}" 00610 -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}" 00611 -D "EXTENSIONS=${EXTENSIONS}" 00612 -D "CACHE_FILE=${PROJECT_BINARY_DIR}/BasisCache.txt" 00613 -D "CMAKE_FILE=${CMAKE_FILE}" 00614 -P "${BASIS_MODULE_PATH}/ConfigureIncludeFiles.cmake" 00615 RESULT_VARIABLE RT 00616 ) 00617 00618 if (RT EQUAL 0) 00619 execute_process ( 00620 COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_FILE}.updated" 00621 ) 00622 else () 00623 message (FATAL_ERROR "Failed to configure public header files!") 00624 endif () 00625 00626 if (NOT EXISTS "${CMAKE_FILE}") 00627 message (FATAL_ERROR "File ${CMAKE_FILE} not generated as it should have been!") 00628 endif () 00629 00630 # remove header files from build tree which were copied there before but 00631 # are part of a now disabled module or were simply removed from the source tree 00632 if (EXISTS "${CMAKE_FILE}.tmp") 00633 execute_process ( 00634 # Compare current list of headers to list of previously configured files. 00635 # If the lists differ, this command removes files which have been removed 00636 # from the directory tree with root PROJECT_INCLUDE_DIR also from the 00637 # tree with root directory BINARY_INCLUDE_DIR. 00638 COMMAND "${CMAKE_COMMAND}" ${COMMON_ARGS} 00639 -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}" 00640 -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}" 00641 -D "CMAKE_FILE=${CMAKE_FILE}.tmp" 00642 -D "REFERENCE_FILE=${CMAKE_FILE}" 00643 -P "${BASIS_MODULE_PATH}/CheckPublicHeaders.cmake" 00644 VERBATIM 00645 ) 00646 file (REMOVE "${CMAKE_FILE}.tmp") 00647 if (NOT RT EQUAL 0) 00648 message (FATAL_ERROR "Failed to remove obsolete header files from build tree." 00649 " Remove the ${BINARY_INCLUDE_DIR} directory and re-run CMake.") 00650 endif () 00651 endif () 00652 00653 message (STATUS "Configuring public header files... - done") 00654 00655 # We need a list of the configured files to add them as dependency of the 00656 # custom build targets such that these get re-build whenever a file changed. 00657 # Additionally, including this file here which is modified whenever a 00658 # header file is added or removed triggeres a re-configuration of the 00659 # build system which is required to re-execute this function and adjust 00660 # these custom build targets. 00661 00662 include ("${CMAKE_FILE}") 00663 00664 # -------------------------------------------------------------------------- 00665 # check if any header was added or removed (always out-of-date) 00666 00667 # error message displayed when a file was added or removed which requires 00668 # a reconfiguration of the build system 00669 set (ERRORMSG "You have either added, removed, or renamed a public header file" 00670 " with a .in suffix in the file name. Therefore, the build system" 00671 " needs to be re-configured. Either try to build again which will" 00672 " trigger CMake and re-configure the build system or run CMake manually.") 00673 basis_list_to_string (ERRORMSG ${ERRORMSG}) 00674 00675 # custom command which globs the files in the project's include directory 00676 set (COMMENT "Checking if public header files were added or removed") 00677 if (PROJECT_IS_MODULE) 00678 set (COMMENT "${COMMENT} to ${PROJECT_NAME} module") 00679 endif () 00680 add_custom_command ( 00681 OUTPUT "${CMAKE_FILE}.tmp" 00682 COMMAND "${CMAKE_COMMAND}" 00683 -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}" 00684 -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}" 00685 -D "EXTENSIONS=${EXTENSIONS}" 00686 -D "CMAKE_FILE=${CMAKE_FILE}.tmp" 00687 -D "PREVIEW=TRUE" # do not actually configure the files 00688 -P "${BASIS_MODULE_PATH}/ConfigureIncludeFiles.cmake" 00689 COMMENT "${COMMENT}" 00690 VERBATIM 00691 ) 00692 00693 # custom target to detect whether a file was added or removed 00694 basis_make_target_uid (CHECK_HEADERS_TARGET headers_check) 00695 add_custom_target ( 00696 ${CHECK_HEADERS_TARGET} ALL 00697 # trigger execution of custom command that generates the list 00698 # of current files in the project's include directory 00699 DEPENDS "${CMAKE_FILE}.tmp" 00700 # Compare current list of headers to list of previously configured files. 00701 # If the lists differ, the build of this target fails with the given error message. 00702 COMMAND "${CMAKE_COMMAND}" 00703 -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}" 00704 -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}" 00705 -D "CMAKE_FILE=${CMAKE_FILE}" 00706 -D "REFERENCE_FILE=${CMAKE_FILE}.tmp" 00707 -D "ERRORMSG=${ERRORMSG}" 00708 -D "REMOVE_FILES_IF_DIFFERENT=TRUE" # triggers reconfigure on next build 00709 -P "${BASIS_MODULE_PATH}/CheckPublicHeaders.cmake" 00710 # remove temporary file again to force its regeneration 00711 COMMAND "${CMAKE_COMMAND}" -E remove "${CMAKE_FILE}.tmp" 00712 VERBATIM 00713 ) 00714 if (PROJECT_IS_MODULE) 00715 if (NOT TARGET headers_check) 00716 add_custom_target (headers_check ALL) 00717 endif () 00718 add_dependencies (headers_check ${CHECK_HEADERS_TARGET}) 00719 endif () 00720 00721 # -------------------------------------------------------------------------- 00722 # add build command to re-configure public header files 00723 if (PUBLIC_HEADERS) 00724 set (COMMENT "Configuring public header files") 00725 if (PROJECT_IS_MODULE) 00726 set (COMMENT "${COMMENT} of ${PROJECT_NAME} module") 00727 endif () 00728 add_custom_command ( 00729 OUTPUT "${CMAKE_FILE}.updated" # do not use same file as included 00730 # before otherwise CMake will re-configure 00731 # the build system next time 00732 COMMAND "${CMAKE_COMMAND}" 00733 -D "PROJECT_INCLUDE_DIRS=${INCLUDE_DIRS}" 00734 -D "BINARY_INCLUDE_DIR=${BINARY_INCLUDE_DIR}" 00735 -D "EXTENSIONS=${EXTENSIONS}" 00736 -D "CACHE_FILE=${PROJECT_BINARY_DIR}/BasisCache.txt" 00737 -P "${BASIS_MODULE_PATH}/ConfigureIncludeFiles.cmake" 00738 COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_FILE}.updated" 00739 DEPENDS ${PUBLIC_HEADERS} 00740 COMMENT "${COMMENT}" 00741 VERBATIM 00742 ) 00743 basis_make_target_uid (CONFIGURE_HEADERS_TARGET headers) 00744 add_custom_target ( 00745 ${CONFIGURE_HEADERS_TARGET} ALL 00746 DEPENDS ${CHECK_HEADERS_TARGET} "${CMAKE_FILE}.updated" 00747 SOURCES ${PUBLIC_HEADERS} 00748 ) 00749 if (PROJECT_IS_MODULE) 00750 if (NOT TARGET headers) 00751 add_custom_target (headers ALL) 00752 endif () 00753 add_dependencies (headers ${CONFIGURE_HEADERS_TARGET}) 00754 endif () 00755 endif () 00756 endfunction () 00757 00758 # ---------------------------------------------------------------------------- 00759 ## @brief Add library targets for the public modules in @c PROJECT_LIBRARY_DIR. 00760 # 00761 # This function configures ("builds") the library modules in the 00762 # @c PROJECT_LIBRARY_DIR that are written in a scripting language such as 00763 # Python or Perl. The names of the added library targets can be modified using 00764 # the <tt><LANG>_LIBRARY_TARGET</tt> variables, which are set to their 00765 # default values in the @c BasisSettings.cmake file. 00766 function (basis_configure_script_libraries) 00767 if (NOT IS_DIRECTORY "${PROJECT_LIBRARY_DIR}") 00768 return () 00769 endif () 00770 # Python 00771 if (PythonInterp_FOUND) 00772 set (PYTHON_EXT .py .py.in) 00773 set (PYTHON_LIB_DIRS) 00774 if (PYTHON_VERSION_MAJOR) 00775 list (APPEND PYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}/python${PYTHON_VERSION_MAJOR}") 00776 endif () 00777 list (APPEND PYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}/python") 00778 list (APPEND PYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}") 00779 else () 00780 set (PYTHON_LIB_DIRS) 00781 endif () 00782 # Jython 00783 if (JythonInterp_FOUND) 00784 set (JYTHON_EXT .py .py.in) 00785 set (JYTHON_LIB_DIRS) 00786 if (JYTHON_VERSION_MAJOR) 00787 list (APPEND JYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}/jython${JYTHON_VERSION_MAJOR}") 00788 endif () 00789 list (APPEND JYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}/jython") 00790 list (APPEND JYTHON_LIB_DIRS "${PROJECT_LIBRARY_DIR}") 00791 else () 00792 set (JYTHON_LIB_DIRS) 00793 endif () 00794 # Perl 00795 if (Perl_FOUND) 00796 set (PERL_EXT .pm .pm.in) 00797 set (PERL_LIB_DIRS) 00798 if (PERL_VERSION_MAJOR) 00799 list (APPEND PERL_LIB_DIRS "${PROJECT_LIBRARY_DIR}/perl${PERL_VERSION_MAJOR}") 00800 endif () 00801 list (APPEND PERL_LIB_DIRS "${PROJECT_LIBRARY_DIR}/perl") 00802 list (APPEND PERL_LIB_DIRS "${PROJECT_LIBRARY_DIR}") 00803 else () 00804 set (PERL_LIB_DIRS) 00805 endif () 00806 # MATLAB 00807 if (MATLAB_FOUND) 00808 set (MATLAB_EXT .m .m.in) 00809 set (MATLAB_LIB_DIRS) 00810 if (MATLAB_RELEASE) 00811 list (APPEND MATLAB_LIB_DIRS "${PROJECT_LIBRARY_DIR}/matlab/${MATLAB_RELEASE}") 00812 endif () 00813 if (MATLAB_VERSION_MAJOR) 00814 list (APPEND MATLAB_LIB_DIRS "${PROJECT_LIBRARY_DIR}/matlab${MATLAB_VERSION_MAJOR}") 00815 endif () 00816 list (APPEND MATLAB_LIB_DIRS "${PROJECT_LIBRARY_DIR}/matlab") 00817 list (APPEND MATLAB_LIB_DIRS "${PROJECT_LIBRARY_DIR}") 00818 else () 00819 set (MATLAB_LIB_DIRS) 00820 endif () 00821 # Bash 00822 if (BASH_FOUND) 00823 set (BASH_EXT .sh .sh.in) 00824 set (BASH_LIB_DIRS) 00825 if (BASH_VERSION_MAJOR) 00826 list (APPEND BASH_LIB_DIRS "${PROJECT_LIBRARY_DIR}/bash${BASH_VERSION_MAJOR}") 00827 endif () 00828 list (APPEND BASH_LIB_DIRS "${PROJECT_LIBRARY_DIR}/bash") 00829 list (APPEND BASH_LIB_DIRS "${PROJECT_LIBRARY_DIR}") 00830 else () 00831 set (BASH_LIB_DIRS) 00832 endif () 00833 # add library targets 00834 set (TARGETS) 00835 foreach (LANGUAGE IN ITEMS PYTHON JYTHON PERL MATLAB BASH) 00836 foreach (LIB_DIR IN LISTS ${LANGUAGE}_LIB_DIRS) 00837 set (EXPRESSIONS) 00838 foreach (MODULE_EXT IN LISTS ${LANGUAGE}_EXT) 00839 list (APPEND EXPRESSIONS "${LIB_DIR}/**${MODULE_EXT}") 00840 endforeach () 00841 file (GLOB_RECURSE SOURCES ${EXPRESSIONS}) 00842 basis_get_source_language (SOURCE_LANGUAGE ${SOURCES}) # in particular required to 00843 # not falsely build Jython modules 00844 # as Python library 00845 if (SOURCE_LANGUAGE MATCHES "UNKNOWN|AMBIGUOUS") 00846 message (WARNING "Failed to auto-detect scripting language of modules in ${LIB_DIR}!" 00847 " Skipping source files matching one of the extensions [${${LANGUAGE}_EXT}].") 00848 elseif (SOURCE_LANGUAGE MATCHES "${LANGUAGE}") 00849 set (TARGET_NAME "${${LANGUAGE}_LIBRARY_TARGET}") 00850 basis_add_library (${TARGET_NAME} ${EXPRESSIONS} LANGUAGE ${LANGUAGE}) 00851 basis_set_target_properties ( 00852 ${TARGET_NAME} 00853 PROPERTIES 00854 SOURCE_DIRECTORY "${LIB_DIR}" 00855 LIBRARY_OUTPUT_DIRECTORY "${BINARY_${LANGUAGE}_LIBRARY_DIR}" 00856 LIBRARY_INSTALL_DIRECTORY "${INSTALL_${LANGUAGE}_SITE_DIR}" 00857 PREFIX "" 00858 ) 00859 list (APPEND TARGETS ${TARGET_NAME}) 00860 break () 00861 endif () 00862 endforeach () 00863 endforeach () 00864 if (TARGETS) 00865 basis_make_target_uid (LIBRARY_TARGET lib) 00866 add_custom_target (${LIBRARY_TARGET} ALL) 00867 basis_add_dependencies (${LIBRARY_TARGET} ${TARGETS}) 00868 endif () 00869 endfunction () 00870 00871 # ---------------------------------------------------------------------------- 00872 ## @brief Configure root documentation files. 00873 # 00874 # The root documentation files are located in the top-level directory of the 00875 # project's source tree. These are, in particular, the 00876 # * @c AUTHORS.txt file with information on the authors of the software, 00877 # * @c COPYING.txt file with copyright and licensing information, 00878 # * @c README.txt file, 00879 # * @c INSTALL.txt file with build and installation instructions, 00880 # * @c WELCOME.txt file with text used as welcome text of the installer. 00881 # where the top-level project requires all of these files except of the 00882 # @c WELCOME.txt file which defaults to the readme file. Modules of a project 00883 # usually do not include any of these files. Otherwise, the content of the 00884 # module's documentation file is appended to the corresponding file of the 00885 # top-level project. 00886 macro (basis_configure_root_documentation_files) 00887 foreach (F AUTHORS COPYING README INSTALL WELCOME) 00888 if (EXISTS "${PROJECT_SOURCE_DIR}/${F}.txt") 00889 set (PROJECT_${F}_FILE "${PROJECT_SOURCE_DIR}/${F}.txt") 00890 if (PROJECT_IS_MODULE) 00891 file (READ "${PROJECT_${F}_FILE}" T) 00892 file ( 00893 APPEND "${BASIS_PROJECT_${F}_FILE}" 00894 "\n\n\n" 00895 "------------------------------------------------------------------------------\n" 00896 "${PROJECT_NAME} Module\n" 00897 "------------------------------------------------------------------------------\n" 00898 "${T}" 00899 ) 00900 else () 00901 set (BASIS_PROJECT_${F}_FILE "${PROJECT_BINARY_DIR}/${F}.txt") 00902 # do not use configure_file() to copy the file, otherwise CMake will 00903 # update the build system only because we modified this file in the if-clause 00904 execute_process (COMMAND "${CMAKE_COMMAND}" -E copy "${PROJECT_${F}_FILE}" "${BASIS_PROJECT_${F}_FILE}") 00905 # use extension on Windows, but leave it out on Unix 00906 get_filename_component (N "${F}" NAME_WE) 00907 get_filename_component (E "${F}" EXT) 00908 if (WIN32) 00909 if (NOT E) 00910 set (E ".txt") 00911 endif () 00912 else () 00913 if ("${E}" STREQUAL ".txt") 00914 set (E "") 00915 endif () 00916 endif () 00917 set (N "${N}${E}") 00918 # install file 00919 if (F MATCHES "COPYING") 00920 install ( 00921 FILES "${PROJECT_BINARY_DIR}/${F}.txt" 00922 DESTINATION "${INSTALL_DOC_DIR}" 00923 RENAME "${N}" 00924 OPTIONAL 00925 ) 00926 endif () 00927 endif () 00928 elseif (NOT F MATCHES "WELCOME" AND NOT PROJECT_IS_MODULE) 00929 message (FATAL_ERROR "Project requires a ${F}.txt file in ${PROJECT_SOURCE_DIR}!") 00930 endif () 00931 endforeach () 00932 set (PROJECT_LICENSE_FILE "${PROJECT_COPYING_FILE}") # compatibility with Slicer 00933 endmacro () 00934 00935 # ---------------------------------------------------------------------------- 00936 ## @brief Get build time stamp. 00937 # 00938 # The build time stamp is used as an alternative to the version and revision 00939 # information in @c PROJECT_RELEASE if version is invalid, i.e., set to 0.0.0 00940 # as is the case for development branches, and now revision from a revision 00941 # control system is available. 00942 function (basis_get_build_timestamp TIMESTAMP) 00943 if (WIN32) 00944 execute_process ( 00945 COMMAND "${BASIS_MODULE_PATH}/buildtimestamp.cmd" 00946 RESULT_VARIABLE RT 00947 OUTPUT_VARIABLE BUILD_TIMESTAMP 00948 ERROR_QUIET 00949 OUTPUT_STRIP_TRAILING_WHITESPACE 00950 ) 00951 else () 00952 execute_process ( 00953 COMMAND "date" -u "+%Y.%m.%d (%H:%M UTC)" 00954 RESULT_VARIABLE RT 00955 OUTPUT_VARIABLE BUILD_TIMESTAMP 00956 ERROR_QUIET 00957 OUTPUT_STRIP_TRAILING_WHITESPACE 00958 ) 00959 endif () 00960 if (RT EQUAL 0) 00961 set (${TIMESTAMP} "${BUILD_TIMESTAMP}" PARENT_SCOPE) 00962 else () 00963 set (${TIMESTAMP} PARENT_SCOPE) 00964 endif () 00965 endfunction () 00966 00967 # ---------------------------------------------------------------------------- 00968 ## @brief Initialize project, calls CMake's project() command. 00969 # 00970 # @sa basis_project() 00971 # @sa basis_project_impl() 00972 # 00973 # @returns Sets the following non-cached CMake variables: 00974 # @retval PROJECT_REVISION Revision number of Subversion controlled 00975 # source tree or 0 if the source tree is 00976 # not under revision control. 00977 # @retval PROJECT_RELEASE A string of project version and revision 00978 # that can be used for the output of 00979 # version information. The format of this 00980 # string is either one of the following: 00981 # - "v1.0 (r42)" 00982 # - "v1.0.5 (r50)" 00983 # - "v1.0" (if revision unknown) 00984 # - "r42" (if version is 0.0.0) 00985 # - "" (otherwise) 00986 macro (basis_project_initialize) 00987 # -------------------------------------------------------------------------- 00988 # CMake version and policies 00989 cmake_minimum_required (VERSION 2.8.4) 00990 00991 # Add policies introduced with CMake versions newer than the one specified 00992 # above. These policies would otherwise trigger a policy not set warning by 00993 # newer CMake versions. 00994 00995 if (POLICY CMP0016) 00996 cmake_policy (SET CMP0016 NEW) 00997 endif () 00998 00999 if (POLICY CMP0017) 01000 cmake_policy (SET CMP0017 NEW) 01001 endif () 01002 01003 # -------------------------------------------------------------------------- 01004 # reset 01005 01006 # only set if not set by top-level project before configuring a module 01007 basis_set_if_empty (PROJECT_IS_MODULE FALSE) 01008 # set only by basis_use_package() to TRUE such that functions such as 01009 # the overwritten (basis_)link_directories() command or add_library() 01010 # know that these directories/targets belong to an external project which 01011 # is part of the same superbuild. otherwise, it shall be FALSE. 01012 set (BUNDLE_PROJECT FALSE) 01013 01014 # hide it here to avoid that it shows up in the GUI on error 01015 set (CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE INTERNAL "" FORCE) 01016 01017 # -------------------------------------------------------------------------- 01018 # project meta-data 01019 if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/BasisProject.cmake") 01020 set (BASIS_basis_project_CALLED FALSE) 01021 include ("${CMAKE_CURRENT_SOURCE_DIR}/BasisProject.cmake") 01022 if (NOT BASIS_basis_project_CALLED) 01023 message (FATAL_ERROR "Missing basis_project() command in BasisProject.cmake!") 01024 endif () 01025 else () 01026 message (FATAL_ERROR "Missing BasisProject.cmake file!") 01027 endif () 01028 01029 # -------------------------------------------------------------------------- 01030 # project() 01031 project ("${PROJECT_NAME}") 01032 01033 # work-around for issue with CMAKE_PROJECT_NAME always being set to 'Project' 01034 if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}") 01035 set_property (CACHE CMAKE_PROJECT_NAME PROPERTY VALUE "${PROJECT_NAME}") 01036 endif () 01037 01038 # get revision of project 01039 # 01040 # Note: Use revision when branch, i.e., either trunk, a branch, or a tag 01041 # has been modified last. For tags, this should in particular 01042 # correspond to the revision when the tag was created. 01043 if (BASIS_REVISION_INFO) 01044 basis_svn_get_last_changed_revision ("${PROJECT_SOURCE_DIR}" PROJECT_REVISION) 01045 else () 01046 set (PROJECT_REVISION 0) 01047 endif () 01048 01049 # extract version numbers from version string 01050 basis_version_numbers ( 01051 "${PROJECT_VERSION}" 01052 PROJECT_VERSION_MAJOR 01053 PROJECT_VERSION_MINOR 01054 PROJECT_VERSION_PATCH 01055 ) 01056 01057 set (PROJECT_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") 01058 01059 # version information string 01060 if (PROJECT_VERSION MATCHES "^0+(\\.0+)?(\\.0+)?") 01061 if (PROJECT_REVISION) 01062 set (PROJECT_RELEASE "r${PROJECT_REVISION}") 01063 else () 01064 basis_get_build_timestamp (BUILD_TIMESTAMP) 01065 if (BUILD_TIMESTAMP) 01066 set (PROJECT_RELEASE "b${BUILD_TIMESTAMP}") 01067 else () 01068 set (PROJECT_RELEASE "") 01069 endif () 01070 endif () 01071 else () 01072 set (PROJECT_RELEASE "v${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") 01073 if (PROJECT_VERSION_PATCH) 01074 set (PROJECT_RELEASE "${PROJECT_RELEASE}.${PROJECT_VERSION_PATCH}") 01075 endif () 01076 if (PROJECT_REVISION) 01077 set (PROJECT_RELEASE "${PROJECT_RELEASE} (r${PROJECT_REVISION})") 01078 endif () 01079 endif () 01080 01081 set (PROJECT_VERSION_AND_REVISION "${PROJECT_RELEASE}") # backwards compatibility to BASIS < 1.3 01082 01083 # version number for use in Perl modules 01084 set (PROJECT_VERSION_PERL "${PROJECT_VERSION_MAJOR}") 01085 if (PROJECT_VERSION_MAJOR LESS 10) 01086 set (PROJECT_VERSION_PERL "${PROJECT_VERSION_PERL}.0${PROJECT_VERSION_MINOR}") 01087 else () 01088 set (PROJECT_VERSION_PERL "${PROJECT_VERSION_PERL}.${PROJECT_VERSION_MINOR}") 01089 endif () 01090 if (PROJECT_VERSION_PATCH LESS 10) 01091 set (PROJECT_VERSION_PERL "${PROJECT_VERSION_PERL}_0${PROJECT_VERSION_PATCH}") 01092 else () 01093 set (PROJECT_VERSION_PERL "${PROJECT_VERSION_PERL}_${PROJECT_VERSION_PATCH}") 01094 endif () 01095 01096 # print project information 01097 if (NOT PROJECT_IS_MODULE) 01098 message (STATUS "${PROJECT_NAME} ${PROJECT_RELEASE}") 01099 endif () 01100 01101 # -------------------------------------------------------------------------- 01102 # reset project properties - *after* PROJECT_NAME was set 01103 01104 # The following variables are used across BASIS macros and functions. They 01105 # in particular remember information added by one function or macro which 01106 # is required by another function or macro. 01107 # 01108 # These variables need to be properties such that they can be set in 01109 # subdirectories. Moreover, they have to be assigned with the project's 01110 # root source directory such that a top-level project's properties are restored 01111 # after this subproject is finalized such that the top-level project itself can 01112 # be finalized properly. 01113 # 01114 # Attention: In particular the IMPORTED_* properties are already used 01115 # during the import of targets when including the use files of 01116 # external packages. Hence, this property has to be reset before. 01117 01118 # see basis_add_imported_target() 01119 basis_set_project_property (PROPERTY IMPORTED_TARGETS "") 01120 basis_set_project_property (PROPERTY IMPORTED_TYPES "") 01121 basis_set_project_property (PROPERTY IMPORTED_LOCATIONS "") 01122 basis_set_project_property (PROPERTY IMPORTED_RANKS "") 01123 # see basis_include_directories() 01124 basis_set_project_property (PROPERTY PROJECT_INCLUDE_DIRS "") 01125 # see basis_link_directories() 01126 basis_set_project_property (PROPERTY PROJECT_LINK_DIRS "") 01127 basis_set_project_property (PROPERTY BUNDLE_LINK_DIRS "") 01128 # see add_executable(), add_library() 01129 basis_set_project_property (PROPERTY TARGETS "") 01130 # see basis_add_*() functions 01131 basis_set_project_property (PROPERTY EXPORT_TARGETS "") 01132 basis_set_project_property (PROPERTY INSTALL_EXPORT_TARGETS "") 01133 basis_set_project_property (PROPERTY CUSTOM_EXPORT_TARGETS "") 01134 basis_set_project_property (PROPERTY TEST_EXPORT_TARGETS "") 01135 basis_set_project_property (PROPERTY PROJECT_USES_CXX_UTILITIES FALSE) 01136 basis_set_project_property (PROPERTY PROJECT_USES_PYTHON_UTILITIES FALSE) 01137 basis_set_project_property (PROPERTY PROJECT_USES_PERL_UTILITIES FALSE) 01138 basis_set_project_property (PROPERTY PROJECT_USES_BASH_UTILITIES FALSE) 01139 # yet unused 01140 basis_set_project_property (PROPERTY PROJECT_USES_JAVA_UTILITIES FALSE) 01141 basis_set_project_property (PROPERTY PROJECT_USES_MATLAB_UTILITIES FALSE) 01142 endmacro () 01143 01144 # ---------------------------------------------------------------------------- 01145 ## @brief Initialize project settings. 01146 macro (basis_initialize_settings) 01147 # -------------------------------------------------------------------------- 01148 # configure BASIS directory structure 01149 include ("${BASIS_MODULE_PATH}/DirectoriesSettings.cmake") 01150 configure_file ( 01151 "${BASIS_MODULE_PATH}/Directories.cmake.in" 01152 "${BINARY_CONFIG_DIR}/Directories.cmake" 01153 @ONLY 01154 ) 01155 # -------------------------------------------------------------------------- 01156 # include project specific settings 01157 # 01158 # This file enables the project to modify the default behavior of BASIS, 01159 # but only if BASIS allows so as the BASIS project settings are included 01160 # afterwards. 01161 if (EXISTS "${PROJECT_CONFIG_DIR}/Settings.cmake.in") 01162 configure_file ( 01163 "${PROJECT_CONFIG_DIR}/Settings.cmake.in" 01164 "${BINARY_CONFIG_DIR}/Settings.cmake" 01165 @ONLY 01166 ) 01167 include ("${BINARY_CONFIG_DIR}/Settings.cmake" NO_POLICY_SCOPE) 01168 else () 01169 include ("${PROJECT_CONFIG_DIR}/Settings.cmake" NO_POLICY_SCOPE OPTIONAL) 01170 endif () 01171 # -------------------------------------------------------------------------- 01172 # configure project specific BASIS settings 01173 set (_BASIS_NAMESPACE_CMAKE "${PROJECT_PACKAGE_L}") 01174 if (PROJECT_IS_SUBPROJECT OR PROJECT_IS_MODULE) 01175 set (_NAMESPACE_CMAKE "${_BASIS_NAMESPACE_CMAKE}.${PROJECT_NAME_L}") 01176 else () 01177 set (_NAMESPACE_CMAKE "${_BASIS_NAMESPACE_CMAKE}") 01178 endif () 01179 # default namespaces used for supported programming languages 01180 foreach (_L IN LISTS BASIS_LANGUAGES_U) 01181 if (_L MATCHES "PERL") 01182 set (_NAMESPACE_${_L} "${PROJECT_PACKAGE}") 01183 else () 01184 set (_NAMESPACE_${_L} "${PROJECT_PACKAGE_L}") 01185 endif () 01186 endforeach () 01187 if (PROJECT_IS_SUBPROJECT) 01188 foreach (_L IN LISTS BASIS_LANGUAGES_U) 01189 if (_L MATCHES "PERL") 01190 set (_NAMESPACE_${_L} "${_NAMESPACE_${_L}}${BASIS_NAMESPACE_DELIMITER_${_L}}${PROJECT_NAME}") 01191 elseif (NOT _L MATCHES "CMAKE") 01192 set (_NAMESPACE_${_L} "${_NAMESPACE_${_L}}${BASIS_NAMESPACE_DELIMITER_${_L}}${PROJECT_NAME_L}") 01193 endif () 01194 endforeach () 01195 endif () 01196 # package configuration 01197 set (_BASIS_PROJECT_PACKAGE_CONFIG_PREFIX "${BASIS_PROJECT_PACKAGE}") 01198 if (PROJECT_IS_SUBPROJECT OR PROJECT_IS_MODULE) 01199 set (_PROJECT_PACKAGE_CONFIG_PREFIX "${_BASIS_PROJECT_PACKAGE_CONFIG_PREFIX}${PROJECT_NAME}") 01200 else () 01201 set (_PROJECT_PACKAGE_CONFIG_PREFIX "${_BASIS_PROJECT_PACKAGE_CONFIG_PREFIX}") 01202 endif () 01203 if (PROJECT_PACKAGE_VENDOR) 01204 set (_BASIS_PROJECT_PACKAGE_UID "${PROJECT_PACKAGE_VENDOR}-${PROJECT_PACKAGE}-${PROJECT_VERSION}") 01205 else () 01206 set (_BASIS_PROJECT_PACKAGE_UID "${PROJECT_PACKAGE}-${PROJECT_VERSION}") 01207 endif () 01208 # configure settings file which contains the documentation of these variables 01209 configure_file ( 01210 "${BASIS_MODULE_PATH}/ProjectSettings.cmake.in" 01211 "${BINARY_CONFIG_DIR}/ProjectSettings.cmake" 01212 @ONLY 01213 ) 01214 # unset local variables 01215 foreach (_L IN LISTS BASIS_LANGUAGES_U) 01216 unset (_BASIS_NAMESPACE_${_L}) 01217 unset (_NAMESPACE_${_L}) 01218 endforeach () 01219 unset (_BASIS_PROJECT_PACKAGE_UID) 01220 unset (_BASIS_PROJECT_PACKAGE_CONFIG_PREFIX) 01221 unset (_PROJECT_PACKAGE_CONFIG_PREFIX) 01222 unset (_L) 01223 # include configured project specific BASIS settings 01224 include ("${BINARY_CONFIG_DIR}/ProjectSettings.cmake" NO_POLICY_SCOPE) 01225 endmacro () 01226 01227 # ---------------------------------------------------------------------------- 01228 ## @brief Find packages this project depends on. 01229 macro (basis_find_packages) 01230 set (BASIS_SET_TARGET_PROPERTIES_IMPORT TRUE) # see set_target_properties() 01231 01232 # Attention: This function is used before the Directories.cmake.in and 01233 # Settings.cmake.in files were configured and included. 01234 set (PROJECT_CONFIG_DIR "${CMAKE_CURRENT_SOURCE_DIR}/config") 01235 01236 # -------------------------------------------------------------------------- 01237 # add project config directory to CMAKE_MODULE_PATH 01238 set (CMAKE_MODULE_PATH "${PROJECT_CONFIG_DIR}" ${CMAKE_MODULE_PATH}) 01239 01240 # -------------------------------------------------------------------------- 01241 # Depends.cmake 01242 01243 # This file is in particular of interest if a dependency is required if 01244 # certain modules are enabled, but not others. 01245 01246 # Attention: This function is used before the Directories.cmake.in and 01247 # Settings.cmake.in files were configured and included. 01248 include ("${PROJECT_CONFIG_DIR}/Depends.cmake" OPTIONAL) 01249 01250 # -------------------------------------------------------------------------- 01251 # required dependencies 01252 foreach (P IN LISTS PROJECT_DEPENDS) 01253 basis_find_package ("${P}" REQUIRED) 01254 basis_use_package ("${P}" REQUIRED) 01255 endforeach () 01256 01257 # -------------------------------------------------------------------------- 01258 # optional dependencies 01259 foreach (P IN LISTS PROJECT_OPTIONAL_DEPENDS) 01260 basis_find_package ("${P}" QUIET) 01261 basis_use_package ("${P}") 01262 endforeach () 01263 01264 # -------------------------------------------------------------------------- 01265 # test dependencies 01266 if (BUILD_TESTING) 01267 # required test dependencies 01268 foreach (P IN LISTS PROJECT_TEST_DEPENDS) 01269 basis_find_package ("${P}") # do not use REQUIRED here to be able to show 01270 basis_use_package ("${P}") # error message below 01271 basis_tokenize_dependency ("${P}" P VER CMPS) 01272 string (TOUPPER "${P}" U) 01273 if (NOT ${P}_FOUND AND NOT ${U}_FOUND) 01274 message (FATAL_ERROR "Could not find package ${P}! It is required by " 01275 "the tests of ${PROJECT_NAME}. Either specify " 01276 "package location manually and try again or " 01277 "disable testing by setting BUILD_TESTING to OFF.") 01278 01279 endif () 01280 unset (U) 01281 unset (VER) 01282 unset (CMPS) 01283 endforeach () 01284 # optional test dependencies 01285 foreach (P IN LISTS PROJECT_OPTIONAL_TEST_DEPENDS) 01286 basis_find_package ("${P}" QUIET) 01287 basis_use_package ("${P}") 01288 endforeach () 01289 endif () 01290 01291 unset (P) 01292 01293 set (BASIS_SET_TARGET_PROPERTIES_IMPORT FALSE) # see set_target_properties() 01294 endmacro () 01295 01296 # ============================================================================ 01297 # finalization 01298 # ============================================================================ 01299 01300 # ---------------------------------------------------------------------------- 01301 ## @brief Add installation rules for public header files. 01302 macro (basis_install_public_headers) 01303 # subdirectory of basis.h header file 01304 basis_library_prefix (_BASIS_H_PREFIX CXX) 01305 # install public header files from source tree 01306 if (EXISTS "${PROJECT_INCLUDE_DIR}") 01307 basis_install_directory ("${PROJECT_INCLUDE_DIR}" "${INSTALL_INCLUDE_DIR}" PATTERN "*.in" EXCLUDE) 01308 endif () 01309 # install configured public header files, excluding BASIS utilities 01310 file (GLOB_RECURSE _CONFIGURED_PUBLIC_HEADERS "${BINARY_INCLUDE_DIR}/*") 01311 list (REMOVE_ITEM _CONFIGURED_PUBLIC_HEADERS "${BINARY_INCLUDE_DIR}/${_BASIS_H_PREFIX}basis.h") 01312 if (_CONFIGURED_PUBLIC_HEADERS) 01313 basis_install_directory ( 01314 "${BINARY_INCLUDE_DIR}" "${INSTALL_INCLUDE_DIR}" 01315 REGEX "/${_BASIS_H_PREFIX}basis\\.h$" EXCLUDE # BASIS utilities header only installed 01316 # below if included by any other public header 01317 PATTERN "*.cmake" EXCLUDE # e.g., <Name>PublicHeaders.cmake file, 01318 PATTERN "*.cmake.*" EXCLUDE # see basis_configure_public_headers() 01319 ) 01320 endif () 01321 # "parse" public header files to check if C++ BASIS utilities are included 01322 if (NOT BASIS_INSTALL_PUBLIC_HEADERS_OF_CXX_UTILITIES) 01323 # get list of all public header files of project 01324 set (_PUBLIC_HEADERS) 01325 if (NOT BASIS_CONFIGURE_INCLUDES) 01326 file (GLOB_RECURSE _PUBLIC_HEADERS "${PROJECT_INCLUDE_DIR}/*.h") 01327 endif () 01328 list (APPEND _PUBLIC_HEADERS ${_CONFIGURED_PUBLIC_HEADERS}) 01329 # check include statements of each public header file 01330 foreach (_A IN LISTS _PUBLIC_HEADERS) 01331 basis_utilities_check (_B "${_A}" CXX) 01332 if (_B) 01333 set (BASIS_INSTALL_PUBLIC_HEADERS_OF_CXX_UTILITIES TRUE) 01334 break () 01335 endif () 01336 endforeach () 01337 unset (_PUBLIC_HEADERS) 01338 unset (_A) 01339 unset (_B) 01340 endif () 01341 unset (_CONFIGURED_PUBLIC_HEADERS) 01342 # install public header of BASIS utilities (optional) 01343 if (BASIS_INSTALL_PUBLIC_HEADERS_OF_CXX_UTILITIES) 01344 install ( 01345 FILES "${BINARY_INCLUDE_DIR}/${_BASIS_H_DIR}/basis.h" 01346 DESTINATION "${INSTALL_INCLUDE_DIR}/${_BASIS_H_PREFIX}" 01347 COMPONENT "${BASIS_LIBRARY_COMPONENT}" 01348 ) 01349 endif () 01350 endmacro () 01351 01352 01353 ## @} 01354 # end of Doxygen group 01355 01356 # ============================================================================ 01357 # root CMakeLists.txt implementation 01358 # ============================================================================ 01359 01360 # ---------------------------------------------------------------------------- 01361 ## @brief Implementation of root <tt>CMakeLists.txt</tt> file of BASIS project. 01362 # 01363 # This macro implements the entire logic of the top-level 01364 # <tt>CMakeLists.txt</tt> file. At first, the project is initialized and the 01365 # BASIS settings configured using the project information given in the 01366 # <tt>BasisProject.cmake</tt> file which must be located in the same directory. 01367 # The, the code in the <tt>CMakeLists.txt</tt> files in the subdirectories is 01368 # executed in order. At the end, the configuration of the build system is 01369 # finalized, including in particular also the addition of custom build targets 01370 # which perform the actual build of custom build targets such as the ones build 01371 # using the MATLAB Compiler. 01372 # 01373 # @sa BasisProject.cmake 01374 # @sa basis_project() 01375 # 01376 # @ingroup CMakeAPI 01377 macro (basis_project_impl) 01378 # -------------------------------------------------------------------------- 01379 # set CMAKE_INSTALL_PREFIX to cached invalid value to have 01380 # basis_initialize_settings() set it to BASIS's default rather than CMake's 01381 # default even if this is not the first configure run because a previous 01382 # one was interrupted by an error such as a requird package that was not found 01383 if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 01384 set (CMAKE_INSTALL_PREFIX "" CACHE INTERNAL "Installation prefix." FORCE) 01385 endif () 01386 01387 # -------------------------------------------------------------------------- 01388 # initialize project 01389 basis_project_initialize () 01390 01391 # -------------------------------------------------------------------------- 01392 # load information of modules 01393 if (NOT PROJECT_IS_MODULE) 01394 basis_project_modules () 01395 endif () 01396 01397 if (BASIS_DEBUG) 01398 basis_dump_variables ("${PROJECT_BINARY_DIR}/VariablesAfterDetectionOfModules.cmake") 01399 endif () 01400 01401 # -------------------------------------------------------------------------- 01402 # initialize Slicer module 01403 basis_slicer_module_initialize () 01404 01405 # -------------------------------------------------------------------------- 01406 # Python 01407 01408 # In case of a Slicer Extension, the UseSlicer.cmake file of Slicer (>= 4.0) 01409 # will set PYTHON_EXECUTABLE and requires us not to set this variable before 01410 # the UseSlicer.cmake file has been included. Hence, we set this variable 01411 # here only if it has not been set by Slicer, but before any PythonInterp 01412 # dependency declared by this package such that the Python interpreter 01413 # configured while building BASIS is used to avoid conflicts of different 01414 # versions used to compile the Python utilities (if BASIS_COMPILE_SCRIPTS 01415 # was set to ON) and the one used to configure/build this package. 01416 # 01417 # Note: The PYTHON_EXECUTABLE variable has to be cached such that 01418 # PythonInterp.cmake does not look for the interpreter itself. 01419 if (BASIS_PYTHON_EXECUTABLE) 01420 set ( 01421 PYTHON_EXECUTABLE 01422 "${BASIS_PYTHON_EXECUTABLE}" 01423 CACHE PATH 01424 "The Python interpreter." 01425 ) 01426 mark_as_advanced (PYTHON_EXECUTABLE) 01427 endif () 01428 # Note that PERL_EXECUTABLE and BASH_EXECUTABLE are set in BASISUse.cmake. 01429 01430 # -------------------------------------------------------------------------- 01431 # find packages 01432 01433 # any package use file must be included after PROJECT_NAME was set as the 01434 # imported targets are added to the <Project>_TARGETS property using 01435 # basis_set_project_property() in add_executable() and add_library() 01436 basis_use_package (BASIS) 01437 basis_find_packages () 01438 01439 if (BASIS_DEBUG) 01440 basis_dump_variables ("${PROJECT_BINARY_DIR}/VariablesAfterFindDependencies.cmake") 01441 endif () 01442 01443 # -------------------------------------------------------------------------- 01444 # get interpreter versions - set to invalid version if not available 01445 if (NOT PYTHON_VERSION_STRING) 01446 basis_get_python_version () 01447 endif () 01448 if (NOT JYTHON_VERSION_STRING) 01449 basis_get_jython_version () 01450 endif () 01451 if (NOT PERL_VERSION_STRING) 01452 basis_get_perl_version () 01453 endif () 01454 if (NOT BASH_VERSION_STRING) 01455 basis_get_bash_version () 01456 endif () 01457 if (NOT MATLAB_VERSION_STRING) 01458 basis_get_matlab_version () 01459 endif () 01460 01461 if (PYTHON_EXECUTABLE AND PYTHON_VERSION_MAJOR EQUAL 0 OR (PYTHON_VERSION_MAJOR EQUAL 1 AND PYTHON_VERSION_MINOR EQUAL 4)) 01462 message (WARNING "Failed to determine Python version! Check if you can run \"${PYTHON_EXECUTABLE} -E\" in a Terminal.") 01463 endif () 01464 if (JYTHON_EXECUTABLE AND JYTHON_VERSION_MAJOR EQUAL 0) 01465 message (WARNING "Failed to determine Jython version! Check if you can run \"${JYTHON_EXECUTABLE}\".") 01466 endif () 01467 if (PERL_EXECUTABLE AND PERL_VERSION_MAJOR EQUAL 0) 01468 message (WARNING "Failed to determine Perl version! Check if you can run \"${PERL_EXECUTABLE}\".") 01469 endif () 01470 if (BASH_EXECUTABLE AND BASH_VERSION_MAJOR EQUAL 0) 01471 message (WARNING "Failed to determine Bash version! Check if you can run \"${BASH_EXECUTABLE}\".") 01472 endif () 01473 if (MATLAB_EXECUTABLE AND MATLAB_VERSION_MAJOR EQUAL 0) 01474 message (WARNING "Failed to determine MATLAB version! Check if you can run \"${MATLAB_EXECUTABLE} -nodesktop -nosplash -r 'version,quit force'\" and try again.") 01475 endif () 01476 01477 # -------------------------------------------------------------------------- 01478 # initialize settings 01479 basis_initialize_settings () 01480 01481 # -------------------------------------------------------------------------- 01482 # assertions 01483 basis_buildtree_asserts () 01484 basis_installtree_asserts () 01485 01486 # -------------------------------------------------------------------------- 01487 # defaul script configuration - see basis_configure_script() 01488 set (BASIS_SCRIPT_CONFIG_FILE "${BINARY_CONFIG_DIR}/BasisScriptConfig.cmake") 01489 configure_file ("${BASIS_MODULE_PATH}/ScriptConfig.cmake.in" "${BASIS_SCRIPT_CONFIG_FILE}" @ONLY) 01490 if (EXISTS "${PROJECT_CONFIG_DIR}/ScriptConfig.cmake.in") 01491 configure_file ("${PROJECT_CONFIG_DIR}/ScriptConfig.cmake.in" "${BINARY_CONFIG_DIR}/ScriptConfig.cmake" @ONLY) 01492 endif () 01493 01494 # -------------------------------------------------------------------------- 01495 # root documentation files 01496 basis_configure_root_documentation_files () 01497 01498 # -------------------------------------------------------------------------- 01499 # enable testing 01500 if (NOT PROJECT_IS_MODULE) 01501 include ("${BASIS_MODULE_PATH}/BasisTest.cmake") 01502 basis_disable_testing_if_no_tests () 01503 if (BUILD_TESTING AND NOT EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake") 01504 message (WARNING "Missing CTestConfig.cmake file in top directory of source tree!" 01505 " You will not be able to submit test results to the CDash dashboard.") 01506 endif () 01507 endif () 01508 01509 # -------------------------------------------------------------------------- 01510 # public header files and script libraries 01511 01512 # dump currently defined CMake variables such that these can be used to 01513 # configure the .in public header and module files during the build step 01514 basis_dump_variables ("${PROJECT_BINARY_DIR}/BasisCache.txt") 01515 basis_include_directories (BEFORE "${BINARY_INCLUDE_DIR}" 01516 "${PROJECT_INCLUDE_DIR}" 01517 "${PROJECT_CODE_DIR}") 01518 basis_configure_public_headers () 01519 basis_configure_script_libraries () 01520 01521 # -------------------------------------------------------------------------- 01522 # subdirectories 01523 if (BASIS_DEBUG) 01524 basis_dump_variables ("${PROJECT_BINARY_DIR}/VariablesAfterInitialization.cmake") 01525 endif () 01526 01527 # build modules 01528 if (NOT PROJECT_IS_MODULE) 01529 foreach (MODULE IN LISTS PROJECT_MODULES_ENABLED) 01530 message (STATUS "Configuring module ${MODULE}...") 01531 set (PROJECT_IS_MODULE TRUE) 01532 add_subdirectory ("${MODULE_${MODULE}_SOURCE_DIR}" "${MODULE_${MODULE}_BINARY_DIR}") 01533 set (PROJECT_IS_MODULE FALSE) 01534 message (STATUS "Configuring module ${MODULE}... - done") 01535 endforeach () 01536 endif () 01537 01538 # add default project directories to list of subdirectories 01539 # (in reverse order always at beginning of list) 01540 if (BUILD_EXAMPLE) 01541 list (INSERT PROJECT_SUBDIRS 0 "${PROJECT_EXAMPLE_DIR}") 01542 endif () 01543 if (BUILD_TESTING) 01544 list (INSERT PROJECT_SUBDIRS 0 "${PROJECT_TESTING_DIR}") 01545 endif () 01546 list (INSERT PROJECT_SUBDIRS 0 "${PROJECT_DATA_DIR}") 01547 list (INSERT PROJECT_SUBDIRS 0 "${PROJECT_CODE_DIR}") 01548 01549 # process subdirectories 01550 foreach (SUBDIR IN LISTS PROJECT_SUBDIRS) 01551 if (IS_DIRECTORY "${SUBDIR}") 01552 add_subdirectory ("${SUBDIR}") 01553 endif () 01554 endforeach () 01555 01556 if (BASIS_DEBUG) 01557 basis_dump_variables ("${PROJECT_BINARY_DIR}/VariablesAfterSubdirectories.cmake") 01558 endif () 01559 01560 # -------------------------------------------------------------------------- 01561 # write convenience file to setup MATLAB environment 01562 if (MATLAB_FOUND) 01563 basis_create_addpaths_mfile () 01564 endif () 01565 01566 # -------------------------------------------------------------------------- 01567 # copy project properties of modules 01568 if (NOT PROJECT_IS_MODULE) 01569 # copy properties of modules 01570 foreach (M IN LISTS PROJECT_MODULES_ENABLED) 01571 foreach (P IN ITEMS IMPORTED_TARGETS 01572 IMPORTED_TYPES 01573 IMPORTED_LOCATIONS 01574 IMPORTED_RANKS 01575 PROJECT_INCLUDE_DIRS 01576 PROJECT_LINK_DIRS 01577 BUNDLE_LINK_DIRS 01578 TARGETS 01579 CUSTOM_EXPORT_TARGETS 01580 TEST_EXPORT_TARGETS) 01581 basis_get_project_property (V ${M} ${P}) 01582 basis_set_project_property (APPEND PROPERTY ${P} ${V}) 01583 endforeach () 01584 endforeach () 01585 foreach (L IN ITEMS CXX PYTHON PERL BASH) 01586 foreach (M IN LISTS PROJECT_MODULES_ENABLED) 01587 basis_get_project_property (P ${M} PROJECT_USES_${L}_UTILITIES) 01588 if (P) 01589 basis_set_project_property (PROPERTY PROJECT_USES_${L}_UTILITIES TRUE) 01590 break () 01591 endif () 01592 endforeach () 01593 endforeach () 01594 endif () 01595 01596 # -------------------------------------------------------------------------- 01597 # finalize custom targets 01598 if (NOT PROJECT_IS_MODULE OR PROJECT_IS_SUBPROJECT) 01599 # configure the BASIS utilities 01600 basis_configure_utilities () 01601 # add missing build commands for custom targets 01602 basis_finalize_targets () 01603 # add build target for missing __init__.py files of Python package 01604 basis_add_init_py_target () 01605 endif () 01606 01607 # -------------------------------------------------------------------------- 01608 # add installation rules for public headers 01609 basis_install_public_headers () 01610 01611 # -------------------------------------------------------------------------- 01612 # generate configuration files 01613 include ("${BASIS_MODULE_PATH}/GenerateConfig.cmake") 01614 01615 # ---------------------------------------------------------------------------- 01616 # change log 01617 basis_add_changelog () 01618 01619 # -------------------------------------------------------------------------- 01620 # build/install package documentation 01621 # 01622 # This is done after all files which may be interesting for inclusion 01623 # in the documentation are generated. In particular, this has to be done 01624 # after the configuration of the BASIS utilities. 01625 if (EXISTS "${PROJECT_DOC_DIR}" AND BUILD_DOCUMENTATION) 01626 add_subdirectory ("${PROJECT_DOC_DIR}") 01627 endif () 01628 01629 # -------------------------------------------------------------------------- 01630 # package software 01631 include ("${BASIS_MODULE_PATH}/BasisPack.cmake") 01632 01633 # -------------------------------------------------------------------------- 01634 # add installation rule to register package with CMake 01635 if (BASIS_REGISTER AND NOT PROJECT_IS_MODULE AND PROJECT_VERSION VERSION_GREATER 0.0.0) 01636 basis_register_package () 01637 endif () 01638 01639 # -------------------------------------------------------------------------- 01640 # uninstaller 01641 if (NOT PROJECT_IS_MODULE) 01642 # add uninstall target 01643 basis_add_uninstall () 01644 # add code to generate uninstaller at the end of the installation 01645 # 01646 # Attention: This must be done at last and using a add_subdirectory() call 01647 # such that the code is executed at last by the root cmake_install.cmake! 01648 add_subdirectory ("${BASIS_MODULE_PATH}/uninstall" "${PROJECT_BINARY_DIR}/uninstall") 01649 endif () 01650 01651 if (BASIS_DEBUG) 01652 basis_dump_variables ("${PROJECT_BINARY_DIR}/VariablesAfterFinalization.cmake") 01653 endif () 01654 endmacro ()