BASIS  version 1.2.3 (revision 2104)
DocTools.cmake
Go to the documentation of this file.
00001 ##############################################################################
00002 # @file  DocTools.cmake
00003 # @brief Tools related to gnerating or adding software documentation.
00004 #
00005 # Copyright (c) 2011, 2012 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_DOCTOOLS_INCLUDED)
00014   return ()
00015 else ()
00016   set (__BASIS_DOCTOOLS_INCLUDED TRUE)
00017 endif ()
00018 
00019 
00020 # ============================================================================
00021 # used programs
00022 # ============================================================================
00023 
00024 # Doxygen - used by basis_add_doc()
00025 find_package (Doxygen)
00026 
00027 ## @brief Command svn2cl which is used to generate a ChangeLog from the Subversion log.
00028 find_program (
00029   SVN2CL_EXECUTABLE
00030     NAMES svn2cl svn2cl.sh
00031     DOC   "The command line tool svn2cl."
00032 )
00033 mark_as_advanced (SVN2CL_EXECUTABLE)
00034 
00035 # ============================================================================
00036 # settings
00037 # ============================================================================
00038 
00039 ## @addtogroup CMakeUtilities
00040 #  @{
00041 
00042 
00043 ## @brief Default Doxygen configuration.
00044 set (BASIS_DOXYGEN_DOXYFILE "${CMAKE_CURRENT_LIST_DIR}/Doxyfile.in")
00045 
00046 
00047 ## @}
00048 # end of Doxygen group
00049 
00050 
00051 # ============================================================================
00052 # helper
00053 # ============================================================================
00054 
00055 ## @addtogroup CMakeUtilities
00056 #  @{
00057 
00058 
00059 # ----------------------------------------------------------------------------
00060 ## @brief Get default Doxygen filter patterns.
00061 #
00062 # @param [out] FILTER_PATTERNS List of default Doxygen filter patterns.
00063 function (basis_default_doxygen_filters FILTER_PATTERNS)
00064   set (PATTERNS)
00065 
00066   macro (register_filter FILTER)
00067     basis_get_target_uid (TARGET_UID "${BASIS_NAMESPACE_LOWER}.${FILTER}")
00068     if (TARGET "${TARGET_UID}")
00069       basis_get_target_location (FILTER_PATH "${TARGET_UID}" ABSOLUTE)
00070       foreach (ARG ${ARGN})
00071         list (APPEND PATTERNS "${ARG}=${FILTER_PATH}")
00072       endforeach ()
00073     elseif (BASIS_VERBOSE)
00074       message (WARNING "Doxygen filter ${FILTER} not available.")
00075     endif ()
00076   endmacro ()
00077 
00078   register_filter (
00079     basis.doxyfilter-cmake
00080       "CMakeLists.txt"
00081       "*.cmake"
00082       "*.cmake.in"
00083       "*.ctest"
00084       "*.ctest.in"
00085   )
00086 
00087   register_filter (
00088     basis.doxyfilter-bash
00089       "*.sh"
00090       "*.sh.in"
00091   )
00092 
00093   register_filter (
00094     basis.doxyfilter-matlab
00095       "*.m"
00096       "*.m.in"
00097   )
00098 
00099   # TODO Python filer disabled because it does not work properly
00100 #  register_filter (
00101 #    basis.doxyfilter-python
00102 #      "*.py"
00103 #      "*.py.in"
00104 #  )
00105 
00106   # return
00107   set ("${FILTER_PATTERNS}" "${PATTERNS}" PARENT_SCOPE)
00108 endfunction ()
00109 
00110 
00111 ## @}
00112 # end of Doxygen group
00113 
00114 
00115 # ============================================================================
00116 # adding / generating documentation
00117 # ============================================================================
00118 
00119 # ----------------------------------------------------------------------------
00120 ## @brief Add documentation target.
00121 #
00122 # This function is especially used to add a custom target to the "doc" target
00123 # which is used to generate documentation from input files such as in
00124 # particular source code files. Other documentation files such as HTML, Word,
00125 # or PDF documents can be added as well using this function. A component
00126 # as part of which this documentation shall be installed can be specified.
00127 #
00128 # @param [in] TARGET_NAME Name of the documentation target or file.
00129 # @param [in] ARGN        List of arguments. The valid arguments are:
00130 # @par
00131 # <table border="0">
00132 #   <tr>
00133 #     @tp @b COMPONENT component @endtp
00134 #     <td>Name of the component this documentation belongs to.
00135 #         Defaults to @c BASIS_LIBRARY_COMPONENT for documentation generated
00136 #         from in-source comments and @c BASIS_RUNTIME_COMPONENT, otherwise.</td>
00137 #   </tr>
00138 #   <tr>
00139 #     @tp @b GENERATOR generator @endtp
00140 #     <td>Documentation generator, where the case of the generator name is
00141 #         ignored, i.e., @c Doxygen, @c DOXYGEN, @c doxYgen are all valid
00142 #         arguments which select the @c Doxygen generator. The parameters for the
00143 #         different supported generators are documented below.
00144 #         The default generator is @c None. The @c None generator simply installs
00145 #         the document with the filename @c TARGET_NAME and has no own options.</td>
00146 #   </tr>
00147 #   <tr>
00148 #     @tp @b DESTINATION dir @endtp
00149 #     <td>Installation directory prefix. Defaults to @c INSTALL_DOC_DIR or
00150 #         <tt>INSTALL_DOC_DIR/&lt;target&gt;</tt> in case of the Doxygen generator,
00151 #         where <tt>&lt;target&gt;</tt> is the @c TARGET_NAME in lowercase only.</td>
00152 #   </tr>
00153 # </table>
00154 #
00155 # @par Generator: None
00156 # @n
00157 # The documentation files are installed in/as <tt>INSTALL_DOC_DIR/TARGET_NAME</tt>
00158 # as part of the component specified by the @c COMPONENT option.
00159 # @n@n
00160 # <table border="0">
00161 #   <tr>
00162 #     @tp @b OUTPUT_NAME filename @endtp
00163 #     <td>Name of installed documentationf file. Default: @p TARGET_NAME.</td>
00164 #   </tr>
00165 # </table>
00166 # @n
00167 # Example:
00168 # @code
00169 # basis_add_doc ("User Manual.pdf" OUTPUT_NAME "BASIS User Manual.pdf")
00170 # basis_add_doc (DeveloperManual.docx COMPONENT dev)
00171 # basis_add_doc (SourceManual.html    COMPONENT src)
00172 # @endcode
00173 #
00174 # @par Generator: Doxygen
00175 # @n
00176 # Uses the <a href="http://www.stack.nl/~dimitri/doxygen/index.html">Doxygen</a> tool
00177 # to generate the documentation from in-source code comments.
00178 # @n@n
00179 # <table border="0">
00180 #   <tr>
00181 #     @tp @b DOXYFILE file @endtp
00182 #     <td>Name of the template Doxyfile.</td>
00183 #   </tr>
00184 #   <tr>
00185 #     @tp @b PROJECT_NAME name @endtp
00186 #     <td>Value for Doxygen's @c PROJECT_NAME tag which is used to
00187 #         specify the project name.@n
00188 #         Default: @c PROJECT_NAME.</td>
00189 #   </tr>
00190 #   <tr>
00191 #     @tp @b PROJECT_NUMBER version @endtp
00192 #     <td>Value for Doxygen's @c PROJECT_NUMBER tag which is used
00193 #         to specify the project version number.@n
00194 #         Default: @c PROJECT_VERSION_AND_REVISION.</td>
00195 #   </tr>
00196 #   <tr>
00197 #     @tp @b INPUT path1 [path2 ...] @endtp
00198 #     <td>Value for Doxygen's @c INPUT tag which is used to specify input
00199 #         directories/files. Any given input path is added to the default
00200 #         input paths.@n
00201 #         Default: @c PROJECT_CODE_DIR, @c BINARY_CODE_DIR,
00202 #                  @c PROJECT_INCLUDE_DIR, @c BINARY_INCLUDE_DIR.</td>
00203 #   </tr>
00204 #   <tr>
00205 #     @tp @b INPUT_FILTER filter @endtp
00206 #     <td>
00207 #       Value for Doxygen's @c INPUT_FILTER tag which can be used to
00208 #       specify a default filter for all input files. Set to either one of
00209 #       @c None, @c NONE, or @c none to use no input filter.@n
00210 #       Default: @c doxyfilter of BASIS.
00211 #     </td>
00212 #   <tr>
00213 #     @tp @b FILTER_PATTERNS pattern1 [pattern2...] @endtp
00214 #     <td>Value for Doxygen's @c FILTER_PATTERNS tag which can be used to
00215 #         specify filters on a per file pattern basis.@n
00216 #         Default: BASIS Doxygen filter patterns.</td>
00217 #   </tr>
00218 #   <tr>
00219 #     @tp @b INCLUDE_PATH path1 [path2...] @endtp
00220 #     <td>Doxygen's @c INCLUDE_PATH tag can be used to specify one or more
00221 #         directories that contain include files that are not input files
00222 #         but should be processed by the preprocessor. Any given directories
00223 #         are appended to the default include path considered.
00224 #         Default: Directories added by basis_include_directories().</td>
00225 #   </tr>
00226 #   <tr>
00227 #     @tp @b EXCLUDE_PATTERNS pattern1 [pattern2 ...] @endtp
00228 #     <td>Additional patterns used for Doxygen's @c EXCLUDE_PATTERNS tag
00229 #         which can be used to specify files and/or directories that
00230 #         should be excluded from the INPUT source files.@n
00231 #         Default: No exclude patterns.</td>
00232 #   </tr>
00233 #   <tr>
00234 #     @tp @b OUTPUT_DIRECTORY dir @endtp
00235 #     <td>Value for Doxygen's @c OUTPUT_DIRECTORY tag which can be used to
00236 #         specify the output directory. The output files are written to
00237 #         subdirectories named "html", "latex", "rtf", and "man".@n
00238 #         Default: <tt>CMAKE_CURRENT_BINARY_DIR/TARGET_NAME</tt>.</td>
00239 #   </tr>
00240 #   <tr>
00241 #     @tp @b COLS_IN_ALPHA_INDEX n @endtp
00242 #     <td>Number of columns in alphabetical index if @p GENERATE_HTML is @c YES.
00243 #         Default: 3.</td>
00244 #   </tr>
00245 #   <tr>
00246 #     @tp @b GENERATE_HTML @endtp
00247 #     <td>If given, Doxygen's @c GENERATE_HTML tag is set to YES, otherwise NO.</td>
00248 #   </tr>
00249 #   <tr>
00250 #     @tp @b GENERATE_LATEX @endtp
00251 #     <td>If given, Doxygen's @c GENERATE_LATEX tag is set to YES, otherwise NO.</td>
00252 #   </tr>
00253 #   <tr>
00254 #     @tp @b GENERATE_RTF @endtp
00255 #     <td>If given, Doxygen's @c GENERATE_RTF tag is set to YES, otherwise NO.</td>
00256 #   </tr>
00257 #   <tr>
00258 #     @tp @b GENERATE_MAN @endtp
00259 #     <td>If given, Doxygen's @c GENERATE_MAN tag is set to YES, otherwise NO.</td>
00260 #   </tr>
00261 # </table>
00262 # @n
00263 # See <a href="http://www.stack.nl/~dimitri/doxygen/config.html">here</a> for a
00264 # documentation of the Doxygen tags. If none of the <tt>GENERATE_&lt;*&gt;</tt>
00265 # options is given, @c GENERATE_HTML is set to @c YES.
00266 # @n@n
00267 # Example:
00268 # @code
00269 # basis_add_doc (
00270 #   api
00271 #   GENERATOR Doxygen
00272 #     DOXYFILE        "Doxyfile.in"
00273 #     PROJECT_NAME    "${PROJECT_NAME}"
00274 #     PROJECT_VERSION "${PROJECT_VERSION}"
00275 #   COMPONENT dev
00276 # )
00277 # @endcode
00278 #
00279 # @returns Adds a custom target @p TARGET_NAME for the generation of the
00280 #          documentation or configures the given file in case of the @c None
00281 #          generator.
00282 #
00283 # @ingroup CMakeAPI
00284 function (basis_add_doc TARGET_NAME)
00285   # parse arguments
00286   CMAKE_PARSE_ARGUMENTS (ARGN "" "GENERATOR;COMPONENT;DESTINATION" "" ${ARGN})
00287 
00288   # default generator
00289   if (NOT ARGN_GENERATOR)
00290     set (ARGN_GENERATOR "NONE")
00291   else ()
00292     # generator name is case insensitive
00293     string (TOUPPER "${ARGN_GENERATOR}" ARGN_GENERATOR)
00294   endif ()
00295 
00296   # check target name
00297   if (NOT ARGN_GENERATOR MATCHES "NONE")
00298     basis_check_target_name ("${TARGET_NAME}")
00299     basis_make_target_uid (TARGET_UID "${TARGET_NAME}")
00300   endif ()
00301 
00302   # lower target name is used, for example, for default DESTINATION
00303   string (TOLOWER "${TARGET_NAME}" TARGET_NAME_LOWER)
00304 
00305   # default destination
00306   if (NOT ARGN_DESTINATION)
00307     if (ARGN_GENERATOR MATCHES "DOXYGEN")
00308       if (NOT INSTALL_APIDOC_DIR)
00309         set (
00310           INSTALL_APIDOC_DIR "${INSTALL_DOC_DIR}/${TARGET_NAME_LOWER}"
00311           CACHE PATH
00312             "Installation directory of API documentation."
00313         )
00314         mark_as_advanced (INSTALL_APIDOC_DIR)
00315       endif ()
00316       set (ARGN_DESTINATION "${INSTALL_APIDOC_DIR}")
00317     else ()
00318       set (ARGN_DESTINATION "${INSTALL_DOC_DIR}")
00319     endif ()
00320   endif ()
00321 
00322   # default component
00323   if (ARGN_GENERATOR MATCHES "DOXYGEN")
00324     if (NOT ARGN_COMPONENT)
00325       set (ARGN_COMPONENT "${BASIS_LIBRARY_COMPONENT}")
00326     endif ()
00327   else ()
00328     if (NOT ARGN_COMPONENT)
00329       set (ARGN_COMPONENT "${BASIS_RUNTIME_COMPONENT}")
00330     endif ()
00331   endif ()
00332   if (NOT ARGN_COMPONENT)
00333     set (ARGN_COMPONENT "Unspecified")
00334   endif ()
00335 
00336   # --------------------------------------------------------------------------
00337   # generator: NONE
00338   # --------------------------------------------------------------------------
00339 
00340   if (ARGN_GENERATOR MATCHES "NONE")
00341 
00342     CMAKE_PARSE_ARGUMENTS (DOC "" "OUTPUT_NAME" "" ${ARGN_UNPARSED_ARGUMENTS})
00343 
00344     if (NOT DOC_OUTPUT_NAME)
00345       set (DOC_OUTPUT_NAME "${TARGET_NAME}")
00346     endif ()
00347 
00348     basis_get_relative_path (
00349       DOC_PATH
00350         "${CMAKE_SOURCE_DIR}"
00351         "${CMAKE_CURRENT_SOURCE_DIR}/${DOC_OUTPUT_NAME}"
00352     )
00353 
00354     if (BASIS_VERBOSE)
00355       message (STATUS "Adding documentation ${DOC_PATH}...")
00356     endif ()
00357 
00358     # install documentation directory
00359     if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}")
00360       install (
00361         DIRECTORY   "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}/"
00362         DESTINATION "${ARGN_DESTINATION}/${DOC_OUTPUT_NAME}"
00363         COMPONENT   "${ARGN_COMPONENT}"
00364         PATTERN     ".svn" EXCLUDE
00365         PATTERN     ".git" EXCLUDE
00366         PATTERN     "*~"   EXCLUDE
00367       )
00368     # install documentation file
00369     else ()
00370       install (
00371         FILES       "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}"
00372         DESTINATION "${ARGN_DESTINATION}"
00373         COMPONENT   "${ARGN_COMPONENT}"
00374         RENAME      "${DOC_OUTPUT_NAME}"
00375       )
00376     endif ()
00377 
00378     if (BASIS_VERBOSE)
00379       message (STATUS "Adding documentation ${DOC_PATH}... - done")
00380     endif ()
00381 
00382   # --------------------------------------------------------------------------
00383   # generator: DOXYGEN
00384   # --------------------------------------------------------------------------
00385 
00386   elseif (ARGN_GENERATOR MATCHES "DOXYGEN")
00387 
00388     if (BASIS_VERBOSE)
00389       message (STATUS "Adding documentation ${TARGET_UID}...")
00390     endif ()
00391 
00392     # Doxygen found ?
00393     if (BUILD_DOCUMENTATION)
00394       set (ERRMSGTYP "")
00395       set (ERRMSG    "failed")
00396     else ()
00397       set (ERRMSGTYP "STATUS")
00398       set (ERRMSG    "skipped")
00399     endif ()
00400 
00401     if (NOT DOXYGEN_EXECUTABLE)
00402       message (${ERRMSGTYP} "Doxygen not found. Generation of ${TARGET_UID} documentation disabled.")
00403       if (BASIS_VERBOSE)
00404         message (STATUS "Adding documentation ${TARGET_UID}... - ${ERRMSG}")
00405       endif ()
00406       return ()
00407     endif ()
00408 
00409     # parse arguments
00410     CMAKE_PARSE_ARGUMENTS (
00411       DOXYGEN
00412         "GENERATE_HTML;GENERATE_LATEX;GENERATE_RTF;GENERATE_MAN"
00413         "DOXYFILE;TAGFILE;PROJECT_NAME;PROJECT_NUMBER;OUTPUT_DIRECTORY;COLS_IN_ALPHA_INDEX"
00414         "INPUT;INPUT_FILTER;FILTER_PATTERNS;EXCLUDE_PATTERNS;INCLUDE_PATH"
00415         ${ARGN_UNPARSED_ARGUMENTS}
00416     )
00417 
00418     if (NOT DOXYGEN_DOXYFILE)
00419       set (DOXYGEN_DOXYFILE "${BASIS_DOXYGEN_DOXYFILE}")
00420     endif ()
00421     if (NOT EXISTS "${DOXYGEN_DOXYFILE}")
00422       message (FATAL_ERROR "Missing option DOXYGEN_FILE or Doxyfile ${DOXYGEN_DOXYFILE} does not exist.")
00423     endif ()
00424 
00425     if (NOT DOXYGEN_PROJECT_NAME)
00426       set (DOXYGEN_PROJECT_NAME "${PROJECT_NAME}")
00427     endif ()
00428     if (NOT DOXYGEN_PROJECT_NUMBER)
00429       set (DOXYGEN_PROJECT_NUMBER "${PROJECT_VERSION_AND_REVISION}")
00430     endif ()
00431     # standard input files
00432     list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/BasisProject.cmake")
00433     if (EXISTS "${PROJECT_CONFIG_DIR}/Depends.cmake")
00434       list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Depends.cmake")
00435     endif ()
00436     if (EXISTS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Directories.cmake")
00437       list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Directories.cmake")
00438     endif ()
00439     if (EXISTS "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
00440       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
00441     endif ()
00442     if (EXISTS "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
00443       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
00444     endif ()
00445     if (EXISTS "${BINARY_CONFIG_DIR}/Settings.cmake")
00446       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/Settings.cmake")
00447     elseif (EXISTS "${PROJECT_CONFIG_DIR}/Settings.cmake")
00448       list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Settings.cmake")
00449     endif ()
00450     if (EXISTS "${BINARY_CONFIG_DIR}/BasisScriptConfig.cmake")
00451       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/BasisScriptConfig.cmake")
00452     endif ()
00453     if (EXISTS "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
00454       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
00455     endif ()
00456     if (EXISTS "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
00457       list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
00458     endif ()
00459     if (EXISTS "${BINARY_CONFIG_DIR}/${PROJECT_NAME}Config.cmake")
00460       list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/${PROJECT_NAME}Config.cmake")
00461     endif ()
00462     if (EXISTS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
00463       list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
00464     endif ()
00465     if (EXISTS "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Use.cmake")
00466       list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Use.cmake")
00467     endif ()
00468     if (EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
00469       list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
00470     endif ()
00471     if (EXISTS "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
00472       list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
00473     endif ()
00474     # input directories
00475     if (NOT BASIS_AUTO_PREFIX_INCLUDES AND EXISTS "${PROJECT_INCLUDE_DIR}")
00476       list (APPEND DOXYGEN_INPUT "${PROJECT_INCLUDE_DIR}")
00477     endif ()
00478     if (EXISTS "${BINARY_INCLUDE_DIR}")
00479       list (APPEND DOXYGEN_INPUT "${BINARY_INCLUDE_DIR}")
00480     endif ()
00481     if (EXISTS "${BINARY_CODE_DIR}")
00482       list (APPEND DOXYGEN_INPUT "${BINARY_CODE_DIR}")
00483     endif ()
00484     if (EXISTS "${PROJECT_CODE_DIR}")
00485       list (APPEND DOXYGEN_INPUT "${PROJECT_CODE_DIR}")
00486     endif ()
00487     basis_get_relative_path (INCLUDE_DIR "${PROJECT_SOURCE_DIR}" "${PROJECT_INCLUDE_DIR}")
00488     basis_get_relative_path (CODE_DIR    "${PROJECT_SOURCE_DIR}" "${PROJECT_CODE_DIR}")
00489     foreach (M IN LISTS PROJECT_MODULES_ENABLED)
00490       if (EXISTS "${PROJECT_MODULES_DIR}/${M}/${CODE_DIR}")
00491         list (APPEND DOXYGEN_INPUT "${PROJECT_MODULES_DIR}/${M}/${CODE_DIR}")
00492       endif ()
00493       if (EXISTS "${PROJECT_MODULES_DIR}/${M}/${INCLUDE_DIR}")
00494         list (APPEND DOXYGEN_INPUT "${BINARY_MODULES_DIR}/${M}/${INCLUDE_DIR}")
00495       endif ()
00496     endforeach ()
00497     # add .dox files as input
00498     file (GLOB_RECURSE DOX_FILES "${PROJECT_DOC_DIR}/*.dox")
00499     list (SORT DOX_FILES) # alphabetic order
00500     list (APPEND DOXYGEN_INPUT ${DOX_FILES})
00501     # add .dox files of BASIS modules
00502     if (PROJECT_NAME MATCHES "^BASIS$")
00503       set (FilesystemHierarchyStandardPageRef "@ref FilesystemHierarchyStandard")
00504       set (BuildOfScriptTargetsPageRef        "@ref BuildOfScriptTargets")
00505     else ()
00506       set (FilesystemHierarchyStandardPageRef "Filesystem Hierarchy Standard")
00507       set (BuildOfScriptTargetsPageRef        "build of script targets")
00508     endif ()
00509     configure_file(
00510       "${BASIS_MODULE_PATH}/Modules.dox.in"
00511       "${CMAKE_CURRENT_BINARY_DIR}/BasisModules.dox" @ONLY)
00512     list (APPEND DOXYGEN_INPUT "${CMAKE_CURRENT_BINARY_DIR}/BasisModules.dox")
00513     # add .dox files of used BASIS utilities
00514     list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
00515     list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/CxxUtilities.dox")
00516     foreach (L IN ITEMS Cxx Java Python Perl Bash Matlab)
00517       string (TOUPPER "${L}" U)
00518       if (U MATCHES "CXX")
00519         if (BASIS_UTILITIES_ENABLED MATCHES "CXX")
00520           set (PROJECT_USES_CXX_UTILITIES TRUE)
00521         else ()
00522           set (PROJECT_USES_CXX_UTILITIES FALSE)
00523         endif ()
00524       else ()
00525         basis_get_project_property (USES_${U}_UTILITIES PROPERTY PROJECT_USES_${U}_UTILITIES)
00526       endif ()
00527       if (USES_${U}_UTILITIES)
00528         list (FIND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox" IDX)
00529         if (IDX EQUAL -1)
00530           list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
00531         endif ()
00532         list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/${L}Utilities.dox")
00533       endif ()
00534     endforeach ()
00535     # include path
00536     basis_get_project_property (INCLUDE_DIRS PROPERTY PROJECT_INCLUDE_DIRS)
00537     foreach (D IN LISTS INCLUDE_DIRS)
00538       list (FIND DOXYGEN_INPUT "${D}" IDX)
00539       if (IDX EQUAL -1)
00540         list (APPEND DOXYGEN_INCLUDE_PATH "${D}")
00541       endif ()
00542     endforeach ()
00543     basis_list_to_delimited_string (
00544       DOXYGEN_INCLUDE_PATH "\"\nINCLUDE_PATH          += \"" ${DOXYGEN_INCLUDE_PATH}
00545     )
00546     set (DOXYGEN_INCLUDE_PATH "\"${DOXYGEN_INCLUDE_PATH}\"")
00547     # make string from DOXYGEN_INPUT - after include path was set
00548     basis_list_to_delimited_string (
00549       DOXYGEN_INPUT "\"\nINPUT                 += \"" ${DOXYGEN_INPUT}
00550     )
00551     set (DOXYGEN_INPUT "\"${DOXYGEN_INPUT}\"")
00552     # input filters
00553     if (NOT DOXYGEN_INPUT_FILTER)
00554       basis_get_target_uid (DOXYFILTER "${BASIS_NAMESPACE_LOWER}.basis.doxyfilter")
00555       if (TARGET "${DOXYFILTER}")
00556         basis_get_target_location (DOXYGEN_INPUT_FILTER "${DOXYFILTER}" ABSOLUTE)
00557       endif ()
00558     endif ()
00559     if (DOXYGEN_INPUT_FILTER MATCHES "^(None|NONE|none)$")
00560       set (DOXYGEN_INPUT_FILTER)
00561     endif ()
00562     if (NOT DOXYGEN_FILTER_PATTERNS)
00563       basis_default_doxygen_filters (DOXYGEN_FILTER_PATTERNS)
00564     endif ()
00565     basis_list_to_delimited_string (
00566       DOXYGEN_FILTER_PATTERNS "\"\nFILTER_PATTERNS       += \"" ${DOXYGEN_FILTER_PATTERNS}
00567     )
00568     set (DOXYGEN_FILTER_PATTERNS "\"${DOXYGEN_FILTER_PATTERNS}\"")
00569     # exclude patterns
00570     list (APPEND DOXYGEN_EXCLUDE_PATTERNS "cmake_install.cmake")
00571     list (APPEND DOXYGEN_EXCLUDE_PATTERNS "CTestTestfile.cmake")
00572     basis_list_to_delimited_string (
00573       DOXYGEN_EXCLUDE_PATTERNS "\"\nEXCLUDE_PATTERNS      += \"" ${DOXYGEN_EXCLUDE_PATTERNS}
00574     )
00575     set (DOXYGEN_EXCLUDE_PATTERNS "\"${DOXYGEN_EXCLUDE_PATTERNS}\"")
00576     # outputs
00577     if (NOT DOXYGEN_OUTPUT_DIRECTORY)
00578       set (DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME_LOWER}")
00579     endif ()
00580     if (DOXYGEN_TAGFILE MATCHES "^(None|NONE|none)$")
00581       set (DOXYGEN_TAGFILE)
00582     else ()
00583       set (DOXYGEN_TAGFILE "${DOXYGEN_OUTPUT_DIRECTORY}/doxygen.tags")
00584     endif ()
00585     set (NUMBER_OF_OUTPUTS 0)
00586     foreach (FMT HTML LATEX RTF MAN)
00587       set (VAR DOXYGEN_GENERATE_${FMT})
00588       if (${VAR})
00589         set (${VAR} "YES")
00590         math (EXPR NUMBER_OF_OUTPUTS "${NUMBER_OF_OUTPUTS} + 1")
00591       else ()
00592         set (${VAR} "NO")
00593       endif ()
00594     endforeach ()
00595     if (NUMBER_OF_OUTPUTS EQUAL 0)
00596       set (DOXYGEN_GENERATE_HTML "YES")
00597       set (NUMBER_OF_OUTPUTS 1)
00598     endif ()
00599     # other settings
00600     if (NOT DOXYGEN_COLS_IN_ALPHA_INDEX OR DOXYGEN_COLS_IN_ALPHA_INDEX MATCHES "[^0-9]")
00601       set (DOXYGEN_COLS_IN_ALPHA_INDEX 3)
00602     endif ()
00603     # HTML style
00604     set (DOXYGEN_HTML_STYLESHEET "${BASIS_MODULE_PATH}/doxygen_sbia.css")
00605     set (DOXYGEN_HTML_HEADER     "${BASIS_MODULE_PATH}/doxygen_header.html")
00606     set (DOXYGEN_HTML_FOOTER     "${BASIS_MODULE_PATH}/doxygen_footer.html")
00607 
00608     # set output paths relative to DOXYGEN_OUTPUT_DIRECTORY
00609     set (DOXYGEN_HTML_OUTPUT  "html")
00610     set (DOXYGEN_LATEX_OUTPUT "latex")
00611     set (DOXYGEN_RTF_OUTPUT   "rtf")
00612     set (DOXYGEN_MAN_OUTPUT   "man")
00613 
00614     # click & jump in emacs and Visual Studio
00615     if (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
00616       set (DOXYGEN_WARN_FORMAT "\"$file($line) : $text \"")
00617     else ()
00618       set (DOXYGEN_WARN_FORMAT "\"$file:$line: $text \"")
00619     endif ()
00620 
00621     # configure Doxyfile
00622     set (DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME_LOWER}.doxy")
00623     configure_file ("${DOXYGEN_DOXYFILE}" "${DOXYFILE}" @ONLY)
00624 
00625     # add target
00626     set (LOGOS)
00627     if (DOXYGEN_HTML_OUTPUT)
00628       set (LOGOS "${DOXYGEN_OUTPUT_DIRECTORY}/html/logo_sbia.png"
00629                  "${DOXYGEN_OUTPUT_DIRECTORY}/html/logo_penn.png")
00630       add_custom_command (
00631         OUTPUT   ${LOGOS}
00632         COMMAND "${CMAKE_COMMAND}" -E copy
00633                   "${BASIS_MODULE_PATH}/logo_sbia.png"
00634                   "${DOXYGEN_OUTPUT_DIRECTORY}/html/logo_sbia.png"
00635         COMMAND "${CMAKE_COMMAND}" -E copy
00636                   "${BASIS_MODULE_PATH}/logo_penn.gif"
00637                   "${DOXYGEN_OUTPUT_DIRECTORY}/html/logo_penn.gif"
00638         COMMENT "Copying logos to ${DOXYGEN_OUTPUT_DIRECTORY}/html/..."
00639       )
00640     endif ()
00641 
00642     add_custom_target (
00643       ${TARGET_UID} "${DOXYGEN_EXECUTABLE}" "${DOXYFILE}"
00644       DEPENDS ${LOGOS}
00645       WORKING_DIRECTORY "${BASIS_MODULE_DIR}"
00646       COMMENT "Building documentation ${TARGET_UID}..."
00647     )
00648 
00649     # cleanup on "make clean"
00650     set_property (
00651       DIRECTORY
00652       APPEND PROPERTY
00653         ADDITIONAL_MAKE_CLEAN_FILES
00654           "${DOXYGEN_OUTPUT_DIRECTORY}/html"
00655           "${DOXYGEN_OUTPUT_DIRECTORY}/latex"
00656           "${DOXYGEN_OUTPUT_DIRECTORY}/rtf"
00657           "${DOXYGEN_OUTPUT_DIRECTORY}/man"
00658     )
00659 
00660     # clean up / install tags file
00661     if (DOXYGEN_TAGFILE)
00662       set_property (
00663         DIRECTORY
00664         APPEND PROPERTY
00665           ADDITIONAL_MAKE_CLEAN_FILES
00666             "${DOXYGEN_TAGFILE}"
00667       )
00668     endif ()
00669 
00670     # add target as dependency to doc target
00671     if (NOT TARGET doc)
00672       if (BUILD_DOCUMENTATION)
00673         add_custom_target (doc ALL)
00674       else ()
00675         add_custom_target (doc)
00676       endif ()
00677     endif ()
00678 
00679     add_dependencies (doc ${TARGET_UID})
00680     if (TARGET headers)
00681       add_dependencies (${TARGET_UID} headers)
00682     endif ()
00683     if (TARGET scripts)
00684       add_dependencies (${TARGET_UID} scripts)
00685     endif ()
00686 
00687     # install documentation
00688     install (
00689       CODE
00690         "
00691         set (INSTALL_PREFIX \"${ARGN_DESTINATION}\")
00692         if (NOT IS_ABSOLUTE \"\${INSTALL_PREFIX}\")
00693           set (INSTALL_PREFIX \"${INSTALL_PREFIX}/\${INSTALL_PREFIX}\")
00694         endif ()
00695 
00696         macro (install_doxydoc DIR)
00697           file (
00698             GLOB_RECURSE
00699               FILES
00700             RELATIVE \"${DOXYGEN_OUTPUT_DIRECTORY}\"
00701               \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/*\"
00702           )
00703           foreach (F IN LISTS FILES)
00704             execute_process (
00705               COMMAND \"${CMAKE_COMMAND}\" -E compare_files
00706                   \"${DOXYGEN_OUTPUT_DIRECTORY}/\${F}\"
00707                   \"\${INSTALL_PREFIX}/\${F}\"
00708               RESULT_VARIABLE RC
00709               OUTPUT_QUIET
00710               ERROR_QUIET
00711             )
00712             if (RC EQUAL 0)
00713               message (STATUS \"Up-to-date: \${INSTALL_PREFIX}/\${F}\")
00714             else ()
00715               message (STATUS \"Installing: \${INSTALL_PREFIX}/\${F}\")
00716               execute_process (
00717                 COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
00718                     \"${DOXYGEN_OUTPUT_DIRECTORY}/\${F}\"
00719                     \"\${INSTALL_PREFIX}/\${F}\"
00720                 RESULT_VARIABLE RC
00721                 OUTPUT_QUIET
00722                 ERROR_QUIET
00723               )
00724               if (RC EQUAL 0)
00725                 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${INSTALL_PREFIX}/\${F}\")
00726               else ()
00727                 message (STATUS \"Failed to install \${INSTALL_PREFIX}/\${F}\")
00728               endif ()
00729             endif ()
00730           endforeach ()
00731         endmacro ()
00732 
00733         install_doxydoc (html)
00734         install_doxydoc (latex)
00735         install_doxydoc (rtf)
00736         install_doxydoc (man)
00737 
00738         if (EXISTS \"${DOXYGEN_TAGFILE}\")
00739           get_filename_component (DOXYGEN_TAGFILE_NAME \"${DOXYGEN_TAGFILE}\" NAME)
00740           execute_process (
00741             COMMAND \"${CMAKE_COMMAND}\" -E copy
00742               \"${DOXYGEN_TAGFILE}\"
00743               \"\${INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\"
00744           )
00745           list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\")
00746         endif ()
00747         "
00748     )
00749 
00750     if (BASIS_VERBOSE)
00751       message (STATUS "Adding documentation ${TARGET_UID}... - done")
00752     endif ()
00753 
00754   # --------------------------------------------------------------------------
00755   # generator: unknown
00756   # --------------------------------------------------------------------------
00757 
00758   else ()
00759     message (FATAL_ERROR "Unknown documentation generator: ${ARGN_GENERATOR}.")
00760   endif ()
00761 endfunction ()
00762 
00763 # ----------------------------------------------------------------------------
00764 ## @brief Add target for generation of ChangeLog file.
00765 #
00766 # The ChangeLog is either generated from the Subversion or Git log depending
00767 # on which revision control system is used by the project. Moreover, the
00768 # project's source directory must be either a Subversion working copy or
00769 # the root of a Git repository, respectively. In case of Subversion, if the
00770 # command-line tool svn2cl(.sh) is installed, it is used to output a nicer
00771 # formatted change log.
00772 function (basis_add_changelog)
00773   basis_make_target_uid (TARGET_UID "changelog")
00774 
00775   option (BUILD_CHANGELOG "Request build and/or installation of the ChangeLog." OFF)
00776   set (CHANGELOG_FILE "${PROJECT_BINARY_DIR}/ChangeLog")
00777 
00778   if (BASIS_VERBOSE)
00779     message (STATUS "Adding ChangeLog...")
00780   endif ()
00781 
00782   if (BUILD_CHANGELOG)
00783     set (_ALL "ALL")
00784   else ()
00785     set (_ALL)
00786   endif ()
00787 
00788   set (DISABLE_BUILD_CHANGELOG FALSE)
00789 
00790   # --------------------------------------------------------------------------
00791   # generate ChangeLog from Subversion history
00792   if (EXISTS "${PROJECT_SOURCE_DIR}/.svn")
00793     find_package (Subversion QUIET)
00794     if (Subversion_FOUND)
00795 
00796       if (_ALL)
00797         message ("Generation of ChangeLog enabled as part of ALL."
00798                  " Be aware that the ChangeLog generation from the Subversion"
00799                  " commit history can take several minutes and may require the"
00800                  " input of your Subversion repository credentials during the"
00801                  " build. If you would like to build the ChangeLog separate"
00802                  " from the rest of the software package, disable the option"
00803                  " BUILD_CHANGELOG. You can then build the changelog target"
00804                  " separate from ALL.")
00805       endif ()
00806 
00807       # using svn2cl command
00808       if (SVN2CL_EXECUTABLE)
00809         add_custom_target (
00810           ${TARGET_UID} ${_ALL}
00811           COMMAND "${SVN2CL_EXECUTABLE}"
00812               "--output=${CHANGELOG_FILE}"
00813               "--linelen=79"
00814               "--reparagraph"
00815               "--group-by-day"
00816               "--include-actions"
00817               "--separate-daylogs"
00818               "${PROJECT_SOURCE_DIR}"
00819           COMMAND "${CMAKE_COMMAND}"
00820               "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN2CL
00821               -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
00822           WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
00823           COMMENT "Generating ChangeLog from Subversion log (using svn2cl)..."
00824         )
00825       # otherwise, use svn log output directly
00826       else ()
00827         add_custom_target (
00828           ${TARGET_UID} ${_ALL}
00829           COMMAND "${CMAKE_COMMAND}"
00830               "-DCOMMAND=${Subversion_SVN_EXECUTABLE};log"
00831               "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
00832               "-DOUTPUT_FILE=${CHANGELOG_FILE}"
00833               -P "${BASIS_SCRIPT_EXECUTE_PROCESS}"
00834           COMMAND "${CMAKE_COMMAND}"
00835               "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN
00836               -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
00837           COMMENT "Generating ChangeLog from Subversion log..."
00838           VERBATIM
00839         )
00840       endif ()
00841 
00842     else ()
00843       message (STATUS "Project is SVN working copy but Subversion executable was not found."
00844                       " Generation of ChangeLog disabled.")
00845       set (DISABLE_BUILD_CHANGELOG TRUE)
00846     endif ()
00847 
00848   # --------------------------------------------------------------------------
00849   # generate ChangeLog from Git log
00850   elseif (EXISTS "${PROJECT_SOURCE_DIR}/.git")
00851     find_package (Git QUIET)
00852     if (GIT_FOUND)
00853 
00854       add_custom_target (
00855         ${TARGET_UID} ${_ALL}
00856         COMMAND "${CMAKE_COMMAND}"
00857             "-DCOMMAND=${GIT_EXECUTABLE};log;--date-order;--date=short;--pretty=format:%ad\ \ %an%n%n%w(79,8,10)* %s%n%n%b%n"
00858             "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
00859             "-DOUTPUT_FILE=${CHANGELOG_FILE}"
00860             -P "${BASIS_SCRIPT_EXECUTE_PROCESS}"
00861         COMMAND "${CMAKE_COMMAND}"
00862             "-DCHANGELOG_FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=GIT
00863             -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
00864         COMMENT "Generating ChangeLog from Git log..."
00865         VERBATIM
00866       )
00867 
00868     else ()
00869       message (STATUS "Project is Git repository but Git executable was not found."
00870                       " Generation of ChangeLog disabled.")
00871       set (DISABLE_BUILD_CHANGELOG TRUE)
00872     endif ()
00873 
00874   # --------------------------------------------------------------------------
00875   # neither SVN nor Git repository
00876   else ()
00877     message (STATUS "Project is neither SVN working copy nor Git repository."
00878                     " Generation of ChangeLog disabled.")
00879     set (DISABLE_BUILD_CHANGELOG TRUE)
00880   endif ()
00881 
00882   # --------------------------------------------------------------------------
00883   # disable changelog target
00884   if (DISABLE_BUILD_CHANGELOG)
00885     set (BUILD_CHANGELOG OFF CACHE INTERNAL "" FORCE)
00886     if (BASIS_VERBOSE)
00887       message (STATUS "Adding ChangeLog... - skipped")
00888     endif ()
00889     return ()
00890   endif ()
00891 
00892   # --------------------------------------------------------------------------
00893   # cleanup on "make clean"
00894   set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CHANGELOG_FILE}")
00895 
00896   # --------------------------------------------------------------------------
00897   # install ChangeLog
00898   install (
00899     FILES       "${CHANGELOG_FILE}"
00900     DESTINATION "${INSTALL_DOC_DIR}"
00901     COMPONENT   "${BASIS_RUNTIME_COMPONENT}"
00902     OPTIONAL
00903   )
00904 
00905   if (BASIS_VERBOSE)
00906     message (STATUS "Adding ChangeLog... - done")
00907   endif ()
00908 endfunction ()