TargetTools.cmake
Go to the documentation of this file.
00001 ############################################################################## 00002 # @file TargetTools.cmake 00003 # @brief Functions and macros to add executable and library targets. 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 # @ingroup CMakeTools 00011 ############################################################################## 00012 00013 if (__BASIS_TARGETTOOLS_INCLUDED) 00014 return () 00015 else () 00016 set (__BASIS_TARGETTOOLS_INCLUDED TRUE) 00017 endif () 00018 00019 00020 ## @addtogroup CMakeUtilities 00021 # @{ 00022 00023 00024 # ============================================================================ 00025 # properties 00026 # ============================================================================ 00027 00028 # ---------------------------------------------------------------------------- 00029 ## @brief Set properties on a target. 00030 # 00031 # This function replaces CMake's 00032 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_target_properties"> 00033 # set_target_properties()</a> command and extends its functionality. 00034 # In particular, it maps the given target names to the corresponding target UIDs. 00035 # 00036 # @note Due to a bug in CMake (http://www.cmake.org/Bug/view.php?id=12303), 00037 # except of the first property given directly after the @c PROPERTIES keyword, 00038 # only properties listed in @c BASIS_PROPERTIES_ON_TARGETS can be set. 00039 # 00040 # @param [in] ARGN List of arguments. See 00041 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_target_properties"> 00042 # set_target_properties()</a>. 00043 # 00044 # @returns Sets the specified properties on the given target. 00045 # 00046 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_target_properties 00047 # 00048 # @ingroup CMakeAPI 00049 function (basis_set_target_properties) 00050 # convert target names to UIDs 00051 set (TARGET_UIDS) 00052 list (LENGTH ARGN N) 00053 if (N EQUAL 0) 00054 message (FATAL_ERROR "basis_set_target_properties(): Missing arguments!") 00055 endif () 00056 list (GET ARGN 0 ARG) 00057 while (NOT ARG MATCHES "^PROPERTIES$") 00058 basis_get_target_uid (TARGET_UID "${ARG}") 00059 list (APPEND TARGET_UIDS "${TARGET_UID}") 00060 list (REMOVE_AT ARGN 0) 00061 list (LENGTH ARGN N) 00062 if (N EQUAL 0) 00063 break () 00064 else () 00065 list (GET ARGN 0 ARG) 00066 endif () 00067 endwhile () 00068 if (NOT ARG MATCHES "^PROPERTIES$") 00069 message (FATAL_ERROR "Missing PROPERTIES argument!") 00070 elseif (NOT TARGET_UIDS) 00071 message (FATAL_ERROR "No target specified!") 00072 endif () 00073 # remove PROPERTIES keyword 00074 list (REMOVE_AT ARGN 0) 00075 math (EXPR N "${N} - 1") 00076 # set targets properties 00077 # 00078 # Note: By iterating over the properties, the empty property values 00079 # are correctly passed on to CMake's set_target_properties() 00080 # command, while 00081 # _set_target_properties(${TARGET_UIDS} PROPERTIES ${ARGN}) 00082 # (erroneously) discards the empty elements in ARGN. 00083 if (BASIS_DEBUG) 00084 message ("** basis_set_target_properties:") 00085 message ("** Target(s): ${TARGET_UIDS}") 00086 message ("** Properties: [${ARGN}]") 00087 endif () 00088 while (N GREATER 1) 00089 list (GET ARGN 0 PROPERTY) 00090 list (GET ARGN 1 VALUE) 00091 list (REMOVE_AT ARGN 0 1) 00092 list (LENGTH ARGN N) 00093 # The following loop is only required b/c CMake's ARGV and ARGN 00094 # lists do not support arguments which are themselves lists. 00095 # Therefore, we need a way to decide when the list of values for a 00096 # property is terminated. Hence, we only allow known properties 00097 # to be set, except for the first property where the name follows 00098 # directly after the PROPERTIES keyword. 00099 while (N GREATER 0) 00100 list (GET ARGN 0 ARG) 00101 if (ARG MATCHES "${BASIS_PROPERTIES_ON_TARGETS_RE}") 00102 break () 00103 endif () 00104 list (APPEND VALUE "${ARG}") 00105 list (REMOVE_AT ARGN 0) 00106 list (LENGTH ARGN N) 00107 endwhile () 00108 if (BASIS_DEBUG) 00109 message ("** -> ${PROPERTY} = [${VALUE}]") 00110 endif () 00111 # check property name 00112 if (PROPERTY MATCHES "^$") # remember: STREQUAL is buggy and evil! 00113 message (FATAL_ERROR "Empty property name given!") 00114 endif () 00115 # set target property 00116 _set_target_properties (${TARGET_UIDS} PROPERTIES ${PROPERTY} "${VALUE}") 00117 endwhile () 00118 # make sure that every property had a corresponding value 00119 if (NOT N EQUAL 0) 00120 message (FATAL_ERROR "No value given for target property ${ARGN}") 00121 endif () 00122 endfunction () 00123 00124 # ---------------------------------------------------------------------------- 00125 ## @brief Get value of property set on target. 00126 # 00127 # This function replaces CMake's 00128 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:set_target_properties"> 00129 # get_target_properties()</a> command and extends its functionality. 00130 # In particular, it maps the given @p TARGET_NAME to the corresponding target UID. 00131 # 00132 # @param [out] VAR Name of output variable. 00133 # @param [in] TARGET_NAME Name of build target. 00134 # @param [in] ARGN Remaining arguments for 00135 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:get_target_properties"> 00136 # get_target_properties()</a>. 00137 # 00138 # @returns Sets @p VAR to the value of the requested property. 00139 # 00140 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:get_target_property 00141 # 00142 # @ingroup CMakeAPI 00143 function (basis_get_target_property VAR TARGET_NAME) 00144 basis_get_target_uid (TARGET_UID "${TARGET_NAME}") 00145 get_target_property (VALUE "${TARGET_UID}" ${ARGN}) 00146 set (${VAR} "${VALUE}" PARENT_SCOPE) 00147 endfunction () 00148 00149 # ============================================================================ 00150 # definitions 00151 # ============================================================================ 00152 00153 # ---------------------------------------------------------------------------- 00154 ## @brief Add compile definitions. 00155 # 00156 # This function replaces CMake's 00157 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_definitions"> 00158 # add_definitions()</a> command. 00159 # 00160 # @param [in] ARGN List of arguments for 00161 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_definitions"> 00162 # add_definitions()</a>. 00163 # 00164 # @returns Adds the given definitions. 00165 # 00166 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_definitions 00167 # 00168 # @ingroup CMakeAPI 00169 function (basis_add_definitions) 00170 add_definitions (${ARGN}) 00171 endfunction () 00172 00173 # ---------------------------------------------------------------------------- 00174 ## @brief Remove previously added compile definitions. 00175 # 00176 # This function replaces CMake's 00177 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:remove_definitions"> 00178 # remove_definitions()</a> command. 00179 # 00180 # @param [in] ARGN List of arguments for 00181 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:remove_definitions"> 00182 # remove_definitions()</a>. 00183 # 00184 # @returns Removes the specified definitions. 00185 # 00186 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:remove_definition 00187 # 00188 # @ingroup CMakeAPI 00189 function (basis_remove_definitions) 00190 remove_definitions (${ARGN}) 00191 endfunction () 00192 00193 # ============================================================================ 00194 # directories 00195 # ============================================================================ 00196 00197 # ---------------------------------------------------------------------------- 00198 ## @brief Add directories to search path for include files. 00199 # 00200 # Overwrites CMake's 00201 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories"> 00202 # include_directories()</a> command. This is required because the 00203 # basis_include_directories() function is not used by other projects in their 00204 # package use files. Therefore, this macro is an alias for 00205 # basis_include_directories(). 00206 # 00207 # @param [in] ARGN List of arguments for basis_include_directories(). 00208 # 00209 # @returns Adds the given paths to the search path for include files. 00210 # 00211 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories 00212 macro (include_directories) 00213 basis_include_directories (${ARGN}) 00214 endmacro () 00215 00216 # ---------------------------------------------------------------------------- 00217 ## @brief Add directories to search path for include files. 00218 # 00219 # This function replaces CMake's 00220 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories"> 00221 # include_directories()</a> command. Besides invoking CMake's internal command 00222 # with the given arguments, it updates the @c PROJECT_INCLUDE_DIRECTORIES 00223 # property on the current project (see basis_set_project_property()). This list 00224 # contains a list of all include directories used by a project, regardless of 00225 # the directory in which the basis_include_directories() function was used. 00226 # 00227 # @param ARGN List of arguments for 00228 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories"> 00229 # include_directories()</a> command. 00230 # 00231 # @returns Nothing. 00232 # 00233 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:include_directories 00234 # 00235 # @ingroup CMakeAPI 00236 function (basis_include_directories) 00237 # CMake's include_directories () 00238 _include_directories (${ARGN}) 00239 00240 # parse arguments 00241 CMAKE_PARSE_ARGUMENTS (ARGN "AFTER;BEFORE;SYSTEM" "" "" ${ARGN}) 00242 00243 # make relative paths absolute 00244 set (DIRS) 00245 foreach (P IN LISTS ARGN_UNPARSED_ARGUMENTS) 00246 get_filename_component (P "${P}" ABSOLUTE) 00247 list (APPEND DIRS "${P}") 00248 endforeach () 00249 00250 if (DIRS) 00251 # append directories to "global" list of include directories 00252 basis_get_project_property (INCLUDE_DIRS PROPERTY PROJECT_INCLUDE_DIRS) 00253 if (BEFORE) 00254 list (INSERT INCLUDE_DIRS 0 ${DIRS}) 00255 else () 00256 list (APPEND INCLUDE_DIRS ${DIRS}) 00257 endif () 00258 if (INCLUDE_DIRS) 00259 list (REMOVE_DUPLICATES INCLUDE_DIRS) 00260 endif () 00261 if (BASIS_DEBUG) 00262 message ("** basis_include_directories():") 00263 if (BEFORE) 00264 message ("** Add before: ${DIRS}") 00265 else () 00266 message ("** Add after: ${DIRS}") 00267 endif () 00268 if (BASIS_VERBOSE) 00269 message ("** Directories: ${INCLUDE_DIRS}") 00270 endif () 00271 endif () 00272 basis_set_project_property (PROPERTY PROJECT_INCLUDE_DIRS ${INCLUDE_DIRS}) 00273 endif () 00274 endfunction () 00275 00276 # ---------------------------------------------------------------------------- 00277 ## @brief Add directories to search path for libraries. 00278 # 00279 # Overwrites CMake's 00280 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:link_directories"> 00281 # link_directories()</a> command. This is required because the 00282 # basis_link_directories() function is not used by other projects in their 00283 # package use files. Therefore, this macro is an alias for 00284 # basis_link_directories(). 00285 # 00286 # @param [in] ARGN List of arguments for basis_link_directories(). 00287 # 00288 # @returns Adds the given paths to the search path for libraries. 00289 # 00290 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:link_directories 00291 macro (link_directories) 00292 basis_link_directories (${ARGN}) 00293 endmacro () 00294 00295 # ---------------------------------------------------------------------------- 00296 ## @brief Add directories to search path for libraries. 00297 # 00298 # This function replaces CMake's 00299 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:link_directories"> 00300 # link_directories()</a> command. Even though this function yet only invokes 00301 # CMake's internal command, it should be used in BASIS projects to enable the 00302 # extension of this command's functionality as part of BASIS if required. 00303 # 00304 # @param [in] ARGN List of arguments for 00305 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:link_directories"> 00306 # link_directories()</a>. 00307 # 00308 # @returns Adds the given paths to the search path for libraries. 00309 # 00310 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:link_directories 00311 # 00312 # @ingroup CMakeAPI 00313 function (basis_link_directories) 00314 # CMake's link_directories() command 00315 _link_directories (${ARGN}) 00316 # make relative paths absolute 00317 set (DIRS) 00318 foreach (P IN LISTS ARGN) 00319 get_filename_component (P "${P}" ABSOLUTE) 00320 list (APPEND DIRS "${P}") 00321 endforeach () 00322 if (DIRS) 00323 # append directories to "global" list of link directories 00324 basis_get_project_property (LINK_DIRS PROPERTY PROJECT_LINK_DIRS) 00325 list (APPEND LINK_DIRS ${DIRS}) 00326 if (LINK_DIRS) 00327 list (REMOVE_DUPLICATES LINK_DIRS) 00328 endif () 00329 if (BASIS_DEBUG) 00330 message ("** basis_link_directories():") 00331 message ("** Add: [${DIRS}]") 00332 if (BASIS_VERBOSE) 00333 message ("** Directories: [${LINK_DIRS}]") 00334 endif () 00335 endif () 00336 basis_set_project_property (PROPERTY PROJECT_LINK_DIRS "${LINK_DIRS}") 00337 # if the directories are added by an external project's <Pkg>Use.cmake 00338 # file which is part of the same superbuild as this project, add the 00339 # directories further to the list of directories that may be added to 00340 # the RPATH. see basis_set_target_install_rpath(). 00341 if (BUNDLE_PROJECT) # set in basis_use_package() 00342 basis_get_project_property (LINK_DIRS PROPERTY BUNDLE_LINK_DIRS) 00343 list (APPEND LINK_DIRS ${DIRS}) 00344 if (LINK_DIRS) 00345 list (REMOVE_DUPLICATES LINK_DIRS) 00346 endif () 00347 basis_set_project_property (PROPERTY BUNDLE_LINK_DIRS "${LINK_DIRS}") 00348 endif () 00349 endif () 00350 endfunction () 00351 00352 # ============================================================================ 00353 # dependencies 00354 # ============================================================================ 00355 00356 # ---------------------------------------------------------------------------- 00357 ## @brief Add dependencies to build target. 00358 # 00359 # This function replaces CMake's 00360 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_dependencies"> 00361 # add_dependencies()</a> command and extends its functionality. 00362 # In particular, it maps the given target names to the corresponding target UIDs. 00363 # 00364 # @param [in] ARGN Arguments for 00365 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_dependencies"> 00366 # add_dependencies()</a>. 00367 # 00368 # @returns Adds the given dependencies of the specified build target. 00369 # 00370 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_dependencies 00371 # 00372 # @ingroup CMakeAPI 00373 function (basis_add_dependencies) 00374 set (ARGS) 00375 foreach (ARG ${ARGN}) 00376 basis_get_target_uid (UID "${ARG}") 00377 if (TARGET "${UID}") 00378 list (APPEND ARGS "${UID}") 00379 else () 00380 list (APPEND ARGS "${ARG}") 00381 endif () 00382 endforeach () 00383 add_dependencies (${ARGS}) 00384 endfunction () 00385 00386 # ---------------------------------------------------------------------------- 00387 ## @brief Add link dependencies to build target. 00388 # 00389 # This function replaces CMake's 00390 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries"> 00391 # target_link_libraries()</a> command. 00392 # 00393 # The main reason for replacing this function is to treat libraries such as 00394 # MEX-files which are supposed to be compiled into a MATLAB executable added 00395 # by basis_add_executable() special. In this case, these libraries are added 00396 # to the LINK_DEPENDS property of the given MATLAB Compiler target. Similarly, 00397 # executable scripts and modules written in a scripting language may depend 00398 # on other modules. 00399 # 00400 # Another reason is the mapping of build target names to fully-qualified 00401 # build target names as used by BASIS (see basis_get_target_uid()). 00402 # 00403 # Example: 00404 # @code 00405 # basis_add_library (MyMEXFunc MEX myfunc.c) 00406 # basis_add_executable (MyMATLABApp main.m) 00407 # basis_target_link_libraries (MyMATLABApp MyMEXFunc OtherMEXFunc.mexa64) 00408 # @endcode 00409 # 00410 # @param [in] TARGET_NAME Name of the target. 00411 # @param [in] ARGN Link libraries. 00412 # 00413 # @returns Adds link dependencies to the specified build target. 00414 # For custom targets, the given libraries are added to the 00415 # @c LINK_DEPENDS property of these targets, in particular. 00416 # 00417 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries 00418 # 00419 # @ingroup CMakeAPI 00420 function (basis_target_link_libraries TARGET_NAME) 00421 basis_get_target_uid (TARGET_UID "${TARGET_NAME}") 00422 if (NOT TARGET "${TARGET_UID}") 00423 message (FATAL_ERROR "basis_target_link_libraries(): Unknown target ${TARGET_UID}.") 00424 endif () 00425 # get type of named target 00426 get_target_property (BASIS_TYPE ${TARGET_UID} BASIS_TYPE) 00427 # substitute non-fully qualified target names 00428 set (ARGS) 00429 foreach (ARG ${ARGN}) 00430 basis_get_target_uid (UID "${ARG}") 00431 if (TARGET "${UID}") 00432 if (UID MATCHES "^${TARGET_UID}$") 00433 message (FATAL_ERROR "Cannot add link library as dependency of itself!") 00434 endif () 00435 list (APPEND ARGS "${UID}") 00436 else () 00437 list (APPEND ARGS "${ARG}") 00438 endif () 00439 endforeach () 00440 # get current link libraries 00441 if (BASIS_TYPE MATCHES "^EXECUTABLE$|^(SHARED|STATIC|MODULE)_LIBRARY$") 00442 get_target_property (DEPENDS ${TARGET_UID} BASIS_LINK_DEPENDS) 00443 else () 00444 get_target_property (DEPENDS ${TARGET_UID} LINK_DEPENDS) 00445 endif () 00446 if (NOT DEPENDS) 00447 set (DEPENDS) 00448 endif () 00449 # note that MCC does itself a dependency check and in case of scripts 00450 # the basis_get_target_link_libraries() function is used 00451 if (BASIS_TYPE MATCHES "MCC|SCRIPT") 00452 list (APPEND DEPENDS ${ARGS}) 00453 # otherwise 00454 else () 00455 list (APPEND DEPENDS ${ARGS}) 00456 # pull implicit dependencies (e.g., ITK uses this) 00457 set (DEPENDENCY_ADDED 1) 00458 while (DEPENDENCY_ADDED) 00459 set (DEPENDENCY_ADDED 0) 00460 foreach (LIB IN LISTS DEPENDS) 00461 foreach (LIB_DEPEND IN LISTS ${LIB}_LIB_DEPENDS) 00462 if (NOT LIB_DEPEND MATCHES "^$|^general$") 00463 string (REGEX REPLACE "^-l" "" LIB_DEPEND "${LIB_DEPEND}") 00464 list (FIND DEPENDS ${LIB_DEPEND} IDX) 00465 if (IDX EQUAL -1) 00466 list (APPEND DEPENDS ${LIB_DEPEND}) 00467 set (DEPENDENCY_ADDED 1) 00468 endif () 00469 endif () 00470 endforeach () 00471 endforeach () 00472 endwhile () 00473 endif () 00474 # update LINK_DEPENDS 00475 if (BASIS_TYPE MATCHES "^EXECUTABLE$|^(SHARED|STATIC|MODULE)_LIBRARY$") 00476 _set_target_properties (${TARGET_UID} PROPERTIES BASIS_LINK_DEPENDS "${DEPENDS}") 00477 target_link_libraries (${TARGET_UID} ${ARGS}) 00478 else () 00479 # FIXME cannot use LINK_DEPENDS for CMake targets as these depends are 00480 # otherwise added as is to the Makefile. therefore, consider renaming 00481 # LINK_DEPENDS in general to BASIS_LINK_DEPENDS. 00482 _set_target_properties (${TARGET_UID} PROPERTIES LINK_DEPENDS "${DEPENDS}") 00483 endif () 00484 endfunction () 00485 00486 # ============================================================================ 00487 # add targets 00488 # ============================================================================ 00489 00490 # ---------------------------------------------------------------------------- 00491 ## @brief Add custom target. 00492 macro (basis_add_custom_target TARGET_NAME) 00493 basis_check_target_name ("${TARGET_NAME}") 00494 basis_make_target_uid (_UID "${TARGET_NAME}") 00495 add_custom_target (${_UID} ${ARGN}) 00496 unset (_UID) 00497 endmacro () 00498 00499 # ---------------------------------------------------------------------------- 00500 ## @brief Add executable target. 00501 # 00502 # This is the main function to add an executable target to the build system, 00503 # where an executable can be a binary file or a script written in a scripting 00504 # language. In general we refer to any output file which is part of the software 00505 # (i.e., excluding configuration files) and which can be executed 00506 # (e.g., a binary file in the ELF format) or interpreted (e.g., a Python script) 00507 # directly, as executable file. Natively, CMake supports only executables built 00508 # from C/C++ source code files. This function extends CMake's capabilities 00509 # by adding custom build commands for non-natively supported programming 00510 # languages and further standardizes the build of executable targets. 00511 # For example, by default, it is not necessary to specify installation rules 00512 # separately as these are added by this function already (see below). 00513 # 00514 # @par Programming languages 00515 # Besides adding usual executable targets build by the set <tt>C/CXX</tt> 00516 # language compiler, this function inspects the list of source files given and 00517 # detects whether this list contains sources which need to be build using a 00518 # different compiler. In particular, it supports the following languages: 00519 # @n 00520 # <table border="0"> 00521 # <tr> 00522 # @tp @b CXX @endtp 00523 # <td>The default behavior, adding an executable target build from C/C++ 00524 # source code. The target is added via CMake's add_executable() command.</td> 00525 # </tr> 00526 # <tr> 00527 # @tp <b>PYTHON</b>|<b>JYTHON</b>|<b>PERL</b>|<b>BASH</b> @endtp 00528 # <td>Executables written in one of the named scripting languages are built by 00529 # configuring and/or copying the script files to the build tree and 00530 # installation tree, respectively. During the build step, certain strings 00531 # of the form \@VARIABLE\@ are substituted by the values set during the 00532 # configure step. How these CMake variables are set is specified by a 00533 # so-called script configuration, which itself is either a CMake script 00534 # file or a string of CMake code set as value of the @c COMPILE_DEFINITIONS 00535 # property of the executable target.</td> 00536 # </tr> 00537 # <tr> 00538 # @tp @b MATLAB @endtp 00539 # <td>Standalone application built from MATLAB sources using the 00540 # MATLAB Compiler (mcc). This language option is used when the list 00541 # of source files contains one or more *.m files. A custom target is 00542 # added which depends on custom command(s) that build the executable.</td> 00543 # @n@n 00544 # Attention: The *.m file with the entry point/main function of the 00545 # executable has to be given before any other *.m file. 00546 # </tr> 00547 # </table> 00548 # 00549 # @par Helper functions 00550 # If the programming language of the input source files is not specified 00551 # explicitly by providing the @p LANGUAGE argument, the extensions of the 00552 # source files and if necessary the first line of script files are inspected 00553 # by the basis_get_source_language() function. Once the programming language is 00554 # known, this function invokes the proper subcommand which adds the respective 00555 # build target. In particular, it calls basis_add_executable_target() for C++ 00556 # sources (.cxx), basis_add_mcc_target() for MATLAB scripts (.m), and 00557 # basis_add_script() for all other source files. 00558 # 00559 # @note DO NOT use the mentioned subcommands directly. Always use 00560 # basis_add_executable() to add an executable target to your project. 00561 # Only refer to the documentation of the subcommands to learn about the 00562 # available options of the particular subcommand and considered target 00563 # properties. 00564 # 00565 # @par Output directories 00566 # The built executable file is output to the @c BINARY_RUNTIME_DIR or 00567 # @c BINARY_LIBEXEC_DIR if the @p LIBEXEC option is given. 00568 # If this function is used within the @c PROJECT_TESTING_DIR, however, 00569 # the built executable is output to the @c TESTING_RUNTIME_DIR or 00570 # @c TESTING_LIBEXEC_DIR instead. 00571 # 00572 # @par Installation 00573 # An install command for the added executable target is added by this function 00574 # as well. The executable will be installed as part of the specified @p COMPONENT 00575 # in the directory @c INSTALL_RUNTIME_DIR or @c INSTALL_LIBEXEC_DIR if the option 00576 # @p LIBEXEC is given. Executable targets are exported by default such that they 00577 # can be imported by other CMake-aware projects by including the CMake 00578 # configuration file of this package (<Package>Config.cmake file). 00579 # No installation rules are added, however, if this function is used within the 00580 # @c PROJECT_TESTING_DIR or if "none" (case-insensitive) is given as 00581 # @p DESTINATION. Test executables are further only exported as part of the 00582 # build tree, but not the installation as they are by default not installed. 00583 # 00584 # @param [in] TARGET_NAME Name of the target. If an existing source file is given 00585 # as first argument, it is added to the list of source files 00586 # and the build target name is derived from the name of this file. 00587 # @param [in] ARGN This argument list is parsed and the following 00588 # arguments are extracted, all other arguments are passed 00589 # on to add_executable() or the respective custom 00590 # commands used to add an executable build target. 00591 # @par 00592 # <table border="0"> 00593 # <tr> 00594 # @tp @b COMPONENT name @endtp 00595 # <td>Name of component as part of which this executable will be installed 00596 # if the specified @c DESTINATION is not "none". 00597 # (default: @c BASIS_RUNTIME_COMPONENT)</td> 00598 # </tr> 00599 # <tr> 00600 # @tp @b DESTINATION dir @endtp 00601 # <td>Installation directory relative to @c CMAKE_INSTALL_PREFIX. 00602 # If "none" (case-insensitive) is given as argument, no default 00603 # installation rules are added for this executable target. 00604 # (default: @c INSTALL_RUNTIME_DIR or @c INSTALL_LIBEXEC_DIR 00605 # if the @p LIBEXEC option is given)</td> 00606 # </tr> 00607 # <tr> 00608 # @tp @b LANGUAGE lang @endtp 00609 # <td>Programming language in which source files are written (case-insensitive). 00610 # If not specified, the programming language is derived from the file name 00611 # extensions of the source files and, if applicable, the shebang directive 00612 # on the first line of the script file. If the programming language could 00613 # not be detected automatically, check the file name extensions of the 00614 # source files and whether no unrecognized additional arguments were given 00615 # or specify the programming language using this option. 00616 # (default: auto-detected)</td> 00617 # </tr> 00618 # <tr> 00619 # @tp @b LIBEXEC @endtp 00620 # <td>Specifies that the built executable is an auxiliary executable which 00621 # is only called by other executables. (default: @c FALSE)</td> 00622 # </tr> 00623 # <tr> 00624 # @tp @b [NO]EXPORT @endtp 00625 # <td>Whether to export this target. (default: @c TRUE)</td> 00626 # </tr> 00627 # <tr> 00628 # @tp @b NO_BASIS_UTILITIES @endtp 00629 # <td>Specify that the BASIS utilities are not used by this executable and hence 00630 # no link dependency on the BASIS utilities shall be added. 00631 # (default: @c NOT @c BASIS_UTILITIES)</td> 00632 # </tr> 00633 # <tr> 00634 # @tp @b USE_BASIS_UTILITIES @endtp 00635 # <td>Specify that the BASIS utilities are used and required by this executable 00636 # and hence a link dependency on the BASIS utilities has to be added. 00637 # (default: @c BASIS_UTILITIES)</td> 00638 # </tr> 00639 # </table> 00640 # 00641 # @returns Adds an executable build target. In case of an executable which is 00642 # not build from C++ source files, the function basis_finalize_targets() 00643 # has to be invoked to finalize the addition of the custom build target. 00644 # This is done at the end of the basis_project_impl() macro. 00645 # 00646 # @sa basis_add_executable_target() 00647 # @sa basis_add_script() 00648 # @sa basis_add_mcc_target() 00649 # 00650 # @ingroup CMakeAPI 00651 function (basis_add_executable TARGET_NAME) 00652 # -------------------------------------------------------------------------- 00653 # parse arguments 00654 CMAKE_PARSE_ARGUMENTS ( 00655 ARGN 00656 "EXECUTABLE;LIBEXEC;NO_BASIS_UTILITIES;USE_BASIS_UTILITIES;EXPORT;NOEXPORT" 00657 "COMPONENT;DESTINATION;LANGUAGE" 00658 "" 00659 ${ARGN} 00660 ) 00661 # derive target name from path if existing source path is given as first argument instead 00662 # and get list of library source files 00663 get_filename_component (S "${TARGET_NAME}" ABSOLUTE) 00664 if (IS_DIRECTORY "${S}" AND NOT ARGN_UNPARSED_ARGUMENTS) 00665 set (SOURCES "${S}") 00666 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME_WE) 00667 elseif (EXISTS "${S}" AND NOT IS_DIRECTORY "${S}" OR (NOT S MATCHES "\\.in$" AND EXISTS "${S}.in" AND NOT IS_DIRECTORY "${S}.in")) 00668 set (SOURCES "${S}") 00669 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME_WE) 00670 else () 00671 set (SOURCES) 00672 endif () 00673 if (ARGN_UNPARSED_ARGUMENTS) 00674 list (APPEND SOURCES ${ARGN_UNPARSED_ARGUMENTS}) 00675 endif () 00676 # -------------------------------------------------------------------------- 00677 # make target UID 00678 basis_check_target_name ("${TARGET_NAME}") 00679 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 00680 # -------------------------------------------------------------------------- 00681 # process globbing expressions to get complete list of source files 00682 basis_add_glob_target (${TARGET_UID} SOURCES ${SOURCES}) 00683 # -------------------------------------------------------------------------- 00684 # determine programming language 00685 if (NOT ARGN_LANGUAGE) 00686 basis_get_source_language (ARGN_LANGUAGE ${SOURCES}) 00687 if (ARGN_LANGUAGE MATCHES "AMBIGUOUS|UNKNOWN") 00688 message ("Target ${TARGET_UID}: Given source code files:") 00689 foreach (SOURCE IN LISTS SOURCES) 00690 message (" ${SOURCE}") 00691 endforeach () 00692 if (ARGN_LANGUAGE MATCHES "AMBIGUOUS") 00693 message (FATAL_ERROR "Target ${TARGET_UID}: Ambiguous source code files! Try to set LANGUAGE manually and make sure that no unknown option was given.") 00694 elseif (ARGN_LANGUAGE MATCHES "UNKNOWN") 00695 message (FATAL_ERROR "Target ${TARGET_UID}: Unknown source code language! Try to set LANGUAGE manually and make sure that no unknown option was given.") 00696 endif () 00697 endif () 00698 endif () 00699 string (TOUPPER "${ARGN_LANGUAGE}" ARGN_LANGUAGE) 00700 # -------------------------------------------------------------------------- 00701 # prepare arguments for subcommand 00702 foreach (ARG IN LISTS ARGN_UNPARSED_ARGUMENTS) 00703 list (REMOVE_ITEM ARGN "${ARG}") 00704 endforeach () 00705 list (APPEND ARGN ${SOURCES}) 00706 # -------------------------------------------------------------------------- 00707 # C++ 00708 if (ARGN_LANGUAGE MATCHES "CXX") 00709 basis_add_executable_target (${TARGET_NAME} ${ARGN}) 00710 # -------------------------------------------------------------------------- 00711 # MATLAB 00712 elseif (ARGN_LANGUAGE MATCHES "MATLAB") 00713 if (ARGN_LIBEXEC) 00714 list (REMOVE_ITEM ARGN LIBEXEC) 00715 basis_add_mcc_target (${TARGET_NAME} LIBEXEC ${ARGN}) 00716 else () 00717 list (REMOVE_ITEM ARGN EXECUTABLE) 00718 basis_add_mcc_target (${TARGET_NAME} EXECUTABLE ${ARGN}) 00719 endif () 00720 # -------------------------------------------------------------------------- 00721 # others 00722 else () 00723 if (ARGN_LIBEXEC) 00724 list (REMOVE_ITEM ARGN LIBEXEC) 00725 basis_add_script (${TARGET_NAME} LIBEXEC ${ARGN}) 00726 else () 00727 list (REMOVE_ITEM ARGN EXECUTABLE) 00728 basis_add_script (${TARGET_NAME} EXECUTABLE ${ARGN}) 00729 endif () 00730 endif () 00731 # -------------------------------------------------------------------------- 00732 # re-glob source files before each build (if necessary) 00733 if (TARGET __${TARGET_UID}) 00734 if (TARGET _${TARGET_UID}) 00735 add_dependencies (_${TARGET_UID} __${TARGET_UID}) 00736 endif () 00737 add_dependencies (${TARGET_UID} __${TARGET_UID}) 00738 endif () 00739 endfunction () 00740 00741 # ---------------------------------------------------------------------------- 00742 ## @brief Add library target. 00743 # 00744 # This is the main function to add a library target to the build system, where 00745 # a library can be a binary archive, shared library, a MEX-file or module(s) 00746 # written in a scripting language. In general we refer to any output file which 00747 # is part of the software (i.e., excluding configuration files), but cannot be 00748 # executed (e.g., a binary file in the ELF format) or interpreted 00749 # (e.g., a Python module) directly, as library file. Natively, CMake supports only 00750 # libraries built from C/C++ source code files. This function extends CMake's 00751 # capabilities by adding custom build commands for non-natively supported 00752 # programming languages and further standardizes the build of library targets. 00753 # For example, by default, it is not necessary to specify installation rules 00754 # separately as these are added by this function already (see below). 00755 # 00756 # @par Programming languages 00757 # Besides adding usual library targets built from C/C++ source code files, 00758 # this function can also add custom build targets for libraries implemented 00759 # in other programming languages. It therefore tries to detect the programming 00760 # language of the given source code files and delegates the addition of the 00761 # build target to the proper helper functions. It in particular supports the 00762 # following languages: 00763 # @n 00764 # <table border="0"> 00765 # <tr> 00766 # @tp @b CXX @endtp 00767 # <td>Source files written in C/C++ are by default built into either 00768 # @p STATIC, @p SHARED, or @p MODULE libraries. If the @p MEX option 00769 # is given, however, a MEX-file (a shared library) is build using 00770 # the MEX script instead of using the default C++ compiler directly.</td> 00771 # </tr> 00772 # <tr> 00773 # @tp <b>PYTHON</b>|<b>JYTHON</b>|<b>PERL</b>|<b>BASH</b> @endtp 00774 # <td>Modules written in one of the named scripting languages are built similar 00775 # to executable scripts except that the file name extension is preserved 00776 # and no executable file permission is set on Unix. These modules are 00777 # intended for import/inclusion in other modules or executables written 00778 # in the particular scripting language only.</td> 00779 # </tr> 00780 # <tr> 00781 # @tp @b MATLAB @endtp 00782 # <td>Libraries of M-files or shared libraries built using the MATLAB Compiler (mcc). 00783 # This language option is used when the list of source files contains one or 00784 # more *.m files. A custom target is added which depends on custom command(s) 00785 # that build the library. If the type of the library is @c SHARED, a shared 00786 # library is build using the MATLAB Compiler. Otherwise, the M-files are 00787 # configured and installed such that they can be used in MATLAB.</td> 00788 # </tr> 00789 # </table> 00790 # 00791 # @par Helper functions 00792 # If the programming language of the input source files is not specified 00793 # explicitly by providing the @p LANGUAGE argument, the extensions of the 00794 # source files are inspected using basis_get_source_language(). Once the 00795 # programming language is known, this function invokes the proper subcommand. 00796 # In particular, it calls basis_add_library_target() for C++ sources (.cxx) 00797 # if the target is not a MEX-file target, basis_add_mex_file() for C++ sources 00798 # if the @p MEX option is given, basis_add_mcc_target() for MATLAB scripts (.m), 00799 # and basis_add_script_library() for all other source files. 00800 # 00801 # @note DO NOT use the mentioned subcommands directly. Always use 00802 # basis_add_library() to add a library target to your project. Only refer 00803 # to the documentation of the subcommands to learn about the available 00804 # options of the particular subcommand and the considered target properties. 00805 # 00806 # @par Output directories 00807 # In case of modules written in a scripting language, the libraries are output to 00808 # the <tt>BINARY_<LANGUAGE>_LIBRARY_DIR</tt> if defined. Otherwise, 00809 # the built libraries are output to the @c BINARY_RUNTIME_DIR, @c BINARY_LIBRARY_DIR, 00810 # and/or @c BINARY_ARCHIVE_DIR. If this command is used within the @c PROJECT_TESTING_DIR, 00811 # however, the files are output to the corresponding directories in the testing tree, 00812 # instead. 00813 # 00814 # @par Installation 00815 # An installation rule for the added library target is added by this function 00816 # if the destination is not "none" (case-insensitive). Runtime libraries are 00817 # installed as part of the @p RUNTIME_COMPONENT to the @p RUNTIME_DESTINATION. 00818 # Library components are installed as part of the @p LIBRARY_COMPONENT to the 00819 # @p LIBRARY_DESTINATION. Library targets are further exported such that they 00820 # can be imported by other CMake-aware projects by including the CMake 00821 # configuration file of this package (<Package>Config.cmake file). 00822 # If this function is used within the @c PROJECT_TESTING_DIR, however, no 00823 # installation rules are added. Test library targets are further only exported 00824 # as part of the build tree. 00825 # 00826 # @par Example 00827 # @code 00828 # basis_add_library (MyLib1 STATIC mylib.cxx) 00829 # basis_add_library (MyLib2 STATIC mylib.cxx COMPONENT dev) 00830 # 00831 # basis_add_library ( 00832 # MyLib3 SHARED mylib.cxx 00833 # RUNTIME_COMPONENT bin 00834 # LIBRARY_COMPONENT dev 00835 # ) 00836 # 00837 # basis_add_library (MyMex MEX mymex.cxx) 00838 # basis_add_library (PythonModule MyModule.py.in) 00839 # basis_add_library (ShellModule MODULE MyModule.sh.in) 00840 # @endcode 00841 # 00842 # @param [in] TARGET_NAME Name of build target. If an existing file is given as 00843 # argument, it is added to the list of source files and 00844 # the target name is derived from the name of this file. 00845 # @param [in] ARGN This argument list is parsed and the following 00846 # arguments are extracted. All unparsed arguments are 00847 # treated as source files. 00848 # @par 00849 # <table border="0"> 00850 # <tr> 00851 # @tp <b>STATIC</b>|<b>SHARED</b>|<b>MODULE</b>|<b>MEX</b> @endtp 00852 # <td>Type of the library. (default: @c SHARED for C++ libraries if 00853 # @c BUILD_SHARED_LIBS evaluates to true or @c STATIC otherwise, 00854 # and @c MODULE in all other cases)</td> 00855 # </tr> 00856 # <tr> 00857 # @tp @b COMPONENT name @endtp 00858 # <td>Name of component as part of which this library will be installed 00859 # if the @c RUNTIME_DESTINATION or @c LIBRARY_DESTINATION is not "none". 00860 # Used only if @p RUNTIME_COMPONENT or @p LIBRARY_COMPONENT not specified. 00861 # (default: see @p RUNTIME_COMPONENT and @p LIBRARY_COMPONENT)</td> 00862 # </tr> 00863 # <tr> 00864 # @tp @b DESTINATION dir @endtp 00865 # <td>Installation directory for runtime and library component relative 00866 # to @c CMAKE_INSTALL_PREFIX. Used only if @p RUNTIME_DESTINATION or 00867 # @p LIBRARY_DESTINATION not specified. If "none" (case-insensitive) 00868 # is given as argument, no default installation rules are added. 00869 # (default: see @p RUNTIME_DESTINATION and @p LIBRARY_DESTINATION)</td> 00870 # </tr> 00871 # <tr> 00872 # @tp @b LANGUAGE lang @endtp 00873 # <td>Programming language in which source files are written (case-insensitive). 00874 # If not specified, the programming language is derived from the file name 00875 # extensions of the source files and, if applicable, the shebang directive 00876 # on the first line of the script file. If the programming language could 00877 # not be detected automatically, check the file name extensions of the 00878 # source files and whether no unrecognized additional arguments were given 00879 # or specify the programming language using this option. 00880 # (default: auto-detected)</td> 00881 # </tr> 00882 # <tr> 00883 # @tp @b LIBRARY_COMPONENT name @endtp 00884 # <td>Name of component as part of which import/static library will be intalled 00885 # if @c LIBRARY_DESTINATION is not "none". 00886 # (default: @c COMPONENT if specified or @c BASIS_LIBRARY_COMPONENT otherwise)</td> 00887 # </tr> 00888 # <tr> 00889 # @tp @b LIBRARY_DESTINATION dir @endtp 00890 # <td>Installation directory of the library component relative to 00891 # @c CMAKE_INSTALL_PREFIX. If "none" (case-insensitive) is given as argument, 00892 # no installation rule for the library component is added. 00893 # (default: @c INSTALL_ARCHIVE_DIR)</td> 00894 # </tr> 00895 # <tr> 00896 # @tp @b RUNTIME_COMPONENT name @endtp 00897 # <td>Name of component as part of which runtime library will be installed 00898 # if @c RUNTIME_DESTINATION is not "none". 00899 # (default: @c COMPONENT if specified or @c BASIS_RUNTIME_COMPONENT otherwise)</td> 00900 # </tr> 00901 # <tr> 00902 # @tp @b RUNTIME_DESTINATION dir @endtp 00903 # <td>Installation directory of the runtime component relative to 00904 # @c CMAKE_INSTALL_PREFIX. If "none" (case-insensitive) is given as argument, 00905 # no installation rule for the runtime library is added. 00906 # (default: @c INSTALL_LIBRARY_DIR on Unix or @c INSTALL_RUNTIME_DIR Windows)</td> 00907 # </tr> 00908 # <tr> 00909 # @tp @b [NO]EXPORT @endtp 00910 # <td>Whether to export this target. (default: @c TRUE)</td> 00911 # </tr> 00912 # <tr> 00913 # @tp @b NO_BASIS_UTILITIES @endtp 00914 # <td>Specify that the BASIS utilities are not used by this executable and hence 00915 # no link dependency on the BASIS utilities shall be added. 00916 # (default: @c NOT @c BASIS_UTILITIES)</td> 00917 # </tr> 00918 # <tr> 00919 # @tp @b USE_BASIS_UTILITIES @endtp 00920 # <td>Specify that the BASIS utilities are used and required by this executable 00921 # and hence a link dependency on the BASIS utilities has to be added. 00922 # (default: @c BASIS_UTILITIES)</td> 00923 # </tr> 00924 # </table> 00925 # 00926 # @returns Adds a library build target. In case of a library not written in C++ 00927 # or MEX-file targets, basis_finalize_targets() has to be invoked 00928 # to finalize the addition of the build target(s). This is done 00929 # at the end of the basis_project_impl() macro. 00930 # 00931 # @sa basis_add_library_target() 00932 # @sa basis_add_script_library() 00933 # @sa basis_add_mex_file() 00934 # @sa basis_add_mcc_target() 00935 # 00936 # @ingroup CMakeAPI 00937 function (basis_add_library TARGET_NAME) 00938 # -------------------------------------------------------------------------- 00939 # parse arguments 00940 CMAKE_PARSE_ARGUMENTS ( 00941 ARGN 00942 "STATIC;SHARED;MODULE;MEX;USE_BASIS_UTILITIES;NO_BASIS_UTILITIES;EXPORT;NOEXPORT" 00943 "COMPONENT;RUNTIME_COMPONENT;LIBRARY_COMPONENT;DESTINATION;RUNTIME_DESTINATION;LIBRARY_DESTINATION;LANGUAGE" 00944 "" 00945 ${ARGN} 00946 ) 00947 # derive target name from path if existing source path is given as first argument instead 00948 # and get list of library source files 00949 get_filename_component (S "${TARGET_NAME}" ABSOLUTE) 00950 if (IS_DIRECTORY "${S}" AND NOT ARGN_UNPARSED_ARGUMENTS) 00951 set (SOURCES "${S}") 00952 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME) 00953 elseif (EXISTS "${S}" AND NOT IS_DIRECTORY "${S}" OR (NOT S MATCHES "\\.in$" AND EXISTS "${S}.in" AND NOT IS_DIRECTORY "${S}.in")) 00954 set (SOURCES "${S}") 00955 if (ARGN_MEX) 00956 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME_WE) 00957 else () 00958 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME) 00959 endif () 00960 else () 00961 set (SOURCES) 00962 endif () 00963 if (ARGN_UNPARSED_ARGUMENTS) 00964 list (APPEND SOURCES ${ARGN_UNPARSED_ARGUMENTS}) 00965 endif () 00966 # -------------------------------------------------------------------------- 00967 # make target UID 00968 basis_check_target_name ("${TARGET_NAME}") 00969 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 00970 # -------------------------------------------------------------------------- 00971 # process globbing expressions to get complete list of source files 00972 basis_add_glob_target (${TARGET_UID} SOURCES ${SOURCES}) 00973 # -------------------------------------------------------------------------- 00974 # determine programming language 00975 if (NOT ARGN_LANGUAGE) 00976 basis_get_source_language (ARGN_LANGUAGE ${SOURCES}) 00977 if (ARGN_LANGUAGE MATCHES "AMBIGUOUS|UNKNOWN") 00978 message ("Target ${TARGET_UID}: Given source code files:") 00979 foreach (SOURCE IN LISTS SOURCES) 00980 message (" ${SOURCE}") 00981 endforeach () 00982 if (ARGN_LANGUAGE MATCHES "AMBIGUOUS") 00983 message (FATAL_ERROR "Target ${TARGET_UID}: Ambiguous source code files! Try to set LANGUAGE manually and make sure that no unknown option was given.") 00984 elseif (ARGN_LANGUAGE MATCHES "UNKNOWN") 00985 message (FATAL_ERROR "Target ${TARGET_UID}: Unknown source code language! Try to set LANGUAGE manually and make sure that no unknown option was given.") 00986 endif () 00987 endif () 00988 endif () 00989 string (TOUPPER "${ARGN_LANGUAGE}" ARGN_LANGUAGE) 00990 # -------------------------------------------------------------------------- 00991 # prepare arguments for subcommand 00992 foreach (ARG IN LISTS ARGN_UNPARSED_ARGUMENTS) 00993 list (REMOVE_ITEM ARGN "${ARG}") 00994 endforeach () 00995 list (APPEND ARGN ${SOURCES}) 00996 # -------------------------------------------------------------------------- 00997 # C++ 00998 if (ARGN_LANGUAGE MATCHES "CXX") 00999 # MEX-file 01000 if (ARGN_MEX) 01001 if (ARGN_STATIC) 01002 message (FATAL_ERROR "Target ${TARGET_UID}: Invalid library type! Only modules or shared libraries can be built by the MEX script.") 01003 endif () 01004 list (REMOVE_ITEM ARGN MODULE) 01005 list (REMOVE_ITEM ARGN SHARED) 01006 list (REMOVE_ITEM ARGN MEX) 01007 basis_add_mex_file (${TARGET_NAME} ${ARGN}) 01008 # library 01009 else () 01010 basis_add_library_target (${TARGET_NAME} ${ARGN}) 01011 endif () 01012 # -------------------------------------------------------------------------- 01013 # MATLAB 01014 elseif (ARGN_LANGUAGE MATCHES "MATLAB") 01015 if (ARGN_STATIC OR ARGN_MEX) 01016 message (FATAL_ERROR "Target ${TARGET_UID}: Invalid library type! Only shared libraries can be built by the MATLAB Compiler.") 01017 endif () 01018 if (ARGN_SHARED) 01019 list (REMOVE_ITEM ARGN SHARED) 01020 basis_add_mcc_target (${TARGET_NAME} SHARED ${ARGN}) 01021 else () 01022 list (REMOVE_ITEM ARGN MODULE) # optional 01023 basis_add_script_library (${TARGET_NAME} ${ARGN}) 01024 endif () 01025 # -------------------------------------------------------------------------- 01026 # other 01027 else () 01028 if (ARGN_STATIC OR ARGN_SHARED OR ARGN_MEX) 01029 message (FATAL_ERROR "Target ${TARGET_UID}: Invalid library type! Only modules can be built from scripts.") 01030 endif () 01031 list (REMOVE_ITEM ARGN MODULE) 01032 basis_add_script_library (${TARGET_NAME} ${ARGN}) 01033 endif () 01034 # -------------------------------------------------------------------------- 01035 # re-glob source files before each build (if necessary) 01036 if (TARGET __${TARGET_UID}) 01037 add_dependencies (${TARGET_UID} __${TARGET_UID}) 01038 endif () 01039 endfunction () 01040 01041 # ---------------------------------------------------------------------------- 01042 ## @brief Add single arbitrary or executable script. 01043 # 01044 # @note This function should not be used directly for executable scripts or 01045 # module libraries. Use basis_add_executable() or basis_add_library() 01046 # in such (most) cases instead. 01047 # 01048 # This function can be used to add a single arbitrary script file (i.e., any 01049 # text file which is input to a program), such as a CTest script for example, 01050 # to the build if neither basis_add_executable() nor basis_add_library() are 01051 # appropriate choices. In all other cases, either basis_add_executable() or 01052 # basis_add_library() should be used. Note that the script file is by default 01053 # not considered to be an executable. Instead it is assumed that the program 01054 # which interprets/processes the script must be executed explicitly with this 01055 # script as argument. Only scripts built with the @p EXECUTABLE or @p LIBEXEC 01056 # type option are treated as executable files, where in case of Unix a shebang 01057 # directive implicitly states the program used by the shell to interpret the 01058 # script and on Windows a Windows Command which imitates the behavior of Unix 01059 # shells is generated by BASIS. Do not use these type options, however, but 01060 # only use the default @p MODULE option. The basis_add_executable() function 01061 # should be used instead to add an executable script. The basis_add_script() 01062 # function shall only be used for none-executable arbitrary script files which 01063 # cannot be built by basis_add_executable() or basis_add_library(). 01064 # 01065 # If the script name ends in <tt>.in</tt>, the <tt>.in</tt> suffix is removed 01066 # from the output name. Further, in case of executable scripts, the file name 01067 # extension is removed from the output file name. Instead, a shebang directive 01068 # is added on Unix to the built script. In order to enable the convenient 01069 # execution of Python and Perl scripts also on Windows without requiring the 01070 # user to setup a proper associate between the filename extension with the 01071 # corresponding interpreter executable, a few lines of Batch code are added at 01072 # the top and bottom of executable Python and Perl scripts. This Batch code 01073 # invokes the configured interpreter with the script file and the given script 01074 # arguments as command-line arguments. Note that both the original script source 01075 # code and the Batch code are stored within the single file. The file name 01076 # extension of such modified scripts is by default set to <tt>.cmd</tt>, the 01077 # common extension for Windows NT Command Scripts. Scripts in other languages 01078 # are not modified and the extension of the original scripts script file is 01079 # preserved on Windows in this case. In case of non-executable scripts, the 01080 # file name extension is kept in any case. 01081 # 01082 # Certain CMake variables within the source file are replaced during the 01083 # built of the script. See the 01084 # <a href="http://www.rad.upenn.edu/sbia/software/basis/scripttargets/> 01085 # Build System Standard</a> for details. 01086 # Note, however, that source files are only configured if the file name 01087 # ends in the <tt>.in</tt> suffix. 01088 # 01089 # A custom CMake build target with the following properties is added by this 01090 # function to the build system. These properties are used by basis_build_script() 01091 # to generate a build script written in CMake code which is executed by a custom 01092 # CMake command. Before the invokation of basis_build_script(), the target 01093 # properties can be modified using basis_set_target_properties(). 01094 # 01095 # @note Custom BASIS build targets are finalized by BASIS at the end of 01096 # basis_project_impl(), i.e., the end of the root CMake configuration file 01097 # of the (sub-)project. 01098 # 01099 # @par Properties on script targets 01100 # <table border=0> 01101 # <tr> 01102 # @tp @b BASIS_TYPE @endtp 01103 # <td>Read-only property with value "SCRIPT_FILE" for arbitrary scripts, 01104 # "SCRIPT_EXECUTABLE" for executable scripts, and "SCRIPT_LIBEXEC" for 01105 # auxiliary executable scripts. 01106 # (default: see @p MODULE, @p EXECUTABLE, @p LIBEXEC options)</td> 01107 # </tr> 01108 # <tr> 01109 # @tp @b BASIS_UTILITIES @endtp 01110 # <td>Whether the BASIS utilities are used by this script. For the supported 01111 # scripting languages for which BASIS utilities are implemented, BASIS 01112 # will in most cases automatically detect whether these utilities are 01113 # used by a script or not. Otherwise, set this property manually or use 01114 # either the @p USE_BASIS_UTILITIES or the @p NO_BASIS_UTILITIES option 01115 # when adding the script target. (default: auto-detected or @c UNKNOWN)</td> 01116 # </tr> 01117 # <tr> 01118 # @tp @b BINARY_DIRECTORY @endtp 01119 # <td>Build tree directory of this target. (default: @c CMAKE_CURRENT_BINARY_DIR)</td> 01120 # </tr> 01121 # <tr> 01122 # @tp @b COMPILE @endtp 01123 # <td>Whether to compile the script if the programming language allows such 01124 # pre-compilation as in case of Python, for example. If @c TRUE, only the 01125 # compiled file is installed. (default: @c BASIS_COMPILE_SCRIPTS)</td> 01126 # </tr> 01127 # <tr> 01128 # @tp @b COMPILE_DEFINITIONS @endtp 01129 # <td>CMake code which is evaluated after the inclusion of the default script 01130 # configuration files. This code can be used to set the replacement text of the 01131 # CMake variables ("@VAR@" patterns) used in the source file. 01132 # See <a href="https://www.cbica.upenn.edu/sbia/software/basis/standard/scripttargets.html#script-configuration"> 01133 # Build System Standard</a> for details. (default: "")</td> 01134 # </tr> 01135 # <tr> 01136 # @tp @b COMPILE_DEFINITIONS_FILE @endtp 01137 # <td>CMake script file with compile definitions, also referred to as script 01138 # configuration file. The named files are included after the default BASIS 01139 # script configuration and before the @c COMPILE_DEFINITIONS code is being 01140 # evaluated. (default: @c BINARY_CONFIG_DIR/ScriptConfig.cmake)</td> 01141 # </tr> 01142 # <tr> 01143 # @tp @b COMPONENT @endtp 01144 # <td>Name of component as part of which this script is installed if 01145 # @c INSTALL_DIRECTORY is not set to "none". 01146 # (default: see @p COMPONENT argument)</td> 01147 # </tr> 01148 # <tr> 01149 # @tp @b EXPORT @endtp 01150 # <td>Whether to export this build target in which case an import library 01151 # target is added to the custom exports file with the path to the 01152 # built/installed script set as @c IMPORT_LOCATION. (default: @c TRUE)</td> 01153 # </tr> 01154 # <tr> 01155 # @tp @b INSTALL_DIRECTORY @endtp 01156 # <td>Installation directory of script file configured for use in installation tree 01157 # relative to @c CMAKE_INSTALL_PREFIX. Set to "none" (case-insensitive) to skip the 01158 # addition of an installation rule. (default: see @p DESTINATION argument)</td> 01159 # </tr> 01160 # <tr> 01161 # @tp @b LANGUAGE @endtp 01162 # <td>Read-only property of programming language of script file in uppercase letters. 01163 # (default: see @p LANGUAGE argument)</td> 01164 # </tr> 01165 # <tr> 01166 # @tp @b LINK_DEPENDS @endtp 01167 # <td>Paths or target names of script modules and libraries used by this script. 01168 # In case of an (auxiliary) executable script, the directories of these modules 01169 # are added to the search path for modules of the given programming language 01170 # if such search paths are supported by the language and BASIS knows how to set 01171 # these (as in case of Python/Jython, Perl, and MATLAB, in particular). 01172 # Moreover, for each listed build target a dependency is added between this 01173 # script target and the named build targets. Use basis_target_link_libraries() 01174 # to add additional link dependencies. 01175 # (default: BASIS utilities module if used or empty list otherwise)</td> 01176 # </tr> 01177 # <tr> 01178 # @tp @b OUTPUT_DIRECTORY @endtp 01179 # <td>Output directory for built script file configured for use in build tree. 01180 # (default: @c BINARY_LIBRARY_DIR for arbitrary scripts, @c BINARY_RUNTIME_DIR 01181 # for executable scripts, and @c BINARY_LIBEXEC_DIR for auxiliary executables)</td> 01182 # </tr> 01183 # <tr> 01184 # @tp @b OUTPUT_NAME @endtp 01185 # <td>Name of built script file including file name extension (if any). 01186 # (default: basename of script file for arbitrary scripts, without extension 01187 # for executable scripts on Unix, and <tt>.cmd</tt> extension on Windows 01188 # in case of executable Python/Jython or Perl script)</td> 01189 # </tr> 01190 # <tr> 01191 # @tp @b SOURCE_DIRECTORY @endtp 01192 # <td>Source directory of this target. (default: @c CMAKE_CURRENT_SOURCE_DIR)</td> 01193 # </tr> 01194 # <tr> 01195 # @tp @b SOURCES @endtp 01196 # <td>Read-only property which lists the source file of this script target. 01197 # Note that the first element in this list actually names a directory 01198 # in the build, the one where the build script for this target is located 01199 # instead of a source file and thus should be ignored. The second entry 01200 # corresponds to the source file of this script target.</td> 01201 # </tr> 01202 # </table> 01203 # 01204 # @attention Properties documented as read-only must not be modified. 01205 # 01206 # @note If this function is used within the @c PROJECT_TESTING_DIR, the built 01207 # executable is output to the @c BINARY_TESTING_DIR directory tree instead. 01208 # Moreover, no installation rules are added. Test executables are further 01209 # not exported, regardless of the @c EXPORT property. 01210 # 01211 # @param [in] TARGET_NAME Name of build target. If an existing file is given as 01212 # argument, it is added to the list of source files and 01213 # the target name is derived from the name of this file. 01214 # @param [in] ARGN The remaining arguments are parsed and the following arguments 01215 # recognized. All unparsed arguments are treated as source files, 01216 # where in particular exactly one source file is required if the 01217 # @p TARGET_NAME argument does not name an existing source file. 01218 # @par 01219 # <table border=0> 01220 # <tr> 01221 # @tp <b>MODULE</b>|<b>EXECUTABLE</b>|<b>LIBEXEC</b> @endtp 01222 # <td>Type of script to built, i.e., either arbitrary module script which 01223 # cannot be executed directly, an executable script with proper shebang 01224 # directive and execute permissions on Unix or Windows Command on Windows, 01225 # or an auxiliary executable. The type of the script mainly changes the 01226 # default values of the target properties such as the output and installation 01227 # directories. To add an (auxiliary) executable script, use 01228 # basis_add_executable(), however, instead of this function. 01229 # The @c EXECUTABLE and @c LIBEXEC options are only intended for 01230 # internal use by BASIS. (default: MODULE)</td> 01231 # </tr> 01232 # <tr> 01233 # @tp @b COMPONENT name @endtp 01234 # <td>Name of installation component as part of which this script is being 01235 # installed if the @c INSTALL_DIRECTORY property is not "none". 01236 # (default: @c BASIS_LIBRARY_COMPONENT for arbitrary scripts or 01237 # @c BASIS_RUNTIME_COMPONENT for executable scripts)</td> 01238 # </tr> 01239 # <tr> 01240 # @tp @b DESTINATION dir @endtp 01241 # <td>Installation directory for script file relative to @c CMAKE_INSTALL_PREFIX. 01242 # If an absolute path is given as argument, it is made relative to the 01243 # configured installation prefix. 01244 # (default: @c INSTALL_LIBRARY_DIR for arbitrary scripts, 01245 # @c INSTALL_RUNTIME_DIR for executable scripts, and @c INSTALL_LIBEXEC_DIR 01246 # for auxiliary executable scripts)</td> 01247 # </tr> 01248 # <tr> 01249 # @tp @b LANGUAGE lang @endtp 01250 # <td>Programming language in which script file is written (case-insensitive). 01251 # If not specified, the programming language is derived from the file name 01252 # extension of the source file and the shebang directive on the first line 01253 # of the script if any. If the programming language could not be detected 01254 # automatically, the @c LANGUAGE property is set to @c UNKNOWN. Note that 01255 # for arbitrary script targets, the script file will still be built correctly 01256 # even if the scripting language was not recognized. The automatic detection 01257 # whether the BASIS utilities are used and required will fail, however. 01258 # In this case, specify the programming language using this option. 01259 # (default: auto-detected or @c UNKNOWN)</td> 01260 # </tr> 01261 # <tr> 01262 # @tp @b [NO]EXPORT @endtp 01263 # <td>Whether to export this target. (default: @c TRUE)</td> 01264 # </tr> 01265 # <tr> 01266 # @tp @b NO_BASIS_UTILITIES @endtp 01267 # <td>Specify that the BASIS utilities are not used by this script. If the 01268 # programming language of the script is known and BASIS utilities are 01269 # available for this language, BASIS will in most cases automatically 01270 # detect whether these utilities are used by a script or not. Use this 01271 # option to skip this check because the script does not make use of the 01272 # BASIS utilities.</td> 01273 # </tr> 01274 # <tr> 01275 # @tp @b USE_BASIS_UTILITIES @endtp 01276 # <td>Specify that the BASIS utilities are used and thus required by this script. 01277 # If the programming language of the script is known and BASIS utilities are 01278 # available for this language, BASIS will in most cases automatically 01279 # detect whether these utilities are used by a script or not. Use this option 01280 # to skip this check because it is already known that the script makes use of 01281 # the BASIS utilities. Note that an error is raised if this option is given, 01282 # but no BASIS utilities are available for the programming language of this 01283 # script or if the programming language is unknown, respectively, not detected 01284 # correctly. In this case, consider the use of the @p LANGUAGE argument.</td> 01285 # </tr> 01286 # </table> 01287 # 01288 # @returns Adds a custom CMake target with the documented properties. The actual custom 01289 # command to build the script is added by basis_build_script(). 01290 # 01291 # @ingroup CMakeAPI 01292 function (basis_add_script TARGET_NAME) 01293 # parse arguments 01294 CMAKE_PARSE_ARGUMENTS ( 01295 ARGN 01296 "MODULE;EXECUTABLE;LIBEXEC;NO_BASIS_UTILITIES;USE_BASIS_UTILITIES;EXPORT;NOEXPORT" 01297 "COMPONENT;DESTINATION;LANGUAGE" 01298 "" 01299 ${ARGN} 01300 ) 01301 if (NOT ARGN_MODULE AND NOT ARGN_EXECUTABLE AND NOT ARGN_LIBEXEC) 01302 set (ARGN_MODULE TRUE) 01303 endif () 01304 if (ARGN_MODULE) 01305 set (TYPE MODULE) 01306 else () 01307 set (TYPE EXECUTABLE) 01308 endif () 01309 string (TOLOWER "${TYPE}" type) 01310 # derive target name from file name if existing source file given as first argument 01311 get_filename_component (S "${TARGET_NAME}" ABSOLUTE) 01312 if (EXISTS "${S}" AND NOT IS_DIRECTORY "${S}" OR (NOT S MATCHES "\\.in$" AND EXISTS "${S}.in" AND NOT IS_DIRECTORY "${S}.in")) 01313 set (SOURCES "${S}") 01314 if (ARGN_MODULE) 01315 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME) 01316 else () 01317 basis_get_source_target_name (TARGET_NAME "${TARGET_NAME}" NAME_WE) 01318 endif () 01319 else () 01320 set (SOURCES) 01321 set (OUTPUT_NAME "${TARGET_NAME}") 01322 endif () 01323 # check target name 01324 basis_check_target_name ("${TARGET_NAME}") 01325 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 01326 message (STATUS "Adding ${type} script ${TARGET_UID}...") 01327 if (ARGN_MODULE AND TYPE MATCHES "EXECUTABLE") 01328 message (FATAL_ERROR "Target ${TARGET_UID}: MODULE and EXECUTABLE or LIBEXEC options are mutually exclusive!") 01329 endif () 01330 # check/set parsed arguments 01331 basis_set_flag (ARGN EXPORT ${BASIS_EXPORT}) 01332 if (ARGN_USE_BASIS_UTILITIES AND ARGN_NO_BASIS_UTILITIES) 01333 message (FATAL_ERROR "Options USE_BASIS_UTILITIES and NO_BASIS_UTILITIES are mutually exclusive!") 01334 endif () 01335 list (LENGTH ARGN_UNPARSED_ARGUMENTS N) 01336 if (SOURCES) 01337 math (EXPR N "${N} + 1") 01338 endif () 01339 if (N GREATER 1) 01340 if (NOT SOURCES) 01341 list (REMOVE_AT ARGN_UNPARSED_ARGUMENTS 0) 01342 endif () 01343 message (FATAL_ERROR "Target ${TARGET_UID}: Too many or unrecognized arguments: ${ARGN_UNPARSED_ARGUMENTS}!\n" 01344 " Only one script can be built by each script target.") 01345 elseif (NOT SOURCES) 01346 set (SOURCES "${ARGN_UNPARSED_ARGUMENTS}") 01347 get_filename_component (SOURCES "${SOURCES}" ABSOLUTE) 01348 endif () 01349 if (NOT EXISTS "${SOURCES}" AND NOT SOURCES MATCHES "\\.in$" AND EXISTS "${SOURCES}.in") 01350 set (SOURCES "${SOURCES}.in") 01351 endif () 01352 if (NOT EXISTS "${SOURCES}") 01353 string (REGEX REPLACE "\\.in$" "" SOURCES "${SOURCES}") 01354 message (FATAL_ERROR "Target ${TARGET_UID}: Source file ${SOURCES}[.in] does not exist!") 01355 endif () 01356 # dump CMake variables for configuration of script 01357 set (BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET_UID}.dir") 01358 basis_dump_variables ("${BUILD_DIR}/cache.cmake") 01359 # auto-detect programming language (may be as well UNKNOWN) 01360 if (ARGN_LANGUAGE) 01361 string (TOUPPER "${ARGN_LANGUAGE}" ARGN_LANGUAGE) 01362 else () 01363 basis_get_source_language (ARGN_LANGUAGE ${SOURCES}) 01364 endif () 01365 # TEST flag 01366 basis_sanitize_for_regex (RE "${PROJECT_TESTING_DIR}") 01367 if (CMAKE_CURRENT_SOURCE_DIR MATCHES "^${RE}") 01368 set (TEST TRUE) 01369 else () 01370 set (TEST FALSE) 01371 endif () 01372 # default directory infix used below 01373 if (ARGN_MODULE) 01374 set (TYPE_INFIX "LIBRARY") 01375 elseif (ARGN_LIBEXEC) 01376 set (TYPE_INFIX "LIBEXEC") 01377 else () 01378 set (TYPE_INFIX "RUNTIME") 01379 endif () 01380 # output name 01381 string (REGEX REPLACE "\\.in$" "" SOURCE_NAME "${SOURCES}") 01382 if (NOT OUTPUT_NAME) 01383 get_filename_component (OUTPUT_NAME "${SOURCE_NAME}" NAME_WE) 01384 endif () 01385 if (ARGN_MODULE) 01386 get_filename_component (SUFFIX "${SOURCE_NAME}" EXT) 01387 else () 01388 if (WIN32) 01389 if (ARGN_LANGUAGE MATCHES "[JP]YTHON|PERL") 01390 set (SUFFIX ".cmd") 01391 else () 01392 get_filename_component (SUFFIX "${SOURCE_NAME}" EXT) 01393 endif () 01394 else () 01395 set (SUFFIX) 01396 endif () 01397 endif () 01398 # output directory 01399 if (TEST) 01400 set (OUTPUT_DIRECTORY "${TESTING_${TYPE_INFIX}_DIR}") 01401 else () 01402 set (OUTPUT_DIRECTORY "${BINARY_${TYPE_INFIX}_DIR}") 01403 endif () 01404 # installation component 01405 if (NOT ARGN_COMPONENT) 01406 if (ARGN_MODULE) 01407 set (ARGN_COMPONENT "${BASIS_LIBRARY_COMPONENT}") 01408 else () 01409 set (ARGN_COMPONENT "${BASIS_RUNTIME_COMPONENT}") 01410 endif () 01411 endif () 01412 if (NOT ARGN_COMPONENT) 01413 set (ARGN_COMPONENT "Unspecified") 01414 endif () 01415 # installation directory 01416 if (ARGN_DESTINATION) 01417 if (ARGN_DESTINATION MATCHES "^[nN][oO][nN][eE]$") 01418 set (ARGN_DESTINATION) 01419 elseif (IS_ABSOLUTE "${ARGN_DESTINATION}") 01420 file (RELATIVE_PATH ARGN_DESTINATION "${CMAKE_INSTALL_PREFIX}" "${ARGN_DESTINATION}") 01421 endif () 01422 elseif (TEST) 01423 set (ARGN_DESTINATION) # do not install 01424 else () 01425 set (ARGN_DESTINATION "${INSTALL_${TYPE_INFIX}_DIR}") 01426 endif () 01427 # script configuration ("compile definitions") 01428 if (EXISTS "${BINARY_CONFIG_DIR}/ScriptConfig.cmake") 01429 set (CONFIG_FILE "${BINARY_CONFIG_DIR}/ScriptConfig.cmake") 01430 else () 01431 set (CONFIG_FILE) 01432 endif () 01433 # auto-detect use of BASIS utilities 01434 set (LINK_DEPENDS) 01435 if (ARGN_LANGUAGE MATCHES "[JP]YTHON") 01436 set (UTILITIES_LANGUAGE "PYTHON") 01437 else () 01438 set (UTILITIES_LANGUAGE "${ARGN_LANGUAGE}") 01439 endif () 01440 if (ARGN_USE_BASIS_UTILITIES) 01441 if (NOT BASIS_UTILITIES_ENABLED MATCHES "${UTILITIES_LANGUAGE}") 01442 message (FATAL_ERROR "Target ${TARGET_UID} requires the BASIS utilities for ${UTILITIES_LANGUAGE}" 01443 " but BASIS was either build without the build of these utilities enabled" 01444 " or no utilities for this programming language are implemented. Remove the" 01445 " USE_BASIS_UTILITIES option if no BASIS utilities are used by the script" 01446 " ${SOURCES} or specify the correct programming language if it was not" 01447 " detected correctly.") 01448 endif () 01449 set (USES_BASIS_UTILITIES TRUE) 01450 elseif (NOT ARGN_NO_BASIS_UTILITIES AND NOT UTILITIES_LANGUAGE MATCHES "UNKNOWN") 01451 basis_utilities_check (USES_BASIS_UTILITIES ${SOURCES} ${UTILITIES_LANGUAGE}) 01452 else () 01453 set (USES_BASIS_UTILITIES FALSE) 01454 endif () 01455 if (USES_BASIS_UTILITIES) 01456 basis_set_project_property (PROPERTY PROJECT_USES_${UTILITIES_LANGUAGE}_UTILITIES TRUE) 01457 if (BASIS_DEBUG) 01458 message ("** Target ${TARGET_UID} uses the BASIS utilities for ${UTILITIES_LANGUAGE}.") 01459 endif () 01460 endif () 01461 # add custom target 01462 add_custom_target (${TARGET_UID} ALL SOURCES ${SOURCES}) 01463 _set_target_properties ( 01464 ${TARGET_UID} 01465 PROPERTIES 01466 LANGUAGE ${ARGN_LANGUAGE} 01467 BASIS_TYPE SCRIPT_${TYPE} 01468 BASIS_UTILITIES ${USES_BASIS_UTILITIES} 01469 SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 01470 BINARY_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 01471 OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY}" 01472 INSTALL_DIRECTORY "${ARGN_DESTINATION}" 01473 COMPONENT "${ARGN_COMPONENT}" 01474 OUTPUT_NAME "${OUTPUT_NAME}" 01475 PREFIX "" 01476 SUFFIX "${SUFFIX}" 01477 COMPILE_DEFINITIONS "" 01478 COMPILE_DEFINITIONS_FILE "${CONFIG_FILE}" 01479 LINK_DEPENDS "${LINK_DEPENDS}" 01480 EXPORT ${EXPORT} 01481 COMPILE ${BASIS_COMPILE_SCRIPTS} 01482 TEST ${TEST} 01483 LIBEXEC ${ARGN_LIBEXEC} 01484 ) 01485 # add target to list of targets 01486 basis_set_project_property (APPEND PROPERTY TARGETS "${TARGET_UID}") 01487 message (STATUS "Adding ${type} script ${TARGET_UID}... - done") 01488 endfunction () 01489 01490 # ============================================================================ 01491 # internal helpers 01492 # ============================================================================ 01493 01494 # ---------------------------------------------------------------------------- 01495 ## @brief Add executable target. 01496 # 01497 # This BASIS function overwrites CMake's 01498 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_executable"> 01499 # add_executable()</a> command in order to store information of imported targets 01500 # which is in particular used to generate the source code of the ExecutableTargetInfo 01501 # modules which are part of the BASIS utilities. 01502 # 01503 # @note Use basis_add_executable() instead where possible! 01504 # 01505 # @param [in] TARGET_UID Name of the target. 01506 # @param [in] ARGN Further arguments of CMake's add_executable(). 01507 # 01508 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_executable 01509 function (add_executable TARGET_UID) 01510 if (ARGC EQUAL 2 AND ARGV1 MATCHES "^IMPORTED$") 01511 _add_executable (${TARGET_UID} IMPORTED) 01512 basis_add_imported_target ("${TARGET_UID}" EXECUTABLE) 01513 else () 01514 _add_executable (${TARGET_UID} ${ARGN}) 01515 basis_set_project_property (APPEND PROPERTY TARGETS "${TARGET_UID}") 01516 endif () 01517 endfunction () 01518 01519 # ---------------------------------------------------------------------------- 01520 ## @brief Add library target. 01521 # 01522 # This BASIS function overwrites CMake's 01523 # <a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_library"> 01524 # add_library()</a> command in order to store information of imported targets. 01525 # 01526 # @note Use basis_add_library() instead where possible! 01527 # 01528 # @param [in] TARGET_UID Name of the target. 01529 # @param [in] ARGN Further arguments of CMake's add_library(). 01530 # 01531 # @sa http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:add_library 01532 function (add_library TARGET_UID) 01533 if (ARGC EQUAL 3 AND ARGV2 MATCHES "^IMPORTED$") 01534 _add_library (${TARGET_UID} "${ARGV1}" IMPORTED) 01535 basis_add_imported_target ("${TARGET_UID}" "${ARGV1}") 01536 else () 01537 _add_library (${TARGET_UID} ${ARGN}) 01538 basis_set_project_property (APPEND PROPERTY TARGETS "${TARGET_UID}") 01539 endif () 01540 endfunction () 01541 01542 # ---------------------------------------------------------------------------- 01543 ## @brief Add executable built from C++ source code. 01544 # 01545 # @note This function should not be used directly. Instead, it is called 01546 # by basis_add_executable() if the (detected) programming language 01547 # of the given source code files is @c CXX (i.e., C/C++). 01548 # 01549 # This function adds an executable target for the build of an executable from 01550 # C++ source code files. Refer to the documentation of basis_add_executable() 01551 # for a description of general options for adding an executable target. 01552 # 01553 # By default, the BASIS C++ utilities library is added as link dependency. 01554 # If none of the BASIS C++ utilities are used by this target, the option 01555 # NO_BASIS_UTILITIES can be given. To enable this option by default, set the 01556 # variable @c BASIS_UTILITIES to @c FALSE, best in the <tt>Settings.cmake</tt> 01557 # file located in the @c PROJECT_CONFIG_DIR (add such file if missing). 01558 # If the use of the BASIS C++ utilities is disabled by default, the 01559 # @c USE_BASIS_UTILITIES option can be used to enable them for this target 01560 # only. Note that the utilities library is a static library and thus the linker 01561 # would simply not include any of the BASIS utility functions in the final 01562 # binary file if not used. The only advantage of setting @c BASIS_UTILITIES to 01563 # @c FALSE or to always specify @c NO_BASIS_UTILITIES if no target uses the 01564 # utilities is that the BASIS utilities library will not be build in this case. 01565 # 01566 # @param [in] TARGET_NAME Name of build target. 01567 # @param [in] ARGN This argument list is parsed and the following 01568 # arguments are extracted, all other arguments are 01569 # considered to be source code files and simply passed 01570 # on to CMake's add_executable() command. 01571 # @par 01572 # <table border=0> 01573 # <tr> 01574 # @tp @b COMPONENT name @endtp 01575 # <td>Name of component as part of which this executable will be installed 01576 # if the specified @c DESTINATION is not "none". 01577 # (default: @c BASIS_RUNTIME_COMPONENT)</td> 01578 # </tr> 01579 # <tr> 01580 # @tp @b DESTINATION dir @endtp 01581 # <td>Installation directory relative to @c CMAKE_INSTALL_PREFIX. 01582 # If "none" (case-insensitive) is given as argument, no default 01583 # installation rules are added for this executable target. 01584 # (default: @c INSTALL_RUNTIME_DIR or @c INSTALL_LIBEXEC_DIR 01585 # if @p LIBEXEC is given)</td> 01586 # </tr> 01587 # <tr> 01588 # @tp @b LIBEXEC @endtp 01589 # <td>Specifies that the built executable is an auxiliary executable which 01590 # is only called by other executables. (default: @c FALSE)</td> 01591 # </tr> 01592 # <tr> 01593 # @tp @b [NO]EXPORT @endtp 01594 # <td>Whether to export this target. (default: @c TRUE)</td> 01595 # </tr> 01596 # <tr> 01597 # @tp @b NO_BASIS_UTILITIES @endtp 01598 # <td>Specify that the BASIS utilities are not used by this executable and hence 01599 # no link dependency on the BASIS utilities library shall be added. 01600 # (default: @c NOT @c BASIS_UTILITIES)</td> 01601 # </tr> 01602 # <tr> 01603 # @tp @b USE_BASIS_UTILITIES @endtp 01604 # <td>Specify that the BASIS utilities are used and required by this executable 01605 # and hence a link dependency on the BASIS utilities library has to be added. 01606 # (default: @c BASIS_UTILITIES)</td> 01607 # </tr> 01608 # </table> 01609 # 01610 # @returns Adds executable target using CMake's add_executable() command. 01611 # 01612 # @sa basis_add_executable() 01613 function (basis_add_executable_target TARGET_NAME) 01614 # check target name 01615 basis_check_target_name (${TARGET_NAME}) 01616 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 01617 message (STATUS "Adding executable ${TARGET_UID}...") 01618 # parse arguments 01619 CMAKE_PARSE_ARGUMENTS ( 01620 ARGN 01621 "USE_BASIS_UTILITIES;NO_BASIS_UTILITIES;EXPORT;NOEXPORT;LIBEXEC" 01622 "COMPONENT;DESTINATION" 01623 "" 01624 ${ARGN} 01625 ) 01626 set (SOURCES ${ARGN_UNPARSED_ARGUMENTS}) 01627 basis_set_flag (ARGN EXPORT ${BASIS_EXPORT}) 01628 if (ARGN_USE_BASIS_UTILITIES AND ARGN_NO_BASIS_UTILITIES) 01629 message (FATAL_ERROR "Target ${TARGET_UID}: Options USE_BASIS_UTILITIES and NO_BASIS_UTILITIES are mutually exclusive!") 01630 endif () 01631 if (ARGN_USE_BASIS_UTILITIES) 01632 set (USES_BASIS_UTILITIES TRUE) 01633 elseif (ARGN_NO_BASIS_UTILITIES) 01634 set (USES_BASIS_UTILITIES FALSE) 01635 else () 01636 set (USES_BASIS_UTILITIES ${BASIS_UTILITIES}) 01637 endif () 01638 # TEST flag 01639 basis_sanitize_for_regex (RE "${PROJECT_TESTING_DIR}") 01640 if (CMAKE_CURRENT_SOURCE_DIR MATCHES "^${RE}") 01641 set (TEST TRUE) 01642 else () 01643 set (TEST FALSE) 01644 endif () 01645 # installation component 01646 if (NOT ARGN_COMPONENT) 01647 set (ARGN_COMPONENT "${BASIS_RUNTIME_COMPONENT}") 01648 endif () 01649 if (NOT ARGN_COMPONENT) 01650 set (ARGN_COMPONENT "Unspecified") 01651 endif () 01652 # installation directory 01653 if (ARGN_DESTINATION) 01654 if (ARGN_DESTINATION MATCHES "^[nN][oO][nN][eE]$") 01655 set (ARGN_DESTINATION) 01656 elseif (IS_ABSOLUTE "${ARGN_DESTINATION}") 01657 file (RELATIVE_PATH ARGN_DESTINATION "${CMAKE_INSTALL_PREFIX}" "${ARGN_DESTINATION}") 01658 endif () 01659 elseif (ARGN_LIBEXEC) 01660 set (ARGN_DESTINATION "${INSTALL_LIBEXEC_DIR}") 01661 else () 01662 set (ARGN_DESTINATION "${INSTALL_RUNTIME_DIR}") 01663 endif () 01664 # configure (.in) source files 01665 basis_configure_sources (SOURCES ${SOURCES}) 01666 # add executable target 01667 add_executable (${TARGET_UID} ${SOURCES}) 01668 basis_make_target_uid (HEADERS_TARGET headers) 01669 if (TARGET "${HEADERS_TARGET}") 01670 add_dependencies (${TARGET_UID} ${HEADERS_TARGET}) 01671 endif () 01672 if (TARGET __${TARGET_UID}) # re-glob source files 01673 add_dependencies (_${TARGET_UID} __${TARGET_UID}) 01674 endif () 01675 _set_target_properties (${TARGET_UID} PROPERTIES BASIS_TYPE "EXECUTABLE" OUTPUT_NAME "${TARGET_NAME}") 01676 if (ARGN_LIBEXEC) 01677 _set_target_properties (${TARGET_UID} PROPERTIES LIBEXEC 1 COMPILE_DEFINITIONS LIBEXEC) 01678 else () 01679 _set_target_properties (${TARGET_UID} PROPERTIES LIBEXEC 0) 01680 endif () 01681 _set_target_properties (${TARGET_UID} PROPERTIES TEST ${TEST}) 01682 # output directory 01683 if (TEST) 01684 if (ARGN_LIBEXEC) 01685 _set_target_properties (${TARGET_UID} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_LIBEXEC_DIR}") 01686 else () 01687 _set_target_properties (${TARGET_UID} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_RUNTIME_DIR}") 01688 endif () 01689 elseif (ARGN_LIBEXEC) 01690 _set_target_properties (${TARGET_UID} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${BINARY_LIBEXEC_DIR}") 01691 else () 01692 _set_target_properties (${TARGET_UID} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${BINARY_RUNTIME_DIR}") 01693 endif () 01694 # installation directory 01695 _set_target_properties (${TARGET_UID} PROPERTIES RUNTIME_INSTALL_DIRECTORY "${ARGN_DESTINATION}") 01696 # link to BASIS utilities 01697 if (USES_BASIS_UTILITIES) 01698 if (NOT TARGET ${BASIS_CXX_UTILITIES_LIBRARY}) 01699 message (FATAL_ERROR "Target ${TARGET_UID} seems to make use of the BASIS C++" 01700 " utilities but BASIS was built without C++ utilities enabled." 01701 " Either specify the option NO_BASIS_UTILITIES, set the global" 01702 " variable BASIS_UTILITIES to FALSE" 01703 " (in ${PROJECT_CONFIG_DIR}/Settings.cmake) or" 01704 " rebuild BASIS with C++ utilities enabled.") 01705 endif () 01706 # add project-specific library target if not present yet 01707 basis_add_utilities_library (BASIS_UTILITIES_TARGET) 01708 # non-project specific utilities build as part of BASIS 01709 basis_target_link_libraries (${TARGET_UID} ${BASIS_CXX_UTILITIES_LIBRARY}) 01710 # project-specific utilities build as part of this project 01711 basis_target_link_libraries (${TARGET_UID} ${BASIS_UTILITIES_TARGET}) 01712 endif () 01713 _set_target_properties (${TARGET_UID} PROPERTIES BASIS_UTILITIES ${USES_BASIS_UTILITIES}) 01714 # export 01715 set (EXPORT_OPT) 01716 if (EXPORT) 01717 if (TEST) 01718 basis_set_project_property (APPEND PROPERTY TEST_EXPORT_TARGETS "${TARGET_UID}") 01719 else () 01720 basis_set_project_property (APPEND PROPERTY EXPORT_TARGETS "${TARGET_UID}") 01721 if (ARGN_DESTINATION) 01722 basis_set_project_property (APPEND PROPERTY INSTALL_EXPORT_TARGETS "${TARGET_UID}") 01723 endif () 01724 set (EXPORT_OPT "EXPORT" "${PROJECT_NAME}") # for install() below 01725 endif () 01726 endif () 01727 # installation 01728 if (ARGN_DESTINATION) 01729 if (TEST) 01730 # TODO install (selected?) tests 01731 else () 01732 install ( 01733 TARGETS ${TARGET_UID} ${EXPORT_OPT} 01734 DESTINATION "${ARGN_DESTINATION}" 01735 COMPONENT "${ARGN_COMPONENT}" 01736 ) 01737 endif () 01738 endif () 01739 # done 01740 message (STATUS "Adding executable ${TARGET_UID}... - done") 01741 endfunction () 01742 01743 # ---------------------------------------------------------------------------- 01744 ## @brief Add library built from C++ source code. 01745 # 01746 # @note This function should not be used directly. Instead, it is called 01747 # by basis_add_library() if the (detected) programming language 01748 # of the given source code files is @c CXX (i.e., C/C++) and the 01749 # option @c MEX is not given. 01750 # 01751 # This function adds a library target which builds a library from C++ source 01752 # code files. Refer to the documentation of basis_add_library() for a 01753 # description of the general options for adding a library target. 01754 # 01755 # By default, the BASIS C++ utilities library is added as link dependency. 01756 # If none of the BASIS C++ utilities are used by this target, the option 01757 # NO_BASIS_UTILITIES can be given. To enable this option by default, set the 01758 # variable @c BASIS_UTILITIES to @c FALSE, best in the <tt>Settings.cmake</tt> 01759 # file located in the @c PROJECT_CONFIG_DIR (add such file if missing). 01760 # If the use of the BASIS C++ utilities is disabled by default, the 01761 # @c USE_BASIS_UTILITIES option can be used to enable them for this target 01762 # only. Note that the utilities library is a static library and thus the linker 01763 # would simply not include any of the BASIS utility functions in the final 01764 # binary file if not used. The only advantage of setting @c BASIS_UTILITIES to 01765 # @c FALSE or to always specify @c NO_BASIS_UTILITIES if no target uses the 01766 # utilities is that the BASIS utilities library will not be build in this case. 01767 # 01768 # @param [in] TARGET_NAME Name of build target. 01769 # @param [in] ARGN This argument list is parsed and the following 01770 # arguments are extracted. All other arguments are 01771 # considered to be source code files and simply 01772 # passed on to CMake's add_library() command. 01773 # @par 01774 # <table border=0> 01775 # <tr> 01776 # @tp <b>STATIC</b>|<b>SHARED</b>|<b>MODULE</b> @endtp 01777 # <td>Type of the library. (default: @c SHARED if @c BUILD_SHARED_LIBS 01778 # evaluates to true or @c STATIC otherwise)</td> 01779 # </tr> 01780 # <tr> 01781 # @tp @b COMPONENT name @endtp 01782 # <td>Name of component as part of which this library will be installed 01783 # if either the @c RUNTIME_INSTALL_DIRECTORY or 01784 # @c LIBRARY_INSTALL_DIRECTORY property is not "none". Used only if 01785 # either @p RUNTIME_COMPONENT or @p LIBRARY_COMPONENT not specified. 01786 # (default: see @p RUNTIME_COMPONENT and @p LIBRARY_COMPONENT)</td> 01787 # </tr> 01788 # <tr> 01789 # @tp @b DESTINATION dir @endtp 01790 # <td>Installation directory for runtime and library component relative 01791 # to @c CMAKE_INSTALL_PREFIX. Used only if either @p RUNTIME_DESTINATION 01792 # or @p LIBRARY_DESTINATION not specified. If "none" (case-insensitive) 01793 # is given as argument, no default installation rules are added. 01794 # (default: see @p RUNTIME_DESTINATION and @p LIBRARY_DESTINATION)</td> 01795 # </tr> 01796 # <tr> 01797 # @tp @b LIBRARY_COMPONENT name @endtp 01798 # <td>Name of component as part of which import/static library will be intalled 01799 # if @c LIBRARY_INSTALL_DIRECTORY property is not "none". 01800 # (default: @c COMPONENT if specified or @c BASIS_LIBRARY_COMPONENT otherwise)</td> 01801 # </tr> 01802 # <tr> 01803 # @tp @b LIBRARY_DESTINATION dir @endtp 01804 # <td>Installation directory of the library component relative to 01805 # @c CMAKE_INSTALL_PREFIX. If "none" (case-insensitive) is given as argument, 01806 # no installation rule for the library component is added. 01807 # (default: @c INSTALL_ARCHIVE_DIR)</td> 01808 # </tr> 01809 # <tr> 01810 # @tp @b RUNTIME_COMPONENT name @endtp 01811 # <td>Name of component as part of which runtime library will be installed 01812 # if @c RUNTIME_INSTALL_DIRECTORY property is not "none". 01813 # (default: @c COMPONENT if specified or @c BASIS_RUNTIME_COMPONENT otherwise)</td> 01814 # </tr> 01815 # <tr> 01816 # @tp @b RUNTIME_DESTINATION dir @endtp 01817 # <td>Installation directory of the runtime component relative to 01818 # @c CMAKE_INSTALL_PREFIX. If "none" (case-insensitive) is given as argument, 01819 # no installation rule for the runtime library is added. 01820 # (default: @c INSTALL_LIBRARY_DIR on Unix or @c INSTALL_RUNTIME_DIR Windows)</td> 01821 # </tr> 01822 # <tr> 01823 # @tp @b [NO]EXPORT @endtp 01824 # <td>Whether to export this target. (default: @c TRUE)</td> 01825 # </tr> 01826 # <tr> 01827 # @tp @b NO_BASIS_UTILITIES @endtp 01828 # <td>Specify that the BASIS utilities are not used by this executable and hence 01829 # no link dependency on the BASIS utilities library shall be added. 01830 # (default: @c NOT BASIS_UTILITIES)</td> 01831 # </tr> 01832 # <tr> 01833 # @tp @b USE_BASIS_UTILITIES @endtp 01834 # <td>Specify that the BASIS utilities are used and required by this executable 01835 # and hence a link dependency on the BASIS utilities library shall be added. 01836 # (default: @c BASIS_UTILITIES)</td> 01837 # </tr> 01838 # </table> 01839 # 01840 # @returns Adds library target using CMake's add_library() command. 01841 # 01842 # @sa basis_add_library() 01843 function (basis_add_library_target TARGET_NAME) 01844 # On UNIX-based systems setting the VERSION property only creates 01845 # annoying files with the version string as suffix. 01846 # Moreover, MEX-files may NEVER have a suffix after the MEX extension! 01847 # Otherwise, the MATLAB Compiler when using the symbolic link 01848 # without this suffix will create code that fails on runtime 01849 # with an .auth file missing error. 01850 # 01851 # Thus, do NOT set VERSION and SOVERSION properties on library targets! 01852 01853 # check target name 01854 basis_check_target_name (${TARGET_NAME}) 01855 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 01856 # parse arguments 01857 CMAKE_PARSE_ARGUMENTS ( 01858 ARGN 01859 "STATIC;SHARED;MODULE;USE_BASIS_UTILITIES;NO_BASIS_UTILITIES;EXPORT;NOEXPORT" 01860 "COMPONENT;RUNTIME_COMPONENT;LIBRARY_COMPONENT;DESTINATION;RUNTIME_DESTINATION;LIBRARY_DESTINATION" 01861 "" 01862 ${ARGN} 01863 ) 01864 set (SOURCES ${ARGN_UNPARSED_ARGUMENTS}) 01865 basis_set_flag (ARGN EXPORT ${BASIS_EXPORT}) 01866 if (ARGN_USE_BASIS_UTILITIES AND ARGN_NO_BASIS_UTILITIES) 01867 message (FATAL_ERROR "Target ${TARGET_UID}: Options USE_BASIS_UTILITIES and NO_BASIS_UTILITIES are mutually exclusive!") 01868 endif () 01869 if (ARGN_USE_BASIS_UTILITIES) 01870 set (USES_BASIS_UTILITIES TRUE) 01871 elseif (ARGN_NO_BASIS_UTILITIES) 01872 set (USES_BASIS_UTILITIES FALSE) 01873 else () 01874 set (USES_BASIS_UTILITIES ${BASIS_UTILITIES}) 01875 endif () 01876 # TEST flag 01877 basis_sanitize_for_regex (RE "${PROJECT_TESTING_DIR}") 01878 if (CMAKE_CURRENT_SOURCE_DIR MATCHES "^${RE}") 01879 set (TEST TRUE) 01880 else () 01881 set (TEST FALSE) 01882 endif () 01883 # library type 01884 if (NOT ARGN_SHARED AND NOT ARGN_STATIC AND NOT ARGN_MODULE) 01885 if (BUILD_SHARED_LIBS) 01886 set (ARGN_SHARED TRUE) 01887 else () 01888 set (ARGN_STATIC TRUE) 01889 endif () 01890 endif () 01891 set (TYPE) 01892 if (ARGN_STATIC) 01893 if (TYPE) 01894 message (FATAL_ERROR "More than one library type specified for target ${TARGET_UID}!") 01895 endif () 01896 set (TYPE "STATIC") 01897 endif () 01898 if (ARGN_SHARED) 01899 if (TYPE) 01900 message (FATAL_ERROR "More than one library type specified for target ${TARGET_UID}!") 01901 endif () 01902 set (TYPE "SHARED") 01903 endif () 01904 if (ARGN_MODULE) 01905 if (TYPE) 01906 message (FATAL_ERROR "More than one library type specified for target ${TARGET_UID}!") 01907 endif () 01908 set (TYPE "MODULE") 01909 endif () 01910 string (TOLOWER "${TYPE}" type) 01911 # status message 01912 message (STATUS "Adding ${type} library ${TARGET_UID}...") 01913 # installation component 01914 if (ARGN_COMPONENT) 01915 if (NOT ARGN_RUNTIME_COMPONENT) 01916 set (ARGN_RUNTIME_COMPONENT "${ARGN_COMPONENT}") 01917 endif () 01918 if (NOT ARGN_LIBRARY_COMPONENT) 01919 set (ARGN_LIBRARY_COMPONENT "${ARGN_COMPONENT}") 01920 endif () 01921 endif () 01922 if (NOT ARGN_RUNTIME_COMPONENT) 01923 set (ARGN_RUNTIME_COMPONENT "${BASIS_RUNTIME_COMPONENT}") 01924 endif () 01925 if (NOT ARGN_RUNTIME_COMPONENT) 01926 set (ARGN_RUNTIME_COMPONENT "Unspecified") 01927 endif () 01928 if (NOT ARGN_LIBRARY_COMPONENT) 01929 set (ARGN_LIBRARY_COMPONENT "${BASIS_LIBRARY_COMPONENT}") 01930 endif () 01931 if (NOT ARGN_LIBRARY_COMPONENT) 01932 set (ARGN_LIBRARY_COMPONENT "Unspecified") 01933 endif () 01934 # installation directories 01935 if (ARGN_DESTINATION) 01936 if (NOT ARGN_STATIC AND NOT ARGN_RUNTIME_DESTINATION) 01937 set (ARGN_RUNTIME_DESTINATION "${ARGN_DESTINATION}") 01938 endif () 01939 if (NOT ARGN_LIBRARY_DESTINATION) 01940 set (ARGN_LIBRARY_DESTINATION "${ARGN_DESTINATION}") 01941 endif () 01942 endif () 01943 if (NOT ARGN_RUNTIME_DESTINATION) 01944 set (ARGN_RUNTIME_DESTINATION "${INSTALL_RUNTIME_DIR}") 01945 endif () 01946 if (NOT ARGN_LIBRARY_DESTINATION) 01947 set (ARGN_LIBRARY_DESTINATION "${INSTALL_LIBRARY_DIR}") 01948 endif () 01949 if (ARGN_STATIC OR ARGN_RUNTIME_DESTINATION MATCHES "^[nN][oO][nN][eE]$") 01950 set (ARGN_RUNTIME_DESTINATION) 01951 endif () 01952 if (ARGN_LIBRARY_DESTINATION MATCHES "^[nN][oO][nN][eE]$") 01953 set (ARGN_LIBRARY_DESTINATION) 01954 endif () 01955 # configure (.in) source files 01956 basis_configure_sources (SOURCES ${SOURCES}) 01957 # add library target 01958 add_library (${TARGET_UID} ${TYPE} ${SOURCES}) 01959 basis_make_target_uid (HEADERS_TARGET headers) 01960 if (TARGET ${HEADERS_TARGET}) 01961 add_dependencies (${TARGET_UID} ${HEADERS_TARGET}) 01962 endif () 01963 if (TARGET __${TARGET_UID}) # re-glob source files 01964 add_dependencies (_${TARGET_UID} __${TARGET_UID}) 01965 endif () 01966 _set_target_properties (${TARGET_UID} PROPERTIES BASIS_TYPE "${TYPE}_LIBRARY" OUTPUT_NAME "${TARGET_NAME}") 01967 # output directory 01968 if (TEST) 01969 _set_target_properties ( 01970 ${TARGET_UID} 01971 PROPERTIES 01972 RUNTIME_OUTPUT_DIRECTORY "${TESTING_RUNTIME_DIR}" 01973 LIBRARY_OUTPUT_DIRECTORY "${TESTING_LIBRARY_DIR}" 01974 ARCHIVE_OUTPUT_DIRECTORY "${TESTING_ARCHIVE_DIR}" 01975 ) 01976 else () 01977 _set_target_properties ( 01978 ${TARGET_UID} 01979 PROPERTIES 01980 RUNTIME_OUTPUT_DIRECTORY "${BINARY_RUNTIME_DIR}" 01981 LIBRARY_OUTPUT_DIRECTORY "${BINARY_LIBRARY_DIR}" 01982 ARCHIVE_OUTPUT_DIRECTORY "${BINARY_ARCHIVE_DIR}" 01983 ) 01984 endif () 01985 # installation directory 01986 # these properties are used by basis_get_target_location() in particular 01987 _set_target_properties ( 01988 ${TARGET_UID} 01989 PROPERTIES 01990 RUNTIME_INSTALL_DIRECTORY "${ARGN_RUNTIME_DESTINATION}" 01991 LIBRARY_INSTALL_DIRECTORY "${ARGN_LIBRARY_DESTINATION}" 01992 ARCHIVE_INSTALL_DIRECTORY "${ARGN_LIBRARY_DESTINATION}" 01993 ) 01994 # link to BASIS utilities 01995 if (USES_BASIS_UTILITIES) 01996 if (NOT TARGET ${BASIS_CXX_UTILITIES_LIBRARY}) 01997 message (FATAL_ERROR "Target ${TARGET_UID} makes use of the BASIS C++ utilities" 01998 " but BASIS was build without C++ utilities enabled." 01999 " Either specify the option NO_BASIS_UTILITIES, set the global" 02000 " variable BASIS_UTILITIES to FALSE" 02001 " (in ${PROJECT_CONFIG_DIR}/Settings.cmake) or" 02002 " rebuild BASIS with C++ utilities enabled.") 02003 endif () 02004 # add project-specific library target if not present yet 02005 basis_add_utilities_library (BASIS_UTILITIES_TARGET) 02006 # non-project specific utilities build as part of BASIS 02007 basis_target_link_libraries (${TARGET_UID} ${BASIS_CXX_UTILITIES_LIBRARY}) 02008 # project-specific utilities build as part of this project 02009 basis_target_link_libraries (${TARGET_UID} ${BASIS_UTILITIES_TARGET}) 02010 endif () 02011 _set_target_properties (${TARGET_UID} PROPERTIES BASIS_UTILITIES ${USES_BASIS_UTILITIES}) 02012 # installation 02013 if (TEST) 02014 # TODO At the moment, no tests are installed. Once there is a way to 02015 # install selected tests, the shared libraries they depend on 02016 # need to be installed as well. 02017 if (EXPORT) 02018 basis_set_project_property (APPEND PROPERTY TEST_EXPORT_TARGETS "${TARGET_UID}") 02019 endif () 02020 else () 02021 if (EXPORT) 02022 set (EXPORT_OPT "EXPORT" "${PROJECT_NAME}") 02023 basis_set_project_property (APPEND PROPERTY EXPORT_TARGETS "${TARGET_UID}") 02024 if (ARGN_RUNTIME_DESTINATION OR ARGN_LIBRARY_DESTINATION) 02025 basis_set_project_property (APPEND PROPERTY INSTALL_EXPORT_TARGETS "${TARGET_UID}") 02026 endif () 02027 else () 02028 set (EXPORT_OPT) 02029 endif () 02030 if (ARGN_RUNTIME_DESTINATION) 02031 install ( 02032 TARGETS ${TARGET_UID} ${EXPORT_OPT} 02033 RUNTIME 02034 DESTINATION "${ARGN_RUNTIME_DESTINATION}" 02035 COMPONENT "${ARGN_RUNTIME_COMPONENT}" 02036 ) 02037 endif () 02038 if (ARGN_LIBRARY_DESTINATION) 02039 install ( 02040 TARGETS ${TARGET_UID} ${EXPORT_OPT} 02041 LIBRARY 02042 DESTINATION "${ARGN_LIBRARY_DESTINATION}" 02043 COMPONENT "${ARGN_LIBRARY_COMPONENT}" 02044 ARCHIVE 02045 DESTINATION "${ARGN_LIBRARY_DESTINATION}" 02046 COMPONENT "${ARGN_LIBRARY_COMPONENT}" 02047 ) 02048 endif () 02049 endif () 02050 # done 02051 message (STATUS "Adding ${type} library ${TARGET_UID}... - done") 02052 endfunction () 02053 02054 # ---------------------------------------------------------------------------- 02055 ## @brief Add script library target. 02056 # 02057 # @note This function should not be used directly. Instead, it is called 02058 # by basis_add_library() if the (detected) programming language 02059 # of the given source code files is neither @c CXX (i.e., C/C++) nor 02060 # @c MATLAB. 02061 # 02062 # This function adds a build target for libraries which are a collection of 02063 # one or more modules written in a scripting language. The relative paths 02064 # of the modules relative to the library's @p SOURCE_DIRECTORY property are 02065 # preserved. This is important for the most widely used scripting languages 02066 # such as Python, Perl, or MATLAB, where the file path relative to the 02067 # package root directory defines the package namespace. 02068 # 02069 # A custom CMake build target with the following properties is added by this 02070 # function to the build system. These properties are used by 02071 # basis_build_script_library() to generate a build script written in CMake 02072 # code which is executed by a custom CMake command. Before the invokation of 02073 # basis_build_script_library(), the target properties can be modified using 02074 # basis_set_target_properties(). 02075 # 02076 # @note Custom BASIS build targets are finalized by BASIS at the end of 02077 # basis_project_impl(), i.e., the end of the root CMake configuration file 02078 # of the (sub-)project. 02079 # 02080 # @par Properties on script library targets 02081 # <table border=0> 02082 # <tr> 02083 # @tp @b BASIS_TYPE @endtp 02084 # <td>Read-only property with value "SCRIPT_LIBRARY" for script library targets.</td> 02085 # </tr> 02086 # <tr> 02087 # @tp @b BASIS_UTILITIES @endtp 02088 # <td>Whether the BASIS utilities are used by any module of this library. 02089 # For the supported scripting languages for which BASIS utilities are 02090 # implemented, BASIS will in most cases automatically detect whether 02091 # these utilities are used by a module or not. Otherwise, set this 02092 # property manually or use either the @p USE_BASIS_UTILITIES or the 02093 # @p NO_BASIS_UTILITIES option when adding the library target. 02094 # (default: auto-detected or @c UNKNOWN)</td> 02095 # </tr> 02096 # <tr> 02097 # @tp @b BINARY_DIRECTORY @endtp 02098 # <td>Build tree directory of this target. (default: @c CMAKE_CURRENT_BINARY_DIR)</td> 02099 # </tr> 02100 # <tr> 02101 # @tp @b COMPILE @endtp 02102 # <td>Whether to compile the library, respectively, it's modules if the 02103 # programming language allows such pre-compilation as in case of Python, 02104 # for example. If @c TRUE, only the compiled files are installed. 02105 # (default: @c BASIS_COMPILE_SCRIPTS)</td> 02106 # </tr> 02107 # <tr> 02108 # @tp @b COMPILE_DEFINITIONS @endtp 02109 # <td>CMake code which is evaluated after the inclusion of the default script 02110 # configuration files. This code can be used to set the replacement text of the 02111 # CMake variables ("@VAR@" patterns) used in the source files. 02112 # See <a href="http://www.rad.upenn.edu/sbia/software/basis/standard/scripttargets.html#script-configuration"> 02113 # Build System Standard</a> for details. (default: "")</td> 02114 # </tr> 02115 # <tr> 02116 # @tp @b COMPILE_DEFINITIONS_FILE @endtp 02117 # <td>CMake script file with compile definitions, also referred to as script 02118 # configuration file. The named files are included after the default BASIS 02119 # script configuration and before the @c COMPILE_DEFINITIONS code is being 02120 # evaluated. (default: @c BINARY_CONFIG_DIR/ScriptConfig.cmake)</td> 02121 # </tr> 02122 # <tr> 02123 # @tp @b EXPORT @endtp 02124 # <td>Whether to export this build target in which case an import library 02125 # target is added to the custom exports file with the path to the 02126 # built/installed modules set as @c IMPORT_LOCATION. (default: @c TRUE)</td> 02127 # </tr> 02128 # <tr> 02129 # @tp @b LANGUAGE @endtp 02130 # <td>Read-only property of programming language of modules in uppercase letters. 02131 # (default: see @p LANGUAGE argument)</td> 02132 # </tr> 02133 # <tr> 02134 # @tp @b LIBRARY_COMPONENT @endtp 02135 # <td>Name of component as part of which this library is installed if 02136 # @c LIBRARY_INSTALL_DIRECTORY is not set to "none". 02137 # (default: see @p COMPONENT argument)</td> 02138 # </tr> 02139 # <tr> 02140 # @tp @b LIBRARY_INSTALL_DIRECTORY @endtp 02141 # <td>Installation directory of library configured for use in installation tree 02142 # relative to @c CMAKE_INSTALL_PREFIX. Set to "none" (case-insensitive) to skip the 02143 # addition of an installation rule. 02144 # (default: <tt>INSTALL_<LANGUAGE>_LIBRARY_DIR</tt> if defined or 02145 # @c INSTALL_LIBRARY_DIR otherwise)</td> 02146 # </tr> 02147 # <tr> 02148 # @tp @b LIBRARY_OUTPUT_DIRECTORY @endtp 02149 # <td>Output directory of library configured for use within the build tree. 02150 # (default: <tt>BINARY_<LANGUAGE>_LIBRARY_DIR</tt> if defined or 02151 # @c BINARY_LIBRARY_DIR otherwise)</td> 02152 # </tr> 02153 # <tr> 02154 # @tp @b LINK_DEPENDS @endtp 02155 # <td>Paths or target names of script modules and libraries used by this script. 02156 # For each listed build target, a dependency is added between this 02157 # library target and the named build targets. Use basis_target_link_libraries() 02158 # to add additional link dependencies. Further note that if this library is 02159 # a link dependency of an executable script added by basis_add_executable() 02160 # (i.e., basis_add_script() actually), the link dependencies of this library 02161 # are inherited by the executable script. 02162 # (default: BASIS utilities module if used or empty list otherwise)</td> 02163 # </tr> 02164 # <tr> 02165 # @tp @b PREFIX @endtp 02166 # <td>Common module prefix. The given directory path is appended to both 02167 # @c LIBRAR_OUTPUT_DIRECTORY and @c LIBRARY_INSTALL_DIRECTORY and can, 02168 # for example, be used to install modules of a Python package as part of 02169 # another Python package, where @c LIBRARY_OUTPUT_DIRECTORY or 02170 # @c LIBRARY_INSTALL_DIRECTORY, respectively, is the directory of the 02171 # main package which is added to the @c PYTHONPATH. Possibly missing 02172 # __init__.py files in case of Python are generated by the _initpy target 02173 # which is automatically added by BASIS in that case and further added to 02174 # the dependencies of this library target. 02175 # (default: @c PROJECT_NAMESPACE_PYTHON if @c LANGUAGE is @c PYTHON with 02176 # periods (.) replaced by slashes (/), @c PROJECT_NAMESPACE_PERL if 02177 # @c LANGUAGE is @c PERL with <tt>::</tt> replaced by slashes (/), 02178 # and "" otherwise)</td> 02179 # </tr> 02180 # <tr> 02181 # @tp @b SOURCE_DIRECTORY @endtp 02182 # <td>Source directory of this target. This directory is in particular 02183 # used to convert the paths of the given source files to relative paths. 02184 # The built modules within the build and installation tree will have the 02185 # same relative path (relative to the @c LIBRARY_OUTPUT_DIRECTORY or 02186 # @c LIBRARY_INSTALL_DIRECTORY, respectively). 02187 # (default: @c CMAKE_CURRENT_SOURCE_DIR)</td> 02188 # </tr> 02189 # <tr> 02190 # @tp @b SOURCES @endtp 02191 # <td>Read-only property which lists the source files of this library. 02192 # Note that the first element in this list actually names a directory 02193 # in the build, the one where the build script for this target is located 02194 # instead of a source file and thus should be ignored.</td> 02195 # </tr> 02196 # </table> 02197 # 02198 # @attention Properties documented as read-only must not be modified. 02199 # 02200 # @param [in] TARGET_NAME Name of build target. 02201 # @param [in] ARGN The remaining arguments are parsed and the following 02202 # arguments extracted. All unparsed arguments are treated 02203 # as the module files of the script library. 02204 # @par 02205 # <table border=0> 02206 # <tr> 02207 # @tp @b COMPONENT name @endtp 02208 # <td>Name of installation component as part of which this library is being 02209 # installed if the @c LIBRARY_INSTALL_DIRECTORY property is not "none". 02210 # (default: @c BASIS_LIBRARY_COMPONENT)</td> 02211 # </tr> 02212 # <tr> 02213 # @tp @b DESTINATION dir @endtp 02214 # <td>Installation directory for library relative to @c CMAKE_INSTALL_PREFIX. 02215 # If an absolute path is given as argument, it is made relative to the 02216 # configured installation prefix. (default: @c INSTALL_LIBRARY_DIR)</td> 02217 # </tr> 02218 # <tr> 02219 # @tp @b LANGUAGE lang @endtp 02220 # <td>Programming language in which modules are written (case-insensitive). 02221 # If not specified, the programming language is derived from the file name 02222 # extensions of the source files and the shebang directive on the first line 02223 # of each module if any. If the programming language could not be detected 02224 # automatically, the @c LANGUAGE property is set to @c UNKNOWN. Note that 02225 # for script library targets, the library may still be built correctly 02226 # even if the scripting language was not recognized. The automatic detection 02227 # whether the BASIS utilities are used and required will fail, however. 02228 # In this case, specify the programming language using this option. 02229 # (default: auto-detected or @c UNKNOWN)</td> 02230 # </tr> 02231 # <tr> 02232 # @tp @b [NO]EXPORT @endtp 02233 # <td>Whether to export this target. (default: @c TRUE)</td> 02234 # </tr> 02235 # <tr> 02236 # @tp @b NO_BASIS_UTILITIES @endtp 02237 # <td>Specify that the BASIS utilities are not used by this library. If the 02238 # programming language of the modules is known and BASIS utilities are 02239 # available for this language, BASIS will in most cases automatically 02240 # detect whether these utilities are used by any module of this library. 02241 # Use this option to skip this check in the case that no module makes 02242 # use of the BASIS utilities.</td> 02243 # </tr> 02244 # <tr> 02245 # @tp @b USE_BASIS_UTILITIES @endtp 02246 # <td>Specify that the BASIS utilities are used and thus required by this library. 02247 # If the programming language of the modules is known and BASIS utilities are 02248 # available for this language, BASIS will in most cases automatically 02249 # detect whether these utilities are used by any module of this library. 02250 # Use this option to skip this check when it is already known that no module 02251 # makes use of the BASIS utilities. Note that an error is raised if this option 02252 # is given, but no BASIS utilities are available for the programming language 02253 # of this script or if the programming language is unknown, respectively, not 02254 # detected correctly. In this case, consider the use of the @p LANGUAGE argument.</td> 02255 # </tr> 02256 # </table> 02257 # 02258 # @returns Adds a custom CMake target with the documented properties. The actual custom 02259 # command to build the library is added by basis_build_script_library(). 02260 # 02261 # @sa basis_add_library() 02262 function (basis_add_script_library TARGET_NAME) 02263 # check target name 02264 basis_check_target_name ("${TARGET_NAME}") 02265 basis_make_target_uid (TARGET_UID "${TARGET_NAME}") 02266 message (STATUS "Adding script library ${TARGET_UID}...") 02267 # dump CMake variables for configuration of script 02268 set (BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${TARGET_UID}.dir") 02269 basis_dump_variables ("${BUILD_DIR}/cache.cmake") 02270 # parse arguments 02271 CMAKE_PARSE_ARGUMENTS ( 02272 ARGN 02273 "NO_BASIS_UTILITIES;USE_BASIS_UTILITIES;EXPORT;NOEXPORT" 02274 "COMPONENT;DESTINATION;LANGUAGE" 02275 "" 02276 ${ARGN} 02277 ) 02278 basis_set_flag (ARGN EXPORT ${BASIS_EXPORT}) 02279 set (SOURCES "${ARGN_UNPARSED_ARGUMENTS}") 02280 # TEST flag 02281 basis_sanitize_for_regex (RE "${PROJECT_TESTING_DIR}") 02282 if (CMAKE_CURRENT_SOURCE_DIR MATCHES "^${RE}") 02283 set (TEST TRUE) 02284 else () 02285 set (TEST FALSE) 02286 endif () 02287 # check source files 02288 set (_SOURCES) 02289 foreach (S IN LISTS SOURCES) 02290 get_filename_component (S "${S}" ABSOLUTE) 02291 if (NOT EXISTS "${S}" AND NOT S MATCHES "\\.in$" AND EXISTS "${S}.in" AND NOT IS_DIRECTORY "${S}.in") 02292 set (S "${S}.in") 02293 elseif (IS_DIRECTORY "${S}") 02294 message (FATAL_ERROR "Target ${TARGET_UID}: Directory ${S} given where file name expected!") 02295 endif () 02296 if (NOT EXISTS "${S}") 02297 string (REGEX REPLACE "\\.in$" "" S "${S}") 02298 message (FATAL_ERROR "Target ${TARGET_UID}: Source file ${S}[.in] does not exist!") 02299 endif () 02300 list (APPEND _SOURCES "${S}") 02301 endforeach () 02302 if (NOT _SOURCES) 02303 message (FATAL_ERROR "Target ${TARGET_UID}: No source files specified!") 02304 endif () 02305 set (SOURCES "${_SOURCES}") 02306 unset (_SOURCES) 02307 # auto-detect programming language (may be as well UNKNOWN) 02308 string (TOUPPER "${ARGN_LANGUAGE}" ARGN_LANGUAGE) 02309 if (NOT ARGN_LANGUAGE) 02310 basis_get_source_language (ARGN_LANGUAGE ${SOURCES}) 02311 if (ARGN_LANGUAGE MATCHES "AMBIGUOUS|UNKNOWN") 02312 message (FATAL_ERROR "Target ${TARGET_UID}: Failed to determine programming" 02313 " language of modules! Make sure that all modules are" 02314 " written in the same language and that the used programming" 02315 " language is supported by BASIS, i.e., either Python (Jython)," 02316 " Perl, Bash, or MATLAB. Otherwise, try to specify the language" 02317 " explicitly using the LANGUAGE option.") 02318 endif () 02319 endif () 02320 # output directory 02321 if (TEST) 02322 if (DEFINED TESTING_${ARGN_LANGUAGE}_LIBRARY_DIR) 02323 set (OUTPUT_DIRECTORY "${TESTING_${ARGN_LANGUAGE}_LIBRARY_DIR}") 02324 else () 02325 set (OUTPUT_DIRECTORY "${TESTING_LIBRARY_DIR}") 02326 endif () 02327 else () 02328 if (DEFINED BINARY_${ARGN_LANGUAGE}_LIBRARY_DIR) 02329 set (OUTPUT_DIRECTORY "${BINARY_${ARGN_LANGUAGE}_LIBRARY_DIR}") 02330 else () 02331 set (OUTPUT_DIRECTORY "${BINARY_LIBRARY_DIR}") 02332 endif () 02333 endif () 02334 # installation component 02335 if (NOT ARGN_COMPONENT) 02336 set (ARGN_COMPONENT "${BASIS_LIBRARY_COMPONENT}") 02337 endif () 02338 if (NOT ARGN_COMPONENT) 02339 set (ARGN_COMPONENT "Unspecified") 02340 endif () 02341 # installation directory 02342 if (TEST) 02343 if (ARGN_DESTINATION) 02344 message (WARNING "Target ${TARGET_UID} is a library used for testing only." 02345 " Installation to the specified directory will be skipped.") 02346 set (ARGN_DESTINATION) 02347 endif () 02348 else () 02349 if (ARGN_DESTINATION) 02350 if (IS_ABSOLUTE "${ARGN_DESTINATION}") 02351 file (RELATIVE_PATH ARGN_DESTINATION "${CMAKE_INSTALL_PREFIX}" "${ARGN_DESTINATION}") 02352 endif () 02353 else () 02354 if (DEFINED INSTALL_${ARGN_LANGUAGE}_LIBRARY_DIR) 02355 set (ARGN_DESTINATION "${INSTALL_${ARGN_LANGUAGE}_LIBRARY_DIR}") 02356 else () 02357 set (ARGN_DESTINATION "${INSTALL_LIBRARY_DIR}") 02358 endif () 02359 endif () 02360 endif () 02361 # common module prefix 02362 if (ARGN_LANGUAGE MATCHES "^([JP]YTHON|PERL|MATLAB|BASH)$") 02363 basis_library_prefix (PREFIX ${ARGN_LANGUAGE}) 02364 else () 02365 set (PREFIX) 02366 endif () 02367 # script configuration ("compile definitions") 02368 if (EXISTS "${BINARY_CONFIG_DIR}/ScriptConfig.cmake") 02369 set (CONFIG_FILE "${BINARY_CONFIG_DIR}/ScriptConfig.cmake") 02370 else () 02371 set (CONFIG_FILE) 02372 endif () 02373 # auto-detect use of BASIS utilities 02374 if (ARGN_LANGUAGE MATCHES "[JP]YTHON") 02375 set (UTILITIES_LANGUAGE "PYTHON") 02376 else () 02377 set (UTILITIES_LANGUAGE "${ARGN_LANGUAGE}") 02378 endif () 02379 if (ARGN_USE_BASIS_UTILITIES) 02380 if (NOT BASIS_UTILITIES_ENABLED MATCHES "${UTILITIES_LANGUAGE}") 02381 message (FATAL_ERROR "Target ${TARGET_UID} requires the BASIS utilities for ${UTILITIES_LANGUAGE}" 02382 " but BASIS was either build without the build of these utilities enabled" 02383 " or no utilities for this programming language are implemented. Remove the" 02384 " USE_BASIS_UTILITIES option if no BASIS utilities are used by the modules" 02385 " of the library or specify the correct programming language if it was not" 02386 " detected correctly.") 02387 endif () 02388 set (USES_BASIS_UTILITIES TRUE) 02389 elseif (NOT ARGN_NO_BASIS_UTILITIES AND NOT UTILITIES_LANGUAGE MATCHES "UNKNOWN") 02390 set (USES_BASIS_UTILITIES FALSE) 02391 foreach (M IN LISTS SOURCES) 02392 basis_utilities_check (USES_BASIS_UTILITIES "${M}" ${UTILITIES_LANGUAGE}) 02393 if (USES_BASIS_UTILITIES) 02394 break () 02395 endif () 02396 endforeach () 02397 else () 02398 set (USES_BASIS_UTILITIES FALSE) 02399 endif () 02400 if (USES_BASIS_UTILITIES) 02401 basis_set_project_property (PROPERTY PROJECT_USES_${UTILITIES_LANGUAGE}_UTILITIES TRUE) 02402 if (BASIS_DEBUG) 02403 message ("** Target ${TARGET_UID} uses the BASIS utilities for ${UTILITIES_LANGUAGE}.") 02404 endif () 02405 endif () 02406 # add custom target 02407 add_custom_target (${TARGET_UID} ALL SOURCES ${SOURCES}) 02408 _set_target_properties ( 02409 ${TARGET_UID} 02410 PROPERTIES 02411 LANGUAGE "${ARGN_LANGUAGE}" 02412 BASIS_TYPE "SCRIPT_LIBRARY" 02413 BASIS_UTILITIES "${USES_BASIS_UTILITIES}" 02414 SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" 02415 BINARY_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 02416 LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY}" 02417 LIBRARY_INSTALL_DIRECTORY "${ARGN_DESTINATION}" 02418 LIBRARY_COMPONENT "${BASIS_LIBRARY_COMPONENT}" 02419 PREFIX "${PREFIX}" 02420 COMPILE_DEFINITIONS "" 02421 COMPILE_DEFINITIONS_FILE "${CONFIG_FILE}" 02422 LINK_DEPENDS "" 02423 EXPORT "${EXPORT}" 02424 COMPILE "${BASIS_COMPILE_SCRIPTS}" 02425 TEST "${TEST}" 02426 ) 02427 # add target to list of targets 02428 basis_set_project_property (APPEND PROPERTY TARGETS "${TARGET_UID}") 02429 message (STATUS "Adding script library ${TARGET_UID}... - done") 02430 endfunction () 02431 02432 # ============================================================================ 02433 # custom build commands 02434 # ============================================================================ 02435 02436 # ---------------------------------------------------------------------------- 02437 ## @brief Finalize custom targets by adding the missing build commands. 02438 # 02439 # This function is called by basis_project_impl() in order to finalize the 02440 # addition of the custom build targets such as, for example, build targets 02441 # for the build of executable scripts, Python packages, MATLAB Compiler 02442 # executables and shared libraries, and MEX-files. 02443 # 02444 # @returns Generates the CMake build scripts and adds custom build commands 02445 # and corresponding targets for the execution of these scripts. 02446 # 02447 # @sa basis_build_script() 02448 # @sa basis_build_script_library() 02449 # @sa basis_build_mcc_target() 02450 # @sa basis_build_mex_file() 02451 function (basis_finalize_targets) 02452 basis_get_project_property (TARGETS PROPERTY TARGETS) 02453 foreach (TARGET_UID ${TARGETS}) 02454 if (NOT TARGET _${TARGET_UID}) 02455 get_target_property (BASIS_TYPE ${TARGET_UID} BASIS_TYPE) 02456 if (BASIS_TYPE MATCHES "^EXECUTABLE$|^(SHARED|MODULE)_LIBRARY$") 02457 basis_set_target_install_rpath (${TARGET_UID}) 02458 elseif (BASIS_TYPE MATCHES "SCRIPT_LIBRARY") 02459 basis_build_script_library (${TARGET_UID}) 02460 elseif (BASIS_TYPE MATCHES "SCRIPT") 02461 basis_build_script (${TARGET_UID}) 02462 elseif (BASIS_TYPE MATCHES "MEX") 02463 basis_build_mex_file (${TARGET_UID}) 02464 elseif (BASIS_TYPE MATCHES "MCC") 02465 basis_build_mcc_target (${TARGET_UID}) 02466 endif () 02467 endif () 02468 endforeach () 02469 endfunction () 02470 02471 # ---------------------------------------------------------------------------- 02472 ## @brief Set INSTALL_RPATH property of executable or shared library target. 02473 # 02474 # This function sets the @c INSTALL_RPATH property of a specified executable or 02475 # shared library target using the @c LINK_DEPENDS obtained using the 02476 # basis_get_target_link_libraries() function. It determines the installation 02477 # location of each dependency using the basis_get_target_location() function. 02478 # 02479 # @returns Sets the @c INSTALL_RPATH property of the specified target. 02480 # 02481 # @sa basis_get_target_link_libraries() 02482 function (basis_set_target_install_rpath TARGET_NAME) 02483 basis_get_target_uid (TARGET_UID "${TARGET_NAME}") 02484 if (NOT TARGET "${TARGET_UID}") 02485 message (FATAL_ERROR "Unknown target: ${TARGET_UID}") 02486 endif () 02487 if (BASIS_DEBUG) 02488 message ("** basis_set_target_install_rpath():") 02489 message ("** TARGET_NAME: ${TARGET_UID}") 02490 endif () 02491 if (CMAKE_HOST_APPLE) 02492 set (ORIGIN "@loader_path") 02493 else () 02494 set (ORIGIN "\$ORIGIN") 02495 endif () 02496 # always prefer libraries located within the same directory 02497 set (INSTALL_RPATH "${ORIGIN}/.") 02498 # common default RPATH (rarely used) 02499 if (CMAKE_INSTALL_RPATH) 02500 set (INSTALL_RPATH "${INSTALL_RPATH};${CMAKE_INSTALL_RPATH}") 02501 endif () 02502 # get location of target used to make paths relative to this $ORIGIN 02503 basis_get_target_location (TARGET_LOCATION ${TARGET_UID} POST_INSTALL_PATH) 02504 # directories of external projects belonging to same bundle which 02505 # were added using [basis_]link_directories() command 02506 basis_get_project_property (BUNDLE_LINK_DIRS PROPERTY BUNDLE_LINK_DIRS) 02507 foreach (LINK_DIR ${BUNDLE_LINK_DIRS}) 02508 list (FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${LINK_DIR}" IDX) 02509 if (IDX EQUAL -1) 02510 if (BASIS_DEBUG AND BASIS_VERBOSE) 02511 message ("** BUNDLE_LINK_DIR: ${LINK_DIR}") 02512 endif () 02513 basis_get_relative_path (RPATH "${TARGET_LOCATION}" "${LINK_DIR}") 02514 list (APPEND INSTALL_RPATH "${ORIGIN}/${RPATH}") 02515 endif () 02516 endforeach () 02517 # directories of link libraries 02518 # 02519 # only the libraries of this project and targets imported 02520 # from other projects which are part of the same bundle 02521 basis_get_target_link_libraries (LINK_DEPENDS ${TARGET_UID}) 02522 if (BASIS_DEBUG AND BASIS_VERBOSE) 02523 message ("** LINK_DEPENDS: [${LINK_DEPENDS}]") 02524 endif () 02525 foreach (LINK_DEPEND ${LINK_DEPENDS}) 02526 set (DEPEND_LOCATION) 02527 if (TARGET "${LINK_DEPEND}") 02528 basis_get_target_property (BUNDLED ${LINK_DEPEND} BUNDLED) 02529 basis_get_target_property (IMPORTED ${LINK_DEPEND} IMPORTED) 02530 if (NOT IMPORTED OR BUNDLED) 02531 basis_get_target_location (DEPEND_LOCATION ${LINK_DEPEND} POST_INSTALL_PATH) 02532 if (BASIS_DEBUG AND BASIS_VERBOSE) 02533 message ("** LOCATION(${LINK_DEPEND}): ${DEPEND_LOCATION}") 02534 endif () 02535 endif () 02536 elseif (IS_ABSOLUTE "${LINK_DEPEND}") 02537 if (IS_DIRECTORY "${LINK_DEPEND}") 02538 set (DEPEND_LOCATION "${LINK_DEPEND}") 02539 else () 02540 get_filename_component (DEPEND_LOCATION "${LINK_DEPEND}" PATH) 02541 endif () 02542 list (FIND BUNDLE_LINK_DIRS "${DEPEND_LOCATION}" IDX) 02543 if (IDX EQUAL -1) 02544 set (DEPEND_LOCATION) 02545 endif () 02546 endif () 02547 if (DEPEND_LOCATION) 02548 list (FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${DEPEND_LOCATION}" IDX) 02549 if (IDX EQUAL -1) 02550 basis_get_relative_path (RPATH "${TARGET_LOCATION}" "${DEPEND_LOCATION}") 02551 list (APPEND INSTALL_RPATH "${ORIGIN}/${RPATH}") 02552 endif () 02553 endif () 02554 endforeach () 02555 # remove duplicates 02556 if (INSTALL_RPATH) 02557 list (REMOVE_DUPLICATES INSTALL_RPATH) 02558 endif () 02559 # set INSTALL_RPATH property 02560 string (REPLACE ";" ":" INSTALL_RPATH "${INSTALL_RPATH}") 02561 _set_target_properties (${TARGET_UID} PROPERTIES INSTALL_RPATH "${INSTALL_RPATH}") 02562 if (BASIS_DEBUG) 02563 message ("** INSTALL_RPATH: [${INSTALL_RPATH}]") 02564 endif () 02565 endfunction () 02566 02567 # ---------------------------------------------------------------------------- 02568 ## @brief Add custom command for build of single script. 02569 # 02570 # This function is called by basis_finalize_targets() which in turn is called 02571 # at the end of basis_project_impl(), i.e., the end of the root CMake 02572 # configuration file of the (sub-)project. 02573 # 02574 # @param [in] TARGET_UID Name/UID of custom target added by basis_add_script(). 02575 # 02576 # @sa basis_add_script() 02577 function (basis_build_script TARGET_UID) 02578 # does this target exist ? 02579 basis_get_target_uid (TARGET_UID "${TARGET_UID}") 02580 if (NOT TARGET "${TARGET_UID}") 02581 message (FATAL_ERROR "Unknown build target: ${TARGET_UID}") 02582 endif () 02583 if (BASIS_VERBOSE) 02584 message (STATUS "Adding build command for target ${TARGET_UID}...") 02585 endif () 02586 # get target properties 02587 basis_get_target_link_libraries (LINK_DEPENDS ${TARGET_UID}) # paths of script modules/packages 02588 # including BASIS utilities if used 02589 set ( 02590 PROPERTIES 02591 LANGUAGE # programming language of script 02592 BASIS_TYPE # must match "^SCRIPT_(EXECUTABLE|LIBEXEC|MODULE)$" 02593 SOURCE_DIRECTORY # CMake source directory 02594 BINARY_DIRECTORY # CMake binary directory 02595 OUTPUT_DIRECTORY # output directory for built script 02596 INSTALL_DIRECTORY # installation directory for built script 02597 COMPONENT # installation component 02598 OUTPUT_NAME # name of built script including extension (if any) 02599 PREFIX # name prefix 02600 SUFFIX # name suffix (e.g., extension for executable script) 02601 COMPILE_DEFINITIONS # CMake code to set variables used to configure script 02602 COMPILE_DEFINITIONS_FILE # script configuration file 02603 TEST # whether this script is used for testing only 02604 EXPORT # whether this target shall be exported 02605 COMPILE # whether to compile script if applicable 02606 SOURCES # path of script source file 02607 ) 02608 foreach (PROPERTY ${PROPERTIES}) 02609 get_target_property (${PROPERTY} ${TARGET_UID} ${PROPERTY}) 02610 endforeach () 02611 set (EXECUTABLE FALSE) 02612 set (LIBEXEC FALSE) 02613 set (MODULE FALSE) 02614 if (BASIS_TYPE MATCHES "^SCRIPT_(EXECUTABLE|LIBEXEC|MODULE)$") 02615 set (${CMAKE_MATCH_1} TRUE) 02616 if (LIBEXEC) 02617 set (EXECUTABLE TRUE) 02618 endif () 02619 else () 02620 message (FATAL_ERROR "Target ${TARGET_UID}: Unexpected BASIS_TYPE: ${BASIS_TYPE}") 02621 endif () 02622 if (NOT BINARY_DIRECTORY) 02623 message (FATAL_ERROR "Target ${TARGET_UID}: Missing BINARY_DIRECTORY property!") 02624 endif () 02625 if (NOT BINARY_DIRECTORY MATCHES "^${CMAKE_BINARY_DIR}(/|$)") 02626 message (FATAL_ERROR "Target ${TARGET_UID}: BINARY_DIRECTORY must be inside of build tree!") 02627 endif () 02628 if (INSTALL_DIRECTORY AND NOT COMPONENT) 02629 set (COMPONENT "Unspecified") 02630 endif () 02631 list (LENGTH SOURCES L) 02632 if (NOT L EQUAL 2) 02633 message (FATAL_ERROR "Target ${TARGET_UID}: Expected two elements in SOURCES list!" 02634 " Have you accidentally modified this read-only property or" 02635 " is your (newer) CMake version not compatible with BASIS?") 02636 endif () 02637 list (GET SOURCES 0 BUILD_DIR) # strange, but CMake stores path to internal build directory here 02638 list (GET SOURCES 1 SOURCE_FILE) 02639 set (BUILD_DIR "${BUILD_DIR}.dir") 02640 # output name 02641 if (NOT OUTPUT_NAME) 02642 basis_get_target_name (OUTPUT_NAME ${TARGET_UID}) 02643 endif () 02644 if (PREFIX) 02645 set (OUTPUT_NAME "${PREFIX}${OUTPUT_NAME}") 02646 endif () 02647 if (SUFFIX) 02648 set (OUTPUT_NAME "${OUTPUT_NAME}${SUFFIX}") 02649 endif () 02650 # arguments of build script 02651 set (OUTPUT_FILE "${OUTPUT_DIRECTORY}/${OUTPUT_NAME}") 02652 if (INSTALL_DIRECTORY) 02653 get_filename_component (SOURCE_NAME "${SOURCE_FILE}" NAME) 02654 set (INSTALL_FILE "${BUILD_DIR}/build/${SOURCE_NAME}") 02655 string (REGEX REPLACE "\\.in$" "" INSTALL_FILE "${INSTALL_FILE}") 02656 set (DESTINATION "${INSTALL_DIRECTORY}") 02657 if (NOT IS_ABSOLUTE "${DESTINATION}") 02658 set (DESTINATION "${CMAKE_INSTALL_PREFIX}/${DESTINATION}") 02659 endif () 02660 else () 02661 set (INSTALL_FILE) 02662 set (DESTINATION) 02663 endif () 02664 set (CONFIG_FILE) 02665 if (EXISTS "${BASIS_SCRIPT_CONFIG_FILE}") 02666 list (APPEND CONFIG_FILE "${BASIS_SCRIPT_CONFIG_FILE}") 02667 endif () 02668 if (COMPILE_DEFINITIONS_FILE) 02669 list (APPEND CONFIG_FILE ${COMPILE_DEFINITIONS_FILE}) 02670 endif () 02671 if (COMPILE_DEFINITIONS) 02672 file (WRITE "${BUILD_DIR}/ScriptConfig.cmake" "# DO NOT edit. Automatically generated by BASIS.\n${COMPILE_DEFINITIONS}\n") 02673 list (APPEND CONFIG_FILE "${BUILD_DIR}/ScriptConfig.cmake") 02674 endif () 02675 set (CACHE_FILE "${BUILD_DIR}/cache.cmake") 02676 set (OPTIONS) 02677 foreach (FLAG IN ITEMS COMPILE EXECUTABLE) 02678 if (${FLAG}) 02679 list (APPEND OPTIONS ${FLAG}) 02680 endif () 02681 endforeach () 02682 # link dependencies - module search paths 02683 set (BUILD_LINK_DEPENDS) 02684 set (INSTALL_LINK_DEPENDS) 02685 foreach (LINK_DEPEND IN LISTS LINK_DEPENDS) 02686 basis_get_target_uid (UID "${LINK_DEPEND}") 02687 if (TARGET "${UID}") 02688 get_target_property (IMPORTED ${UID} IMPORTED) 02689 get_target_property (BUNDLED ${UID} BUNDLED) 02690 if (IMPORTED AND NOT BUNDLED) 02691 basis_get_target_location (LOCATION "${UID}" ABSOLUTE) 02692 if (LOCATION) 02693 list (APPEND BUILD_LINK_DEPENDS "${LOCATION}") 02694 list (APPEND INSTALL_LINK_DEPENDS "${LOCATION}") 02695 else () 02696 message (WARNING "Could not determine build tree location of file corresponding to target ${UID}") 02697 endif () 02698 else () 02699 basis_get_target_location (LOCATION "${UID}" ABSOLUTE) 02700 if (LOCATION) 02701 list (APPEND BUILD_LINK_DEPENDS "${LOCATION}") 02702 else () 02703 message (WARNING "Could not determine build tree location of file corresponding to target ${UID}") 02704 endif () 02705 basis_get_target_property (LINK_DEPEND_IS_TEST "${UID}" TEST) 02706 if (NOT LINK_DEPEND_IS_TEST) 02707 basis_get_target_location (LOCATION "${UID}" POST_INSTALL) 02708 if (LOCATION) 02709 list (APPEND INSTALL_LINK_DEPENDS "relative ${LOCATION}") 02710 else () 02711 message (WARNING "Could not determine installation location of file corresponding to target ${UID}") 02712 endif () 02713 endif () 02714 endif () 02715 else () 02716 list (APPEND BUILD_LINK_DEPENDS "${LINK_DEPEND}") 02717 list (APPEND INSTALL_LINK_DEPENDS "${LINK_DEPEND}") 02718 endif () 02719 endforeach () 02720 # prepend own module search paths - if dependencies among own modules 02721 # not specified or to ensure that 02722 # these are preferred 02723 if (LANGUAGE MATCHES "JYTHON") 02724 if (BINARY_PYTHON_LIBRARY_DIR) 02725 list (INSERT BUILD_LINK_DEPENDS 0 "${BINARY_PYTHON_LIBRARY_DIR}") 02726 endif () 02727 if (INSTALL_PYTHON_LIBRARY_DIR) 02728 list (INSERT INSTALL_LINK_DEPENDS 0 "relative ${CMAKE_INSTALL_PREFIX}/${INSTALL_PYTHON_LIBRARY_DIR}") 02729 endif () 02730 endif () 02731 if (BINARY_${LANGUAGE}_LIBRARY_DIR) 02732 list (INSERT BUILD_LINK_DEPENDS 0 "${BINARY_${LANGUAGE}_LIBRARY_DIR}") 02733 endif () 02734 if (INSTALL_${LANGUAGE}_LIBRARY_DIR) 02735 list (INSERT INSTALL_LINK_DEPENDS 0 "relative ${CMAKE_INSTALL_PREFIX}/${INSTALL_${LANGUAGE}_LIBRARY_DIR}") 02736 endif () 02737 list (INSERT BUILD_LINK_DEPENDS 0 "${BINARY_LIBRARY_DIR}") 02738 list (INSERT INSTALL_LINK_DEPENDS 0 "relative ${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBRARY_DIR}") 02739 if (TEST) 02740 list (INSERT BUILD_LINK_DEPENDS 0 "${TESTING_LIBRARY_DIR}") 02741 endif () 02742 if (BUILD_LINK_DEPENDS) 02743 list (REMOVE_DUPLICATES BUILD_LINK_DEPENDS) 02744 endif () 02745 if (INSTALL_LINK_DEPENDS) 02746 list (REMOVE_DUPLICATES INSTALL_LINK_DEPENDS) 02747 endif () 02748 # remove default site-packages directories 02749 if (LANGUAGE MATCHES "[JP]YTHON|PERL") 02750 list (REMOVE_ITEM BUILD_LINK_DEPENDS "${${LANGUAGE}_SITELIB}") 02751 list (REMOVE_ITEM INSTALL_LINK_DEPENDS "${${LANGUAGE}_SITELIB}") 02752 endif () 02753 # configure build script 02754 set (BUILD_SCRIPT "${BUILD_DIR}/build.cmake") 02755 configure_file ("${BASIS_MODULE_PATH}/configure_script.cmake.in" "${BUILD_SCRIPT}" @ONLY) 02756 # list of all output files 02757 set (OUTPUT_FILES "${OUTPUT_FILE}") 02758 if (INSTALL_FILE) 02759 list (APPEND OUTPUT_FILES "${INSTALL_FILE}") 02760 endif () 02761 if (MODULE AND COMPILE) 02762 basis_get_compiled_file (OUTPUT_CFILE "${OUTPUT_FILE}" ${LANGUAGE}) 02763 basis_get_compiled_file (INSTALL_CFILE "${INSTALL_FILE}" ${LANGUAGE}) 02764 if (OUTPUT_CFILE) 02765 list (APPEND OUTPUT_FILES "${OUTPUT_CFILE}") 02766 endif () 02767 if (INSTALL_CFILE) 02768 list (APPEND OUTPUT_FILES "${INSTALL_CFILE}") 02769 endif () 02770 if (LANGUAGE MATCHES "PYTHON") 02771 basis_compile_python_modules_for_jython (RV) 02772 if (RV) 02773 basis_get_compiled_jython_file_of_python_module (JYTHON_OUTPUT_CFILE "${OUTPUT_FILE}") 02774 basis_get_compiled_file (JYTHON_INSTALL_CFILE "${INSTALL_FILE}" JYTHON) 02775 if (JYTHON_OUTPUT_CFILE) 02776 list (APPEND OUTPUT_FILES "${JYTHON_OUTPUT_CFILE}") 02777 endif () 02778 if (JYTHON_INSTALL_CFILE) 02779 list (APPEND OUTPUT_FILES "${JYTHON_INSTALL_CFILE}") 02780 endif () 02781 endif () 02782 endif () 02783 endif () 02784 # add build command for script 02785 if (OUTPUT_CFILE) 02786 file (RELATIVE_PATH REL "${CMAKE_BINARY_DIR}" "${OUTPUT_CFILE}") 02787 else () 02788 file (RELATIVE_PATH REL "${CMAKE_BINARY_DIR}" "${OUTPUT_FILE}") 02789 endif () 02790 if (LANGUAGE MATCHES "UNKNOWN") 02791 set (COMMENT "Building script ${REL}...") 02792 elseif (MODULE) 02793 set (COMMENT "Building ${LANGUAGE} module ${REL}...") 02794 else () 02795 set (COMMENT "Building ${LANGUAGE} executable ${REL}...") 02796 endif () 02797 add_custom_command ( 02798 OUTPUT ${OUTPUT_FILES} 02799 COMMAND "${CMAKE_COMMAND}" -P "${BUILD_SCRIPT}" 02800 MAIN_DEPENDENCY "${SOURCE_FILE}" 02801 DEPENDS "${BUILD_SCRIPT}" "${BASIS_MODULE_PATH}/CommonTools.cmake" # basis_configure_script() definition 02802 "${BUILD_DIR}/cache.cmake" ${CONFIG_FILE} 02803 COMMENT "${COMMENT}" 02804 VERBATIM 02805 ) 02806 # add custom target 02807 add_custom_target (_${TARGET_UID} DEPENDS ${OUTPUT_FILES}) 02808 foreach (T IN LISTS LINK_DEPENDS) 02809 if (TARGET ${T}) 02810 add_dependencies (_${TARGET_UID} ${T}) 02811 endif () 02812 endforeach () 02813 if (TARGET __${TARGET_UID}) # re-glob source files 02814 add_dependencies (_${TARGET_UID} __${TARGET_UID}) 02815 endif () 02816 add_dependencies (${TARGET_UID} _${TARGET_UID}) 02817 # cleanup on "make clean" - including compiled files regardless of COMPILE flag 02818 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${OUTPUT_FILES}) 02819 foreach (OUTPUT_FILE IN LISTS OUTPUT_FILES) 02820 basis_get_compiled_file (CFILE "${OUTPUT_FILE}" ${LANGUAGE}) 02821 if (CFILE) 02822 list (FIND OUTPUT_FILES "${CFILE}" IDX) 02823 if (IDX EQUAL -1) 02824 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CFILE}") 02825 endif () 02826 endif () 02827 endforeach () 02828 # export target 02829 if (EXPORT) 02830 if (TEST) 02831 basis_set_project_property (APPEND PROPERTY TEST_EXPORT_TARGETS "${TARGET_UID}") 02832 else () 02833 basis_set_project_property (APPEND PROPERTY CUSTOM_EXPORT_TARGETS "${TARGET_UID}") 02834 endif () 02835 endif () 02836 # install script 02837 if (INSTALL_DIRECTORY) 02838 if (INSTALL_CFILE) 02839 if (MODULE AND LANGUAGE MATCHES "PYTHON") 02840 basis_compile_python_modules_for_jython (RV) 02841 if (RV) 02842 basis_get_compiled_script (INSTALL_JYTHON_CFILE "${INSTALL_FILE}" JYTHON) 02843 basis_sanitize_for_regex (LIBRE "${INSTALL_PYTHON_LIBRARY_DIR}") 02844 basis_sanitize_for_regex (SITERE "${INSTALL_PYTHON_SITE_DIR}") 02845 if (INSTALL_CFILE MATCHES "^${LIBRE}/" AND INSTALL_JYTHON_LIBRARY_DIR) 02846 string (REGEX REPLACE "^${LIBRE}/" "${INSTALL_JYTHON_LIBRARY_DIR}/" INSTALL_DIRECTORY_JYTHON "${INSTALL_DIRECTORY}") 02847 elseif (INSTALL_CFILE MATCHES "^${SITERE}/" AND INSTALL_JYTHON_SITE_DIR) 02848 string (REGEX REPLACE "^${SITERE}/" "${INSTALL_JYTHON_SITE_DIR}/" INSTALL_DIRECTORY_JYTHON "${INSTALL_DIRECTORY}") 02849 else () 02850 set (INSTALL_DIRECTORY_JYTHON "${INSTALL_DIRECTORY}") 02851 endif () 02852 install ( 02853 FILES "${INSTALL_JYTHON_CFILE}" 02854 DESTINATION "${INSTALL_DIRECTORY_JYTHON}" 02855 COMPONENT "${COMPONENT}" 02856 ) 02857 endif () 02858 endif () 02859 set (INSTALL_FILE "${INSTALL_CFILE}") 02860 elseif (NOT INSTALL_FILE) 02861 set (INSTALL_FILE "${OUTPUT_FILE}") 02862 endif () 02863 if (MODULE) 02864 set (INSTALLTYPE FILES) 02865 else () 02866 set (INSTALLTYPE PROGRAMS) 02867 endif () 02868 install ( 02869 ${INSTALLTYPE} "${INSTALL_FILE}" 02870 DESTINATION "${INSTALL_DIRECTORY}" 02871 COMPONENT "${COMPONENT}" 02872 RENAME "${OUTPUT_NAME}" 02873 ) 02874 endif () 02875 # done 02876 if (BASIS_VERBOSE) 02877 message (STATUS "Adding build command for target ${TARGET_UID}... - done") 02878 endif () 02879 endfunction () 02880 02881 # ---------------------------------------------------------------------------- 02882 ## @brief Add custom command for build of script library. 02883 # 02884 # This function is called by basis_finalize_targets() which in turn is called 02885 # at the end of basis_project_impl(), i.e., the end of the root CMake 02886 # configuration file of the (sub-)project. 02887 # 02888 # @param [in] TARGET_UID Name/UID of custom target added by basis_add_script_library(). 02889 # 02890 # @sa basis_add_script_library() 02891 function (basis_build_script_library TARGET_UID) 02892 # does this target exist ? 02893 basis_get_target_uid (TARGET_UID "${TARGET_UID}") 02894 if (NOT TARGET "${TARGET_UID}") 02895 message (FATAL_ERROR "Unknown target: ${TARGET_UID}") 02896 endif () 02897 if (BASIS_VERBOSE) 02898 message (STATUS "Adding build command for target ${TARGET_UID}...") 02899 endif () 02900 # get target properties 02901 basis_get_target_link_libraries (LINK_DEPENDS ${TARGET_UID}) # paths of script modules/packages 02902 # including BASIS utilities if used 02903 set ( 02904 PROPERTIES 02905 LANGUAGE # programming language of modules 02906 BASIS_TYPE # must be "SCRIPT_LIBRARY" 02907 BASIS_UTILITIES # whether this target requires the BASIS utilities 02908 SOURCE_DIRECTORY # CMake source directory 02909 BINARY_DIRECTORY # CMake binary directory 02910 LIBRARY_OUTPUT_DIRECTORY # output directory for built modules 02911 LIBRARY_INSTALL_DIRECTORY # installation directory for built modules 02912 LIBRARY_COMPONENT # installation component 02913 PREFIX # common prefix for modules 02914 COMPILE_DEFINITIONS # CMake code to set variables used to configure modules 02915 COMPILE_DEFINITIONS_FILE # script configuration file 02916 LINK_DEPENDS # paths of script modules/packages used by the modules of this library 02917 EXPORT # whether to export this target 02918 COMPILE # whether to compile the modules/library if applicable 02919 SOURCES # source files of module scripts 02920 ) 02921 foreach (PROPERTY ${PROPERTIES}) 02922 get_target_property (${PROPERTY} ${TARGET_UID} ${PROPERTY}) 02923 endforeach () 02924 if (NOT BASIS_TYPE MATCHES "^SCRIPT_LIBRARY$") 02925 message (FATAL_ERROR "Target ${TARGET_UID}: Unexpected BASIS_TYPE: ${BASIS_TYPE}") 02926 endif () 02927 if (NOT SOURCE_DIRECTORY) 02928 message (FATAL_ERROR "Missing SOURCE_DIRECTORY property!") 02929 endif () 02930 if (NOT LIBRARY_OUTPUT_DIRECTORY) 02931 message (FATAL_ERROR "Missing LIBRARY_OUTPUT_DIRECTORY property!") 02932 endif () 02933 if (NOT IS_ABSOLUTE "${LIBRARY_OUTPUT_DIRECTORY}") 02934 set (LIBRARY_OUTPUT_DIRECTORY "${BASIS_PROJECT_BINARY_DIR}/${LIBRARY_OUTPUT_DIRECTORY}") 02935 endif () 02936 if (NOT LIBRARY_OUTPUT_DIRECTORY MATCHES "^${CMAKE_BINARY_DIR}") 02937 message (FATAL_ERROR "Output directory LIBRARY_OUTPUT_DIRECTORY is outside the build tree!") 02938 endif () 02939 if (NOT LIBRARY_COMPONENT) 02940 set (LIBRARY_COMPONENT "Unspecified") 02941 endif () 02942 list (GET SOURCES 0 BUILD_DIR) # strange, but CMake stores path to internal build directory here 02943 list (REMOVE_AT SOURCES 0) 02944 set (BUILD_DIR "${BUILD_DIR}.dir") 02945 if (NOT SOURCES) 02946 message (FATAL_ERROR "Target ${TARGET_UID}: Empty SOURCES list!" 02947 " Have you accidentally modified this read-only property or" 02948 " is your (newer) CMake version not compatible with BASIS?") 02949 endif () 02950 # common arguments of build script 02951 set (CONFIG_FILE) 02952 if (EXISTS "${BASIS_SCRIPT_CONFIG_FILE}") 02953 list (APPEND CONFIG_FILE "${BASIS_SCRIPT_CONFIG_FILE}") 02954 endif () 02955 if (COMPILE_DEFINITIONS_FILE) 02956 list (APPEND CONFIG_FILE ${COMPILE_DEFINITIONS_FILE}) 02957 endif () 02958 if (COMPILE_DEFINITIONS) 02959 file (WRITE "${BUILD_DIR}/ScriptConfig.cmake" "# DO NOT edit. Automatically generated by BASIS.\n${COMPILE_DEFINITIONS}\n") 02960 list (APPEND CONFIG_FILE "${BUILD_DIR}/ScriptConfig.cmake") 02961 endif () 02962 set (CACHE_FILE "${BUILD_DIR}/cache.cmake") 02963 set (OPTIONS) # no additional options 02964 if (COMPILE) 02965 list (APPEND OPTIONS COMPILE) 02966 endif () 02967 # add build command for each module 02968 set (OUTPUT_FILES) # list of all output files 02969 set (FILES_TO_INSTALL) # list of output files for installation 02970 set (BINARY_INSTALL_DIRECTORY "${BUILD_DIR}/build") # common base directory for files to install 02971 foreach (SOURCE_FILE IN LISTS SOURCES) 02972 file (RELATIVE_PATH S "${SOURCE_DIRECTORY}" "${SOURCE_FILE}") 02973 string (REGEX REPLACE "\\.in$" "" S "${S}") 02974 basis_get_source_target_name (BUILD_SCRIPT_NAME "build_${S}") 02975 # arguments of build script 02976 if (PREFIX) 02977 set (S "${PREFIX}${S}") 02978 endif () 02979 set (OUTPUT_FILE "${LIBRARY_OUTPUT_DIRECTORY}/${S}") 02980 if (LIBRARY_INSTALL_DIRECTORY) 02981 set (INSTALL_FILE "${BINARY_INSTALL_DIRECTORY}/${S}") 02982 set (DESTINATION "${LIBRARY_INSTALL_DIRECTORY}/${S}") 02983 if (NOT IS_ABSOLUTE "${DESTINATION}") 02984 set (DESTINATION "${CMAKE_INSTALL_PREFIX}/${DESTINATION}") 02985 endif () 02986 get_filename_component (DESTINATION "${DESTINATION}" PATH) 02987 else () 02988 set (INSTALL_FILE) 02989 set (DESTINATION) 02990 endif () 02991 # configure build script 02992 set (BUILD_SCRIPT "${BUILD_DIR}/${BUILD_SCRIPT_NAME}.cmake") 02993 configure_file ("${BASIS_MODULE_PATH}/configure_script.cmake.in" "${BUILD_SCRIPT}" @ONLY) 02994 # output files of this command 02995 set (_OUTPUT_FILES "${OUTPUT_FILE}") 02996 if (INSTALL_FILE) 02997 list (APPEND _OUTPUT_FILES "${INSTALL_FILE}") 02998 endif () 02999 if (COMPILE) 03000 basis_get_compiled_file (OUTPUT_CFILE "${OUTPUT_FILE}" ${LANGUAGE}) 03001 basis_get_compiled_file (INSTALL_CFILE "${INSTALL_FILE}" ${LANGUAGE}) 03002 if (OUTPUT_CFILE) 03003 list (APPEND _OUTPUT_FILES "${OUTPUT_CFILE}") 03004 endif () 03005 if (INSTALL_CFILE) 03006 list (APPEND _OUTPUT_FILES "${INSTALL_CFILE}") 03007 endif () 03008 if (LANGUAGE MATCHES "PYTHON") 03009 basis_compile_python_modules_for_jython (RV) 03010 if (RV) 03011 basis_get_compiled_jython_file_of_python_module (JYTHON_OUTPUT_CFILE "${OUTPUT_FILE}") 03012 basis_get_compiled_file (JYTHON_INSTALL_CFILE "${INSTALL_FILE}" JYTHON) 03013 if (JYTHON_OUTPUT_CFILE) 03014 list (APPEND _OUTPUT_FILES "${JYTHON_OUTPUT_CFILE}") 03015 endif () 03016 if (JYTHON_INSTALL_CFILE) 03017 list (APPEND _OUTPUT_FILES "${JYTHON_INSTALL_CFILE}") 03018 endif () 03019 endif () 03020 endif () 03021 endif () 03022 if (INSTALL_CFILE) 03023 list (APPEND FILES_TO_INSTALL "${INSTALL_CFILE}") 03024 elseif (INSTALL_FILE) 03025 list (APPEND FILES_TO_INSTALL "${INSTALL_FILE}") 03026 endif () 03027 # add build command 03028 if (OUTPUT_CFILE) 03029 file (RELATIVE_PATH REL "${CMAKE_BINARY_DIR}" "${OUTPUT_CFILE}") 03030 else () 03031 file (RELATIVE_PATH REL "${CMAKE_BINARY_DIR}" "${OUTPUT_FILE}") 03032 endif () 03033 set (COMMENT "Building ${LANGUAGE} module ${REL}...") 03034 add_custom_command ( 03035 OUTPUT ${_OUTPUT_FILES} 03036 COMMAND "${CMAKE_COMMAND}" -P "${BUILD_SCRIPT}" 03037 MAIN_DEPENDENCY "${SOURCE_FILE}" 03038 DEPENDS "${BUILD_SCRIPT}" "${BASIS_MODULE_PATH}/CommonTools.cmake" # basis_configure_script() definition 03039 "${BUILD_DIR}/cache.cmake" ${CONFIG_FILE} 03040 COMMENT "${COMMENT}" 03041 VERBATIM 03042 ) 03043 # add output files of command to list of all output files 03044 list (APPEND OUTPUT_FILES ${_OUTPUT_FILES}) 03045 endforeach () 03046 # add custom target to build modules 03047 add_custom_target (_${TARGET_UID} DEPENDS ${OUTPUT_FILES}) 03048 foreach (T IN LISTS LINK_DEPENDS) 03049 if (TARGET ${T}) 03050 add_dependencies (_${TARGET_UID} ${T}) 03051 endif () 03052 endforeach () 03053 if (TARGET __${TARGET_UID}) # re-glob source files 03054 add_dependencies (_${TARGET_UID} __${TARGET_UID}) 03055 endif () 03056 add_dependencies (${TARGET_UID} _${TARGET_UID}) 03057 # cleanup on "make clean" - including compiled files regardless of COMPILE flag 03058 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${OUTPUT_FILES}) 03059 foreach (OUTPUT_FILE IN LISTS OUTPUT_FILES) 03060 basis_get_compiled_file (CFILE "${OUTPUT_FILE}" ${LANGUAGE}) 03061 if (CFILE) 03062 list (FIND OUTPUT_FILES "${CFILE}" IDX) 03063 if (IDX EQUAL -1) 03064 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CFILE}") 03065 endif () 03066 endif () 03067 endforeach () 03068 # export target 03069 if (EXPORT) 03070 if (TEST) 03071 basis_set_project_property (APPEND PROPERTY TEST_EXPORT_TARGETS "${TARGET_UID}") 03072 else () 03073 basis_set_project_property (APPEND PROPERTY CUSTOM_EXPORT_TARGETS "${TARGET_UID}") 03074 endif () 03075 endif () 03076 # add installation rule 03077 foreach (INSTALL_FILE IN LISTS FILES_TO_INSTALL) 03078 get_filename_component (D "${INSTALL_FILE}" PATH) 03079 file (RELATIVE_PATH D "${BINARY_INSTALL_DIRECTORY}" "${D}") 03080 install ( 03081 FILES "${INSTALL_FILE}" 03082 DESTINATION "${LIBRARY_INSTALL_DIRECTORY}/${D}" 03083 COMPONENT "${LIBRARY_COMPONENT}" 03084 ) 03085 if (LANGUAGE MATCHES "PYTHON" AND INSTALL_FILE MATCHES "\\.pyc$") 03086 basis_compile_python_modules_for_jython (RV) 03087 if (RV) 03088 basis_sanitize_for_regex (LIBRE "${INSTALL_PYTHON_LIBRARY_DIR}") 03089 basis_sanitize_for_regex (SITERE "${INSTALL_PYTHON_SITE_DIR}") 03090 if (LIBRARY_INSTALL_DIRECTORY MATCHES "^${LIBRE}/*$") 03091 set (JYTHON_INSTALL_DIRECTORY "${INSTALL_JYTHON_LIBRARY_DIR}") 03092 elseif (LIBRARY_INSTALL_DIRECTORY MATCHES "^${SITERE}/*$") 03093 set (JYTHON_INSTALL_DIRECTORY "${INSTALL_JYTHON_SITE_DIR}") 03094 else () 03095 set (JYTHON_INSTALL_DIRECTORY "${LIBRARY_INSTALL_DIRECTORY}") 03096 endif () 03097 string (REGEX REPLACE "c$" "" SOURCE_FILE "${INSTALL_FILE}") 03098 basis_get_compiled_file (INSTALL_JYTHON_CFILE "${SOURCE_FILE}" JYTHON) 03099 install ( 03100 FILES "${INSTALL_JYTHON_CFILE}" 03101 DESTINATION "${JYTHON_INSTALL_DIRECTORY}/${D}" 03102 COMPONENT "${LIBRARY_COMPONENT}" 03103 ) 03104 endif () 03105 endif () 03106 endforeach () 03107 # done 03108 if (BASIS_VERBOSE) 03109 message (STATUS "Adding build command for target ${TARGET_UID}... - done") 03110 endif () 03111 endfunction () 03112 03113 # ---------------------------------------------------------------------------- 03114 # @brief Add target to build/install __init__.py files. 03115 function (basis_add_init_py_target) 03116 # constants 03117 set (BUILD_DIR "${PROJECT_BINARY_DIR}/CMakeFiles/_initpy.dir") 03118 basis_sanitize_for_regex (BINARY_PYTHON_LIBRARY_DIR_RE "${BINARY_PYTHON_LIBRARY_DIR}") 03119 basis_sanitize_for_regex (TESTING_PYTHON_LIBRARY_DIR_RE "${TESTING_PYTHON_LIBRARY_DIR}") 03120 basis_sanitize_for_regex (INSTALL_PYTHON_LIBRARY_DIR_RE "${INSTALL_PYTHON_LIBRARY_DIR}") 03121 basis_sanitize_for_regex (BINARY_JYTHON_LIBRARY_DIR_RE "${BINARY_JYTHON_LIBRARY_DIR}") 03122 basis_sanitize_for_regex (TESTING_JYTHON_LIBRARY_DIR_RE "${TESTING_JYTHON_LIBRARY_DIR}") 03123 basis_sanitize_for_regex (INSTALL_JYTHON_LIBRARY_DIR_RE "${INSTALL_JYTHON_LIBRARY_DIR}") 03124 # collect directories requiring a __init__.py file 03125 set (DEPENDENTS) # targets which generate Python/Jython modules and depend on _initpy 03126 set (PYTHON_DIRS) # Python library directories requiring a __init__.py file 03127 set (JYTHON_DIRS) # Jython library directories requiring a __init__.py file 03128 set (EXCLUDE) # exclude these directories 03129 set (INSTALL_EXCLUDE) # exclude these directories upon installation 03130 set (COMPONENTS) # installation components 03131 basis_get_project_property (TARGETS PROPERTY TARGETS) 03132 foreach (TARGET_UID IN LISTS TARGETS) 03133 get_target_property (BASIS_TYPE ${TARGET_UID} BASIS_TYPE) 03134 get_target_property (LANGUAGE ${TARGET_UID} LANGUAGE) 03135 if (BASIS_TYPE MATCHES "MODULE|LIBRARY" AND LANGUAGE MATCHES "^[JP]YTHON$") 03136 # get path of built Python modules 03137 basis_get_target_location (LOCATION ${TARGET_UID} ABSOLUTE) 03138 basis_get_target_location (INSTALL_LOCATION ${TARGET_UID} POST_INSTALL_RELATIVE) 03139 if (BASIS_TYPE MATCHES "^SCRIPT_LIBRARY$") 03140 get_target_property (PREFIX ${TARGET_UID} PREFIX) 03141 get_target_property (SOURCES ${TARGET_UID} SOURCES) 03142 get_target_property (SOURCE_DIRECTORY ${TARGET_UID} SOURCE_DIRECTORY) 03143 string (REGEX REPLACE "/+$" "" PREFIX "${PREFIX}") 03144 if (PREFIX) 03145 set (LOCATION "${LOCATION}/${PREFIX}") 03146 set (INSTALL_LOCATION "${INSTALL_LOCATION}/${PREFIX}") 03147 endif () 03148 list (REMOVE_AT SOURCES 0) # strange, but this is a CMakeFiles/ subdirectory 03149 foreach (SOURCE IN LISTS SOURCES) 03150 file (RELATIVE_PATH SOURCE "${SOURCE_DIRECTORY}" "${SOURCE}") 03151 list (APPEND _LOCATION "${LOCATION}/${SOURCE}") 03152 list (APPEND _INSTALL_LOCATION "${INSTALL_LOCATION}/${SOURCE}") 03153 endforeach () 03154 set (LOCATION "${_LOCATION}") 03155 set (INSTALL_LOCATION "${_INSTALL_LOCATION}") 03156 endif () 03157 # get component (used by installation rule) 03158 get_target_property (COMPONENT ${TARGET_UID} "LIBRARY_COMPONENT") 03159 list (FIND COMPONENTS "${COMPONENT}" IDX) 03160 if (IDX EQUAL -1) 03161 list (APPEND COMPONENTS "${COMPONENT}") 03162 set (INSTALL_${LANGUAGE}_DIRS_${COMPONENT}) # list of directories for which to install 03163 # __init__.py for this component 03164 endif () 03165 # directories for which to build a __init__.py file 03166 foreach (L IN LISTS LOCATION) 03167 basis_get_filename_component (DIR "${L}" PATH) 03168 if (L MATCHES "/__init__.py$") 03169 list (APPEND EXCLUDE "${DIR}") 03170 else () 03171 list (APPEND DEPENDENTS ${TARGET_UID}) # depends on _initpy 03172 if (BINARY_${LANGUAGE}_LIBRARY_DIR_RE AND DIR MATCHES "^${BINARY_${LANGUAGE}_LIBRARY_DIR_RE}/.+") 03173 while (NOT "${DIR}" MATCHES "^${BINARY_${LANGUAGE}_LIBRARY_DIR_RE}$") 03174 list (APPEND ${LANGUAGE}_DIRS "${DIR}") 03175 get_filename_component (DIR "${DIR}" PATH) 03176 endwhile () 03177 elseif (TESTING_${LANGUAGE}_LIBRARY_DIR_RE AND DIR MATCHES "^${TESTING_${LANGUAGE}_LIBRARY_DIR_RE}/.+") 03178 while (NOT "${DIR}" MATCHES "^${TESTING_${LANGUAGE}_LIBRARY_DIR_RE}$") 03179 list (APPEND ${LANGUAGE}_DIRS "${DIR}") 03180 get_filename_component (DIR "${DIR}" PATH) 03181 endwhile () 03182 endif () 03183 endif () 03184 endforeach () 03185 # directories for which to install a __init__.py file 03186 foreach (L IN LISTS INSTALL_LOCATION) 03187 basis_get_filename_component (DIR "${L}" PATH) 03188 if (L MATCHES "/__init__.py$") 03189 list (APPEND INSTALL_EXCLUDE "${DIR}") 03190 else () 03191 list (APPEND DEPENDENTS ${TARGET_UID}) # depends on _initpy 03192 if (INSTALL_${LANGUAGE}_LIBRARY_DIR_RE AND DIR MATCHES "^${INSTALL_${LANGUAGE}_LIBRARY_DIR_RE}/.+") 03193 while (NOT "${DIR}" MATCHES "^${INSTALL_${LANGUAGE}_LIBRARY_DIR_RE}$") 03194 list (APPEND INSTALL_${LANGUAGE}_DIRS_${COMPONENT} "${DIR}") 03195 if (BASIS_COMPILE_SCRIPTS AND LANGUAGE MATCHES "PYTHON") 03196 basis_compile_python_modules_for_jython (RV) 03197 if (RV) 03198 if (INSTALL_JYTHON_LIBRARY_DIR) 03199 file (RELATIVE_PATH REL "${CMAKE_INSTALL_PREFIX}/${INSTALL_PYTHON_LIBRARY_DIR}" "${CMAKE_INSTALL_PREFIX}/${DIR}") 03200 else () 03201 set (REL) 03202 endif () 03203 if (NOT REL MATCHES "^$|^\\.\\./") 03204 list (APPEND INSTALL_JYTHON_DIRS_${COMPONENT} "${INSTALL_JYTHON_LIBRARY_DIR}/${REL}") 03205 endif () 03206 endif () 03207 endif () 03208 get_filename_component (DIR "${DIR}" PATH) 03209 endwhile () 03210 endif () 03211 endif () 03212 endforeach () 03213 endif () 03214 endforeach () 03215 if (DEPENDENTS) 03216 list (REMOVE_DUPLICATES DEPENDENTS) 03217 endif () 03218 # return if nothing to do 03219 if (NOT PYTHON_DIRS AND NOT JYTHON_DIRS) 03220 return () 03221 endif () 03222 if (PYTHON_DIRS) 03223 list (REMOVE_DUPLICATES PYTHON_DIRS) 03224 endif () 03225 if (JYTHON_DIRS) 03226 list (REMOVE_DUPLICATES JYTHON_DIRS) 03227 endif () 03228 if (EXCLUDE) 03229 list (REMOVE_DUPLICATES EXCLUDE) 03230 endif () 03231 if (INSTALL_EXCLUDE) 03232 list (REMOVE_DUPLICATES INSTALL_EXCLUDE) 03233 endif () 03234 # generate build script 03235 set (PYTHON_COMPILED_FILES "${CFILE}") 03236 set (JYTHON_COMPILED_FILES "${CFILE}") 03237 set (C "configure_file (\"${BASIS_PYTHON_TEMPLATES_DIR}/__init__.py.in\" \"${BUILD_DIR}/__init__.py\" @ONLY)\n") 03238 foreach (LANGUAGE IN ITEMS PYTHON JYTHON) # Python *must* come first. See JYTHON_COMPILED_FILES list. 03239 set (${LANGUAGE}_OUTPUT_FILES) 03240 set (${LANGUAGE}_INSTALL_FILE "${BUILD_DIR}/__init__.py") 03241 set (C "${C}\nset (${LANGUAGE}_EXECUTABLE \"${${LANGUAGE}_EXECUTABLE}\")\n\n") 03242 foreach (DIR IN LISTS ${LANGUAGE}_DIRS) 03243 list (FIND EXCLUDE "${DIR}" IDX) 03244 if (IDX EQUAL -1) 03245 set (C "${C}configure_file (\"${BASIS_PYTHON_TEMPLATES_DIR}/__init__.py.in\" \"${DIR}/__init__.py\" @ONLY)\n") 03246 list (APPEND ${LANGUAGE}_OUTPUT_FILES "${DIR}/__init__.py") 03247 endif () 03248 endforeach () 03249 if (BASIS_COMPILE_SCRIPTS AND ${LANGUAGE}_EXECUTABLE) 03250 set (C "${C}\n") 03251 string (TOLOWER "${LANGUAGE}" language) 03252 basis_get_compiled_file (CFILE "${BUILD_DIR}/${language}/__init__.py" ${LANGUAGE}) 03253 set (C "${C}file (MAKE_DIRECTORY \"${BUILD_DIR}/${language}\")\n") 03254 set (C "${C}execute_process (COMMAND \"${${LANGUAGE}_EXECUTABLE}\" -c \"import py_compile; py_compile.compile('${BUILD_DIR}/__init__.py', '${CFILE}')\")\n") 03255 set (${LANGUAGE}_INSTALL_FILE "${CFILE}") 03256 set (C "${C}\n") 03257 foreach (SFILE IN LISTS ${LANGUAGE}_OUTPUT_FILES) 03258 basis_get_compiled_file (CFILE "${SFILE}" ${LANGUAGE}) 03259 set (C "${C}execute_process (COMMAND \"${${LANGUAGE}_EXECUTABLE}\" -c \"import py_compile; py_compile.compile('${SFILE}', '${CFILE}')\")\n") 03260 list (APPEND ${LANGUAGE}_COMPILED_FILES "${CFILE}") 03261 if (LANGUAGE MATCHES "PYTHON") 03262 basis_compile_python_modules_for_jython (RV) 03263 if (RV) 03264 if (BINARY_PYTHON_LIBRARY_DIR AND BINARY_JYTHON_LIBRARY_DIR) 03265 file (RELATIVE_PATH REL "${BINARY_PYTHON_LIBRARY_DIR}" "${SFILE}") 03266 else () 03267 set (REL) 03268 endif () 03269 if (NOT REL MATCHES "^$|^\\.\\./") 03270 basis_get_compiled_file (CFILE "${BINARY_JYTHON_LIBRARY_DIR}/${REL}" JYTHON) 03271 else () 03272 basis_get_compiled_file (CFILE "${SFILE}" JYTHON) 03273 endif () 03274 get_filename_component (CDIR "${CFILE}" PATH) 03275 set (C "${C}file (MAKE_DIRECTORY \"${CDIR}\")\n") 03276 set (C "${C}execute_process (COMMAND \"${JYTHON_EXECUTABLE}\" -c \"import py_compile; py_compile.compile('${SFILE}', '${CFILE}')\")\n") 03277 list (APPEND JYTHON_COMPILED_FILES "${CFILE}") 03278 endif () 03279 endif () 03280 endforeach () 03281 list (APPEND ${LANGUAGE}_OUTPUT_FILES ${${LANGUAGE}_COMPILED_FILES}) 03282 endif () 03283 endforeach () 03284 # write/update build script 03285 set (BUILD_SCRIPT "${BUILD_DIR}/build.cmake") 03286 if (EXISTS "${BUILD_SCRIPT}") 03287 file (WRITE "${BUILD_SCRIPT}.tmp" "${C}") 03288 execute_process ( 03289 COMMAND "${CMAKE_COMMAND}" -E copy_if_different 03290 "${BUILD_SCRIPT}.tmp" "${BUILD_SCRIPT}" 03291 ) 03292 file (REMOVE "${BUILD_SCRIPT}.tmp") 03293 else () 03294 file (WRITE "${BUILD_SCRIPT}" "${C}") 03295 endif () 03296 # add custom build command 03297 add_custom_command ( 03298 OUTPUT "${BUILD_DIR}/__init__.py" ${PYTHON_OUTPUT_FILES} ${JYTHON_OUTPUT_FILES} 03299 COMMAND "${CMAKE_COMMAND}" -P "${BUILD_SCRIPT}" 03300 MAIN_DEPENDENCY "${BASIS_PYTHON_TEMPLATES_DIR}/__init__.py.in" 03301 COMMENT "Building PYTHON modules */__init__.py..." 03302 ) 03303 # add custom target which triggers execution of build script 03304 add_custom_target (_initpy ALL DEPENDS "${BUILD_DIR}/__init__.py" ${PYTHON_OUTPUT_FILES} ${JYTHON_OUTPUT_FILES}) 03305 if (BASIS_DEBUG) 03306 message ("** basis_add_init_py_target():") 03307 endif () 03308 foreach (DEPENDENT IN LISTS DEPENDENTS) 03309 if (BASIS_DEBUG) 03310 message ("** Adding dependency on _initpy target to ${DEPENDENT}") 03311 endif () 03312 add_dependencies (${DEPENDENT} _initpy) 03313 endforeach () 03314 # cleanup on "make clean" - including compiled modules regardless of COMPILE flag 03315 set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${BUILD_DIR}/__init__.py" ${PYTHON_OUTPUT_FILES} ${JYTHON_OUTPUT_FILES}) 03316 # add install rules 03317 foreach (LANGUAGE IN ITEMS PYTHON JYTHON) 03318 foreach (COMPONENT IN LISTS COMPONENTS) 03319 if (INSTALL_${LANGUAGE}_DIRS_${COMPONENT}) 03320 list (REMOVE_DUPLICATES INSTALL_${LANGUAGE}_DIRS_${COMPONENT}) 03321 endif () 03322 foreach (DIR IN LISTS INSTALL_${LANGUAGE}_DIRS_${COMPONENT}) 03323 list (FIND INSTALL_EXCLUDE "${DIR}" IDX) 03324 if (IDX EQUAL -1) 03325 install ( 03326 FILES "${${LANGUAGE}_INSTALL_FILE}" 03327 DESTINATION "${DIR}" 03328 COMPONENT "${COMPONENT}" 03329 ) 03330 endif () 03331 endforeach () 03332 endforeach () 03333 endforeach () 03334 endfunction () 03335 03336 03337 ## @} 03338 # end of Doxygen group