1 # ============================================================================ 2 # Copyright (c) 2011-2012 University of Pennsylvania 3 # Copyright (c) 2013-2016 Andreas Schuh 6 # See COPYING file for license information or visit 7 # https://cmake-basis.github.io/download.html#license 8 # ============================================================================ 10 ############################################################################## 11 # @file UtilitiesTools.cmake 12 # @brief CMake functions related to configuration of BASIS utilities. 15 ############################################################################## 17 ## @addtogroup CMakeUtilities 21 # ============================================================================ 22 # auto-detect which utilities are used 23 # ============================================================================ 25 # ---------------------------------------------------------------------------- 26 ## @brief Check whether the BASIS utilities are used within a given source file. 28 # This function matches the source code against specific import patterns which 29 # are all valid imports of the BASIS utilities for the respective programming 30 # language of the specified file. If the BASIS utilities are used within the 31 # specified source file, the variable named @p VAR is set to @c TRUE. 32 # Otherwise, it is set to @c FALSE. 34 # @param [out] VAR Whether the BASIS utilites are used. 35 # @param [in] SOURCE_FILE Path of source file to check. 36 # @param [in] ARGN Source code language. If not specified, the 37 # programming language is determined automatically. 39 set (UTILITIES_USED FALSE)
45 message (FATAL_ERROR "Too many arguments given!
") 47 # -------------------------------------------------------------------------- 48 # make file path absolute and append .in suffix if necessary 49 get_filename_component (SOURCE_FILE "${SOURCE_FILE}
" ABSOLUTE) 50 if (NOT EXISTS "${SOURCE_FILE}
" AND NOT SOURCE_FILE MATCHES "\\.in$
" AND EXISTS "${SOURCE_FILE}.in
") 51 set (SOURCE_FILE "${SOURCE_FILE}.in
") 53 # -------------------------------------------------------------------------- 55 if (LANGUAGE MATCHES "CXX") 57 file (READ "${SOURCE_FILE}
" SOURCE) 58 # match use/require statements 59 basis_library_prefix (PREFIX ${LANGUAGE}) 60 basis_sanitize_for_regex (RE "[ \\t]*#[ \\t]*include[ \\t]+[<\
"](${PREFIX})?basis.h[\">]") #
e.g., #include
"basis.h", #include <pkg/basis.h>
61 if (SCRIPT MATCHES
"(^|\n)[ \t]*${RE}([ \t]*//.*|[ \t]*)(\n|$)")
62 set (UTILITIES_USED TRUE)
64 # -------------------------------------------------------------------------- 66 elseif (
LANGUAGE MATCHES
"[JP]YTHON")
68 file (READ
"${SOURCE_FILE}" SCRIPT)
69 # deprecated BASIS_PYTHON_UTILITIES macro 70 if (SCRIPT MATCHES
"(^|\n|;)[ \t]*\@BASIS_PYTHON_UTILITIES\@")
71 message (FATAL_ERROR
"Script ${SOURCE_FILE} uses the deprecated BASIS macro \@BASIS_PYTHON_UTILITIES\@!")
74 # match use of package-specific utilities 75 if (SCRIPT MATCHES "[^a-zA-Z._]${PYTHON_PACKAGE}.basis([.; \t\n]|$)
") # e.g., basis = <package>.basis, <package>.basis.exedir() 76 set (UTILITIES_USED TRUE) 78 # match import statements 80 "import[ \\t]+
basis" # e.g., import basis 81 "import[ \\t]+${PYTHON_PACKAGE}\\.basis
" # e.g., import <package>.basis 82 "import[ \\t]+\\.\\.?
basis" # e.g., import .basis, import ..basis 83 "from[ \\t]+${PYTHON_PACKAGE}[ \\t]+
import[ \\t]+
basis" # e.g., from <package> import basis 84 "from[ \\t]+${PYTHON_PACKAGE}.basis[ \\t]+
import[ \\t].*
" # e.g., from <package>.basis import which 85 "from[ \\t]+\\.\\.?[ \\t]+
import[ \\t]+
basis" # e.g., from . import basis",
"from .. import basis 86 "from[ \\t]+\\.\\.?
basis[ \\t]+
import[ \\t].*
" # e.g., from .basis import which, WhichError, from ..basis import which 88 if (SCRIPT MATCHES "(^|\n|;)[ \t]*${RE}([ \t]*as[ \t]+.*)?([ \t]*#.*|[ \t]*)(;|\n|$)
") 89 set (UTILITIES_USED TRUE) 94 # -------------------------------------------------------------------------- 96 elseif (LANGUAGE MATCHES "PERL
") 98 file (READ "${SOURCE_FILE}
" SCRIPT) 99 # deprecated BASIS_PERL_UTILITIES macro 100 if (SCRIPT MATCHES "(^|\n|;)[ \t]*\@BASIS_PERL_UTILITIES\
@") 101 message (FATAL_ERROR "Script ${SOURCE_FILE} uses the deprecated BASIS macro \@BASIS_PERL_UTILITIES\@!
") 103 # match use/require statements 105 set (RE "(use|require)[ \\t]+${PERL_PACKAGE}::Basis([ \\t]+.*)?
") # e.g., use <Package>::Basis qw(:everything); 106 if (SCRIPT MATCHES "(^|\n|;)[ \t]*${RE}([ \t]*#.*|[ \t]*)(;|\n|$)
") 107 set (UTILITIES_USED TRUE) 109 # -------------------------------------------------------------------------- 111 elseif (LANGUAGE MATCHES "BASH
") 113 file (READ "${SOURCE_FILE}
" SCRIPT) 114 # deprecated BASIS_BASH_UTILITIES macro 115 if (SCRIPT MATCHES "(^|\n|;)[ \t]*\@BASIS_BASH_UTILITIES\
@") 116 message (FATAL_ERROR "Script ${SOURCE_FILE} uses the deprecated BASIS macro \@BASIS_BASH_UTILITIES\@!
") 118 # match source/. built-ins 119 set (RE "(source|\\.)[ \\t]+\\\
"?\\\${BASIS_BASH_UTILITIES}?\\\"?[ \\t]*(\\|\\|.*|&&.*)?(#.*)?") #
e.g., . ${BASIS_BASH_UTILITIES} || exit 1
120 if (SCRIPT MATCHES
"(^|\n|;)[ \t]*(${RE})[ \t]*(;|\n|$)")
121 set (UTILITIES_USED TRUE)
125 set (${VAR}
"${UTILITIES_USED}" PARENT_SCOPE)
128 # ============================================================================ 130 # ============================================================================ 132 # ---------------------------------------------------------------------------- 133 ## @brief Add build target for BASIS C++ utilities library. 135 # This function is called by basis_add_executable_target() and basis_add_library_target() 136 # in order to add the "basis" build target for the static project-specific 137 # BASIS utilities library for C++. If the target was added before, it is 138 # only used to get the target UID of this build target so the newly added 139 # executable or library can be linked to it. 141 # The CMake function add_library() checks if the specified source code files 142 # exist. If a source file is not found, an error is raised by CMake. The BASIS 143 # utilities can, however, only be configured at the end of the configuration 144 # step. Therefore, this function simply writes dummy C++ source files in order 145 # to pass the existence check. The actual source files are configured by the 146 # function basis_configure_utilities() which is called by basis_project_end(). 148 # After writing these dummy source files, a library build target for the 149 # project-specific BASIS C++ utilities is added. This build target is not 150 # being build as part of the ALL target in case it is never used by any of 151 # the build targets of the project. Only if build target links to this 152 # library, it will be build and installed. 154 # @param [out] UID UID of added build target. 156 # target UID of
"basis" library target
157 _basis_make_target_uid (TARGET_UID
basis)
158 if (NOT TARGET ${TARGET_UID})
159 if (PROJECT_IS_SUBPROJECT)
160 # a subproject has it's own version of the project-specific BASIS utilities 161 # as the targets and functions live in a separate namespace 162 set (CODE_DIR
"${BINARY_CODE_DIR}")
163 set (INCLUDE_DIR
"${BINARY_INCLUDE_DIR}")
164 set (OUTPUT_DIR
"${BINARY_ARCHIVE_DIR}")
165 set (INSTALL_DIR
"${INSTALL_ARCHIVE_DIR}")
167 # modules, on the other side, share the library with the top-level project 168 # the addition of the utilities target is in this case only required because 169 # of the install(TARGETS) and install(EXPORT) commands. 170 set (CODE_DIR
"${TOPLEVEL_BINARY_CODE_DIR}")
171 set (INCLUDE_DIR
"${TOPLEVEL_BINARY_INCLUDE_DIR}")
172 set (OUTPUT_DIR
"${TOPLEVEL_BINARY_ARCHIVE_DIR}")
173 set (INSTALL_DIR
"${TOPLEVEL_INSTALL_ARCHIVE_DIR}")
175 # write dummy source files 177 foreach (S IN ITEMS basis.h basis.cxx)
178 if (S MATCHES
"\\.h$")
179 set (S
"${INCLUDE_DIR}/${PREFIX}${S}")
181 set (S
"${CODE_DIR}/${S}")
183 if (NOT EXISTS
"${S}")
185 "#error This dummy source file should have been replaced by the" 186 " BASIS CMake function basis_configure_utilities()" 190 # add library target if not present yet - only build if required 191 add_library (${TARGET_UID} STATIC
"${CODE_DIR}/basis.cxx")
192 # define dependency on non-project specific utilities as the order in
193 #
which static libraries are listed on the command-line
for the linker
194 # matters;
this will help CMake to
get the order right
196 #
set target properties
200 BASIS_TYPE STATIC_LIBRARY
202 ARCHIVE_OUTPUT_DIRECTORY
"${OUTPUT_DIR}" 203 ARCHIVE_INSTALL_DIRECTORY
"${INSTALL_DIR}" 209 TARGETS ${TARGET_UID} ${EXPORT_OPT}
211 DESTINATION
"${INSTALL_DIR}" 212 COMPONENT
"${BASIS_LIBRARY_COMPONENT}" 216 message ("** Added BASIS utilities library ${TARGET_UID}
") 220 basis_set_project_property (PROPERTY PROJECT_USES_CXX_UTILITIES TRUE) 221 set (${UID} "${TARGET_UID}
" PARENT_SCOPE) 224 # ============================================================================ 226 # ============================================================================ 228 # ---------------------------------------------------------------------------- 229 ## @brief Add build target for BASIS Python utilities library. 231 # This function is called by basis_target_link_libraries() in order to add the 232 # "basis
" build target for the project-specific BASIS Python utilities. 233 # If the target was added before, it is only used to get the target UID of 234 # this build target so the executable or library can be linked to it. 236 # @note The basis_target_link_libraries() function in fact calls 237 # basis_add_utilities_library() which calls this function. 239 # @param [out] UID UID of added build target. 240 function (basis_add_python_utilities_library UID) 241 basis_make_target_uid (TARGET_UID basis_py) 242 if (NOT TARGET ${TARGET_UID}) 243 basis_library_prefix (PREFIX PYTHON) 244 basis_add_library (.${TARGET_UID} "${BASIS_PYTHON_TEMPLATES_DIR}/basis.py
") 245 basis_set_target_properties (.${TARGET_UID} PROPERTIES PREFIX ${PREFIX}) 246 basis_target_link_libraries (.${TARGET_UID} ${BASIS_PYTHON_UTILITIES_LIBRARY}) 248 basis_set_project_property (PROPERTY PROJECT_USES_PYTHON_UTILITIES TRUE) 249 set (${UID} ${TARGET_UID} PARENT_SCOPE) 252 # ============================================================================ 254 # ============================================================================ 256 # ---------------------------------------------------------------------------- 257 ## @brief Add build target for BASIS Perl utilities library. 259 # This function is called by basis_target_link_libraries() in order to add the 260 # "basis
" build target for the project-specific BASIS Perl utilities. 261 # If the target was added before, it is only used to get the target UID of 262 # this build target so the executable or library can be linked to it. 264 # @note The basis_target_link_libraries() function in fact calls 265 # basis_add_utilities_library() which calls this function. 267 # @param [out] UID UID of added build target. 268 function (basis_add_perl_utilities_library UID) 269 basis_make_target_uid (TARGET_UID Basis_pm) 270 if (NOT TARGET ${TARGET_UID}) 271 basis_library_prefix (PREFIX PERL) 272 basis_add_library (.${TARGET_UID} "${BASIS_PERL_TEMPLATES_DIR}/Basis.pm
") 273 basis_set_target_properties (.${TARGET_UID} PROPERTIES PREFIX ${PREFIX}) 274 basis_target_link_libraries (.${TARGET_UID} ${BASIS_PERL_UTILITIES_LIBRARY}) 276 basis_set_project_property (PROPERTY PROJECT_USES_PERL_UTILITIES TRUE) 277 set (${UID} ${TARGET_UID} PARENT_SCOPE) 280 # ============================================================================ 282 # ============================================================================ 284 # ---------------------------------------------------------------------------- 285 ## @brief Absolute path of current BASH file. 287 # @note Does not resolve symbolic links. 291 # readonly __MYMODULE=@BASIS_BASH___FILE__@ 294 # @ingroup BasisBashUtilities 295 set (BASIS_BASH___FILE__ "$(cd -- \
"$(dirname -- \"\${BASH_SOURCE}\")\" && pwd -P)/$(basename -- \"$BASH_SOURCE\")")
297 # ----------------------------------------------------------------------------
298 ## @brief Absolute path to directory of current BASH file.
300 # @note Does not resolve symbolic links.
307 # @ingroup BasisBashUtilities
310 # ---------------------------------------------------------------------------- 311 ## @brief Add build target for BASIS Bash utilities library. 313 # This function is called by basis_target_link_libraries() in order to add the 314 # "basis" build target for the project-specific BASIS Bash utilities. 315 # If the target was added before, it is only used to get the target UID of 316 # this build target so the executable or library can be linked to it. 318 # @note The basis_target_link_libraries() function in fact calls 319 # basis_add_utilities_library() which calls this function. 321 # @param [out] UID UID of added build target. 324 if (NOT TARGET ${TARGET_UID})
331 set (${UID} ${TARGET_UID} PARENT_SCOPE)
334 # ============================================================================ 336 # ============================================================================ 338 # ---------------------------------------------------------------------------- 339 ## @brief Add build target for BASIS utilities library. 341 # This function is called by basis_target_link_libraries() in order to add the 342 # "basis" build target for the project-specific BASIS utilities for a given 343 # source code language. If the target was added before, it is only used to get 344 # the target UID of this build target so the executable or library can be 347 # @param [out] UID UID of added build target. 348 # @param [in] LANGUAGE Programming language of utilities. 350 if (
"^${LANGUAGE}$" STREQUAL
"^CXX$")
352 message (FATAL_ERROR
"This project makes use of the BASIS C++ utilities" 353 " but BASIS was built without these utilities enabled.")
356 elseif (
"^${LANGUAGE}$" STREQUAL
"^PYTHON$")
358 message (FATAL_ERROR
"This project makes use of the BASIS Python utilities" 359 " but BASIS was built without these utilities enabled.")
362 elseif (
"^${LANGUAGE}$" STREQUAL
"^PERL$")
364 message (FATAL_ERROR
"This project makes use of the BASIS Perl utilities" 365 " but BASIS was built without these utilities enabled.")
368 elseif (
"^${LANGUAGE}$" STREQUAL
"^BASH$")
370 message (FATAL_ERROR
"This project makes use of the BASIS Bash utilities" 371 " but BASIS was built without these utilities enabled.")
375 message (FATAL_ERROR
"Unsupported language: ${LANGUAGE}")
379 # ---------------------------------------------------------------------------- 380 ## @brief Determine whether this project uses any of the BASIS Utilities. 386 if (
CXX OR PYTHON OR PERL OR BASH)
387 set (
RETVAL TRUE PARENT_SCOPE)
389 set (
RETVAL FALSE PARENT_SCOPE)
393 # ---------------------------------------------------------------------------- 394 ## @brief Configure BASIS utilities. 396 # This function configures the following source files which can be used 397 # within the source code of the project. If the BASIS utilities for a specific 398 # language are not used by any of the project's build targets, no target for 399 # the build of these utilities is added, unless the 400 # @c BUILD_BASIS_UTILITIES_FOR_<LANGUAGE> option is set to @c ON. A reason 401 # for forcing the build of the BASIS utilities is that the libraries should 402 # be used by other projects which may want to make use of the BASIS Utilities 403 # to get access to the project attributes. 407 # @tp @b basis.h @endtp 408 # <td>Header file declaring the BASIS utilities for C++.</td> 411 # @tp @b basis.cxx @endtp 412 # <td>Definitions of the constants and functions declared in basis.h.</td> 415 # @tp @b basis.py @endtp 416 # <td>Module defining the BASIS utilities for Python.</td> 419 # @tp @b Basis.pm @endtp 420 # <td>Module defining the BASIS utilities for Perl.</td> 423 # @tp @b basis.sh @endtp 424 # <td>Module defining the BASIS utilities for Bash.</td> 428 # @note Dummy versions of the C++ source files have been written by the 429 # function basis_add_utilities_library() beforehand. This is 430 # necessary because CMake's add_executable() and add_library() commands 431 # raise an error if any of the specified source files does not exist. 434 foreach (L IN ITEMS
CXX PYTHON PERL BASH)
435 if (BUILD_BASIS_UTILITIES_FOR_${L})
447 message (STATUS
"Configuring BASIS utilities...")
448 # -------------------------------------------------------------------------- 449 # executable target information 450 _basis_generate_executable_target_info (${
CXX} ${PYTHON} ${PERL} ${BASH})
451 # --------------------------------------------------------------------------
453 set (PROJECT_ID
"${PROJECT_PACKAGE_NAME}")
454 if (NOT PROJECT_NAME MATCHES
"${PROJECT_PACKAGE_NAME_RE}")
455 set (PROJECT_ID
"${PROJECT_ID}, ${PROJECT_NAME}")
457 # -------------------------------------------------------------------------- 460 # make sure that library target is added which is not the case yet 461 # if the BASIS C++ utilities are not used by any project target, but 462 # their build is forced via the BUILD_BASIS_UTILITIES_FOR_CXX option 465 set (BUILD_ROOT_PATH_CONFIG
"${CMAKE_BINARY_DIR}")
466 set (RUNTIME_BUILD_PATH_CONFIG
"${BINARY_RUNTIME_DIR}")
467 set (LIBEXEC_BUILD_PATH_CONFIG
"${BINARY_LIBEXEC_DIR}")
468 set (LIBRARY_BUILD_PATH_CONFIG
"${BINARY_LIBRARY_DIR}")
469 set (DATA_BUILD_PATH_CONFIG
"${PROJECT_DATA_DIR}")
470 # paths - installation
471 file (RELATIVE_PATH RUNTIME_PATH_PREFIX_CONFIG
"${CMAKE_INSTALL_PREFIX}/${INSTALL_RUNTIME_DIR}" "${CMAKE_INSTALL_PREFIX}")
472 string (REGEX REPLACE
"/$|\\$" "" RUNTIME_PATH_PREFIX_CONFIG
"${RUNTIME_PATH_PREFIX_CONFIG}")
473 file (RELATIVE_PATH LIBEXEC_PATH_PREFIX_CONFIG
"${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBEXEC_DIR}" "${CMAKE_INSTALL_PREFIX}")
474 string (REGEX REPLACE
"/$|\\$" "" LIBEXEC_PATH_PREFIX_CONFIG
"${LIBEXEC_PATH_PREFIX_CONFIG}")
475 set (RUNTIME_PATH_CONFIG
"${INSTALL_RUNTIME_DIR}")
476 set (LIBEXEC_PATH_CONFIG
"${INSTALL_LIBEXEC_DIR}")
477 set (LIBRARY_PATH_CONFIG
"${INSTALL_LIBRARY_DIR}")
478 set (DATA_PATH_CONFIG
"${INSTALL_DATA_DIR}")
480 set (PROJECT_NAMESPACE_CXX_BEGIN
"namespace ${PROJECT_PACKAGE_NAME_L} {")
481 set (PROJECT_NAMESPACE_CXX_END
"}")
482 if (PROJECT_IS_SUBPROJECT)
483 set (PROJECT_NAMESPACE_CXX_BEGIN
"${PROJECT_NAMESPACE_CXX_BEGIN} namespace ${PROJECT_NAME_L} {")
484 set (PROJECT_NAMESPACE_CXX_END
"${PROJECT_NAMESPACE_CXX_END} }")
486 # executable target information 487 set (EXECUTABLE_TARGET_INFO
"${EXECUTABLE_TARGET_INFO_CXX}")
488 # configure source files
490 configure_file (
"${BASIS_CXX_TEMPLATES_DIR}/basis.h.in" "${BINARY_INCLUDE_DIR}/${PREFIX}basis.h" @ONLY)
491 configure_file (
"${BASIS_CXX_TEMPLATES_DIR}/basis.cxx.in" "${BINARY_CODE_DIR}/basis.cxx" @ONLY)
492 source_group (BASIS FILES
"${BINARY_INCLUDE_DIR}/${PREFIX}basis.h" "${BINARY_CODE_DIR}/basis.cxx")
494 # -------------------------------------------------------------------------- 497 # utilities available? 499 message (FATAL_ERROR
"BASIS Python utilities required by this package" 500 " but BASIS was built without Python utilities." 501 " Rebuild BASIS with Python utilities enabled.")
503 # make sure that library target is added which is not the case yet 504 # if the BASIS Python utilities are not used by any project target, but 505 # their build is forced via the BUILD_BASIS_UTILITIES_FOR_PYTHON option 507 # set target properties 508 set (SCRIPT_DEFINITIONS
509 "set (PROJECT_ID \"${PROJECT_ID}\") 510 if (BUILD_INSTALL_SCRIPT) 511 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_PYTHON_I}\") 513 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_PYTHON_B}\") 516 if (
"^${PROJECT_NAME}$" STREQUAL
"^BASIS$")
517 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nbasis_set_script_path (_BASIS_PYTHONPATH \"${BINARY_PYTHON_LIBRARY_DIR}\" \"${INSTALL_PYTHON_LIBRARY_DIR}\")")
518 elseif (BUNDLE_PROJECTS MATCHES
"(^|;)BASIS(;|$)")
519 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nbasis_set_script_path (_BASIS_PYTHONPATH \"${BASIS_PYTHONPATH}\")")
521 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nset (_BASIS_PYTHONPATH \"${BASIS_PYTHONPATH}\")")
527 SOURCE_DIRECTORY
"${BASIS_PYTHON_TEMPLATES_DIR}" 528 BINARY_DIRECTORY
"${BINARY_CODE_DIR}" 529 LIBRARY_OUTPUT_DIRECTORY
"${BINARY_PYTHON_LIBRARY_DIR}" 530 LIBRARY_INSTALL_DIRECTORY
"${INSTALL_PYTHON_LIBRARY_DIR}" 532 SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}" 536 # -------------------------------------------------------------------------- 539 # utilities available? 541 message (FATAL_ERROR
"BASIS Perl utilities required by this package" 542 " but BASIS was built without Perl utilities." 543 " Rebuild BASIS with Perl utilities enabled.")
545 # make sure that library target is added which is not the case yet 546 # if the BASIS Perl utilities are not used by any project target, but 547 # their build is forced via the BUILD_BASIS_UTILITIES_FOR_PERL option 549 # set target properties 554 SOURCE_DIRECTORY
"${BASIS_PERL_TEMPLATES_DIR}" 555 BINARY_DIRECTORY
"${BINARY_CODE_DIR}" 556 LIBRARY_OUTPUT_DIRECTORY
"${BINARY_PERL_LIBRARY_DIR}" 557 LIBRARY_INSTALL_DIRECTORY
"${INSTALL_PERL_LIBRARY_DIR}" 560 "set (PROJECT_ID \"${PROJECT_ID}\") 561 if (BUILD_INSTALL_SCRIPT) 562 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_PERL_I}\") 564 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_PERL_B}\") 569 # -------------------------------------------------------------------------- 572 # utilities available? 574 message (WARNING
"Package uses BASIS Bash utilities but is build" 575 " on a non-Unix system.")
578 message (FATAL_ERROR
"BASIS Bash utilities required by this package" 579 " but BASIS was built without Bash utilities." 580 " Rebuild BASIS with Bash utilities enabled.")
582 # make sure that library target is added which is not the case yet 583 # if the BASIS Python utilities are not used by any project target, but 584 # their build is forced via the BUILD_BASIS_UTILITIES_FOR_BASH option 586 # set target properties 587 set (SCRIPT_DEFINITIONS
588 "set (PROJECT_ID \"${PROJECT_ID}\") 589 if (BUILD_INSTALL_SCRIPT) 590 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_BASH_I}\") 592 set (EXECUTABLE_TARGET_INFO \"${EXECUTABLE_TARGET_INFO_BASH_B}\") 594 set (EXECUTABLE_ALIASES \"${EXECUTABLE_TARGET_INFO_BASH_A}\n\n # define short aliases for this project's targets\n ${EXECUTABLE_TARGET_INFO_BASH_S}\")" 596 if (
"^${PROJECT_NAME}$" STREQUAL
"^BASIS$")
597 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nbasis_set_script_path (_BASIS_BASH_LIBRARY_DIR \"${BINARY_BASH_LIBRARY_DIR}\" \"${INSTALL_BASH_LIBRARY_DIR}\")")
598 elseif (BUNDLE_PROJECTS MATCHES
"(^|;)BASIS(;|$)")
599 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nbasis_set_script_path (_BASIS_BASH_LIBRARY_DIR \"${BASIS_BASHPATH}\")")
601 set (SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}\nset (_BASIS_BASH_LIBRARY_DIR \"${BASIS_BASHPATH}\")")
607 SOURCE_DIRECTORY
"${BASIS_BASH_TEMPLATES_DIR}" 608 BINARY_DIRECTORY
"${BINARY_CODE_DIR}" 609 LIBRARY_OUTPUT_DIRECTORY
"${BINARY_BASH_LIBRARY_DIR}" 610 LIBRARY_INSTALL_DIRECTORY
"${INSTALL_BASH_LIBRARY_DIR}" 612 SCRIPT_DEFINITIONS
"${SCRIPT_DEFINITIONS}" 616 message (STATUS
"Configuring BASIS utilities... - done")
619 # ---------------------------------------------------------------------------- 620 ## @brief Generate code for initialization of executable target information. 622 # This macro generates the initialization code of the executable target 623 # information dictionaries for different supported programming languages. 624 # In case of C++, the source file has been configured and copied to the binary 625 # tree in a first configuration pass such that it could be used in basis_add_*() 626 # commands which check the existence of the arguments immediately. 627 # As the generation of the initialization code requires a complete list of 628 # build targets (cached in @c BASIS_TARGETS), this function has to be called 629 # after all targets have been added and finalized (in case of custom targets). 631 # @param [in] CXX Request code for C++. 632 # @param [in] PYTHON Request code for Python. 633 # @param [in] PERL Request code for Perl. 634 # @param [in] BASH Request code for Bash. 636 # @returns Sets the following variables for each requested language. 638 # @retval EXECUTABLE_TARGET_INFO_CXX C++ code for both build tree and installation. 639 # @retval EXECUTABLE_TARGET_INFO_PYTHON_B Python code for build tree. 640 # @retval EXECUTABLE_TARGET_INFO_PYTHON_I Python code for installation. 641 # @retval EXECUTABLE_TARGET_INFO_PERL_B Perl code for build tree. 642 # @retval EXECUTABLE_TARGET_INFO_PERL_I Perl code for installation. 643 # @retval EXECUTABLE_TARGET_INFO_BASH_B Bash code for build tree. 644 # @retval EXECUTABLE_TARGET_INFO_BASH_I Bash code for installation. 645 # @retval EXECUTABLE_TARGET_INFO_BASH_A Bash code to set aliases. 646 # @retval EXECUTABLE_TARGET_INFO_BASH_S Bash code to set short aliases. 647 function (_basis_generate_executable_target_info CXX PYTHON PERL BASH)
648 # --------------------------------------------------------------------------
649 if (NOT CXX AND NOT PYTHON AND NOT PERL AND NOT BASH)
652 # -------------------------------------------------------------------------- 655 # -------------------------------------------------------------------------- 656 # lists of executable targets and their location 657 set (EXECUTABLE_TARGETS)
658 set (EXECUTABLE_IMPORTED)
659 set (BUILD_LOCATIONS)
660 set (INSTALL_LOCATIONS)
663 foreach (TARGET_UID IN LISTS TARGETS)
665 if (TYPE MATCHES
"EXECUTABLE")
666 get_target_property (IMPORTED ${TARGET_UID} IMPORTED)
670 list (APPEND EXECUTABLE_TARGETS
"${TARGET_UID}")
671 list (APPEND EXECUTABLE_IMPORTED
"${IMPORTED}")
672 list (APPEND BUILD_LOCATIONS
"${BUILD_LOCATION}")
673 list (APPEND INSTALL_LOCATIONS
"${INSTALL_LOCATION}")
675 message (FATAL_ERROR
"Failed to determine build location of target ${TARGET_UID}!")
684 list (LENGTH IMPORTED_TARGETS N)
686 list (GET IMPORTED_TARGETS ${I} TARGET)
687 list (GET IMPORTED_TYPES ${I} TYPE)
688 list (GET IMPORTED_LOCATIONS ${I} LOCATION)
689 if (TYPE MATCHES
"EXECUTABLE")
690 # get corresponding UID (target may be imported from other module) 692 #
skip already considered executables
693 list (FIND EXECUTABLE_TARGETS ${TARGET_UID} IDX)
695 if (LOCATION MATCHES
"^NOTFOUND$")
696 message (WARNING
"Imported target ${TARGET} has no location property!")
698 list (APPEND EXECUTABLE_TARGETS
"${TARGET_UID}")
699 list (APPEND EXECUTABLE_IMPORTED TRUE)
700 list (APPEND BUILD_LOCATIONS
"${LOCATION}")
701 list (APPEND INSTALL_LOCATIONS
"${LOCATION}")
705 math (EXPR I
"${I} + 1")
707 # -------------------------------------------------------------------------- 708 # determine maximum length of target alias for prettier output 709 set (MAX_ALIAS_LENGTH 0)
710 foreach (TARGET_UID IN LISTS EXECUTABLE_TARGETS)
712 string (LENGTH
"${ALIAS}" LENGTH)
713 if (LENGTH GREATER MAX_ALIAS_LENGTH)
714 set (MAX_ALIAS_LENGTH ${LENGTH})
717 # -------------------------------------------------------------------------- 718 # generate source code 719 set (
CC) # C++ - build tree and install tree version, constructor block
720 set (PY_B) # Python - build tree version
721 set (PY_I) # Python - install tree version
722 set (PL_B) # Perl - build tree version, hash entries
723 set (PL_I) # Perl - install tree version, hash entries
724 set (SH_B) # Bash - build tree version
725 set (SH_I) # Bash - install tree version
726 set (SH_A) # Bash - aliases
727 set (SH_S) # Bash -
short aliases
730 set (
CC "// the following code was automatically generated by the BASIS")
731 set (
CC "${CC}\n // CMake function basis_configure_ExecutableTargetInfo()")
735 list (LENGTH EXECUTABLE_TARGETS N)
737 # ------------------------------------------------------------------------ 738 # get executable information 739 list (GET EXECUTABLE_TARGETS ${I} TARGET_UID)
740 list (GET BUILD_LOCATIONS ${I} BUILD_LOCATION)
741 list (GET INSTALL_LOCATIONS ${I} INSTALL_LOCATION)
742 # installation path (relative) to different library paths
743 if (INSTALL_LOCATION)
744 list (GET EXECUTABLE_IMPORTED ${I} IMPORTED)
745 get_target_property (BUNDLED ${TARGET_UID} BUNDLED)
747 foreach (L LIBRARY PYTHON_LIBRARY PERL_LIBRARY BASH_LIBRARY)
748 if (INSTALL_LOCATION AND (NOT IMPORTED OR BUNDLED))
750 RELATIVE_PATH INSTALL_LOCATION_REL2${L}
751 "${CMAKE_INSTALL_PREFIX}/${INSTALL_${L}_DIR}/<package>" 752 "${INSTALL_LOCATION}" 755 set (INSTALL_LOCATION_REL2${L}
"${INSTALL_LOCATION}")
758 # target UID including project namespace 760 # indentation after dictionary key, i.e., alias 761 string (LENGTH
"${ALIAS}" ALIAS_LENGTH)
762 math (EXPR NUM
"${MAX_ALIAS_LENGTH} - ${ALIAS_LENGTH} + 1")
764 string (RANDOM LENGTH ${NUM} ALPHABET
" " S)
768 # ------------------------------------------------------------------------ 773 if (INSTALL_LOCATION)
778 set (
CC "${CC}\n // ${TARGET_UID}")
779 set (
CC "${CC}\n _exec_names [\"${ALIAS}\"]${S}= \"${EXEC_NAME}\";")
780 set (
CC "${CC}\n _build_dirs [\"${ALIAS}\"]${S}= \"${BUILD_DIR}\";")
781 set (
CC "${CC}\n _install_dirs[\"${ALIAS}\"]${S}= \"${INSTALL_DIR}\";")
783 # ------------------------------------------------------------------------ 786 set (PY_B
"${PY_B} '${ALIAS}':${S}'${BUILD_LOCATION}',\n")
787 if (INSTALL_LOCATION)
788 set (PY_I
"${PY_I} '${ALIAS}':${S}'${INSTALL_LOCATION_REL2PYTHON_LIBRARY}',\n")
790 set (PY_I
"${PY_I} '${ALIAS}':${S}'',\n")
793 # ------------------------------------------------------------------------ 797 set (PL_B
"${PL_B},\n")
799 set (PL_B
"${PL_B} '${ALIAS}'${S}=> '${BUILD_LOCATION}'")
801 set (PL_I
"${PL_I},\n")
803 if (INSTALL_LOCATION)
804 set (PL_I
"${PL_I} '${ALIAS}'${S}=> '${INSTALL_LOCATION_REL2PERL_LIBRARY}'")
806 set (PL_I
"${PL_I} '${ALIAS}'${S}=> ''")
809 # ------------------------------------------------------------------------ 813 set (SH_B
"${SH_B}\n _basis_executabletargetinfo_add '${ALIAS}'${S}LOCATION '${BUILD_LOCATION}'")
814 if (INSTALL_LOCATION)
815 set (SH_I
"${SH_I}\n _basis_executabletargetinfo_add '${ALIAS}'${S}LOCATION '${INSTALL_LOCATION_REL2BASH_LIBRARY}'")
817 set (SH_I
"${SH_I}\n _basis_executabletargetinfo_add '${ALIAS}'${S}LOCATION ''")
820 set (SH_A
"${SH_A}\n alias '${ALIAS}'=`get_executable_path '${ALIAS}'`")
821 #
short alias (
if target belongs to
this project)
822 if (ALIAS MATCHES
"^${PROJECT_NAMESPACE_CMAKE_RE}\\.")
824 set (SH_S
"${SH_S}\n alias '${TARGET_NAME}'='${ALIAS}'")
827 # ------------------------------------------------------------------------ 828 # next executable target 829 math (EXPR I
"${I} + 1")
831 # -------------------------------------------------------------------------- 832 # remove unnecessary leading newlines 833 string (STRIP
"${CC}" CC)
834 string (STRIP
"${PY_B}" PY_B)
835 string (STRIP
"${PY_I}" PY_I)
836 string (STRIP
"${PL_B}" PL_B)
837 string (STRIP
"${PL_I}" PL_I)
838 string (STRIP
"${SH_B}" SH_B)
839 string (STRIP
"${SH_I}" SH_I)
840 string (STRIP
"${SH_A}" SH_A)
841 string (STRIP
"${SH_S}" SH_S)
842 # -------------------------------------------------------------------------- 844 set (EXECUTABLE_TARGET_INFO_CXX
"${CC}" PARENT_SCOPE)
845 set (EXECUTABLE_TARGET_INFO_PYTHON_B
"${PY_B}" PARENT_SCOPE)
846 set (EXECUTABLE_TARGET_INFO_PYTHON_I
"${PY_I}" PARENT_SCOPE)
847 set (EXECUTABLE_TARGET_INFO_PERL_B
"${PL_B}" PARENT_SCOPE)
848 set (EXECUTABLE_TARGET_INFO_PERL_I
"${PL_I}" PARENT_SCOPE)
849 set (EXECUTABLE_TARGET_INFO_BASH_B
"${SH_B}" PARENT_SCOPE)
850 set (EXECUTABLE_TARGET_INFO_BASH_I
"${SH_I}" PARENT_SCOPE)
851 set (EXECUTABLE_TARGET_INFO_BASH_A
"${SH_A}" PARENT_SCOPE)
852 set (EXECUTABLE_TARGET_INFO_BASH_S
"${SH_S}" PARENT_SCOPE)
857 # end of Doxygen group function basis_get_target_uid(out TARGET_UID, in TARGET_NAME)
Get "global" target name, i.e., actual CMake target name.
function set_target_properties(in ARGN)
Set target property.
cmake BASIS_PERL_UTILITIES_LIBRARY
function basis_target_link_libraries(in TARGET_NAME, in ARGN)
Add link dependencies to build target.
def which(command, path=None, verbose=0, exts=None)
function basis_get_project_property(out VARIABLE, in ARGN)
Get project-global property value.
function basis_add_cxx_utilities_library(out UID)
Add build target for BASIS C++ utilities library.
function basis_finalize_targets(in ARGN)
Finalize custom targets by adding the missing build commands.
cmake BASIS_BASH___DIR__
Absolute path to directory of current BASH file.
function basis_add_export_target(out EXPORT_OPTION, in TARGET_UID, in IS_TEST, in ARGN)
Add target to export set.
function add_library(in TARGET_UID, in ARGN)
Add library target.
macro basis_sanitize_for_regex(out OUT, in STR)
Sanitize string variable for use in regular expression.
function basis_get_source_language(out LANGUAGE, in ARGN)
Detect programming language of given source code files.
function basis_configure_utilities()
Configure BASIS utilities.
function basis_set_project_property()
Set project-global property.
function basis_add_python_utilities_library(out UID)
Add build target for BASIS Python utilities library.
macro basis_add_utilities_library(out UID, in LANGUAGE)
Add build target for BASIS utilities library.
function basis_add_perl_utilities_library(out UID)
Add build target for BASIS Perl utilities library.
void print_version(const char *name, const char *version=NULL, const char *project=NULL, const char *copyright=NULL, const char *license=NULL)
Print version information including copyright and license notices.
function basis_utilities_check(out VAR, in SOURCE_FILE, in ARGN)
Check whether the BASIS utilities are used within a given source file.
function skip(in condition, in reason, in n)
Skip tests under a certain condition.
function basis_get_target_type(out TYPE, in TARGET_NAME)
Get type name of target.
cmake BASIS_PYTHON_UTILITIES_LIBRARY
cmake PROJECT_NAMESPACE_PERL
CMake variable of Perl package name of project.
function basis_get_fully_qualified_target_uid(out TARGET_UID, in TARGET_NAME)
Get fully-qualified target name.
function basis_make_target_uid(out TARGET_UID, in TARGET_NAME)
Make target UID from given target name.
#define UNIX
Whether the sources are compiled on a Unix-based system.
cmake PROJECT_NAMESPACE_PYTHON
CMake variable of Python package name of project.
option BASIS_DEBUG
Request debugging messages from BASIS functions.
function basis_add_bash_utilities_library(out UID)
Add build target for BASIS Bash utilities library.
function basis_get_project_uses_utilities(in RETVAL)
Determine whether this project uses any of the BASIS Utilities.
macro basis_library_prefix(out PREFIX, in LANGUAGE)
Get default subdirectory prefix of scripted library modules.
cmake BASIS_CXX_UTILITIES_LIBRARY
cmake LANGUAGE
Detected scripting language or UNKNOWN.
cmake BASIS_BASH_UTILITIES_LIBRARY
function basis_set_target_properties(in ARGN)
Set properties on a target.
function basis_get_target_name(out TARGET_NAME, in TARGET_UID)
Get "local" target name, i.e., BASIS target name without check of UID.
function basis_add_library(in TARGET_NAME, in ARGN)
Add library target.
function get_filename_component(inout ARGN)
Fixes CMake's get_filename_component() command.
cmake BASIS_UTILITIES_ENABLED
function basis_get_target_location(out VAR, in TARGET_NAME, in PART)
Get location of build target output file(s).