BASIS  r3148
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 # adding / generating documentation
00022 # ============================================================================
00023 
00024 # ----------------------------------------------------------------------------
00025 ## @brief Add documentation target.
00026 #
00027 # This function is used to add a software documentation files to the project
00028 # which are either just copied to the installation or generated from input
00029 # files such as in particular source code files and documentation files
00030 # marked up using one of the supported lightweight markup languages.
00031 #
00032 # The supported generators are:
00033 # <table border="0">
00034 #   <tr>
00035 #     @tp @b None @endtp
00036 #     <td>This generator simply installs the given file or all files within
00037 #         the specified directory.</td>
00038 #   </tr>
00039 #   <tr>
00040 #     @tp @b Doxygen @endtp
00041 #     <td>Used to generate API documentation from in-source code comments and
00042 #         other related files marked up using Doxygen comments. See
00043 #         basis_add_doxygen_doc() for more details.</td>
00044 #   </tr>
00045 #   <tr>
00046 #     @tp @b Sphinx @endtp
00047 #     <td>Used to generate documentation such as a web site from reStructuredText.
00048 #         See basis_add_sphinx_doc() for more details.</td>
00049 #   </tr>
00050 # </table>
00051 #
00052 # @param [in] TARGET_NAME Name of the documentation target or file.
00053 # @param [in] ARGN        Documentation generator as "GENERATOR generator" option
00054 #                         and additional arguments for the particular generator.
00055 #                         The case of the generator name is ignored, i.e.,
00056 #                         @c Doxygen, @c DOXYGEN, @c doxYgen are all valid arguments
00057 #                         which select the @c Doxygen generator. The default generator
00058 #                         is the @c None generator.</td>
00059 #
00060 # @returns Adds a custom target @p TARGET_NAME for the generation of the
00061 #          documentation.
00062 #
00063 # @sa basis_install_doc()
00064 # @sa basis_add_doxygen_doc()
00065 # @sa basis_add_sphinx_doc()
00066 #
00067 # @ingroup CMakeAPI
00068 function (basis_add_doc TARGET_NAME)
00069   CMAKE_PARSE_ARGUMENTS (ARGN "" "GENERATOR" "" ${ARGN})
00070   if (NOT ARGN_GENERATOR)
00071     set (ARGN_GENERATOR "NONE")
00072   else ()
00073     string (TOUPPER "${ARGN_GENERATOR}" ARGN_GENERATOR)
00074   endif ()
00075   if (ARGN_GENERATOR MATCHES "NONE")
00076     basis_install_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
00077   elseif (ARGN_GENERATOR MATCHES "DOXYGEN")
00078     basis_add_doxygen_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
00079   elseif (ARGN_GENERATOR MATCHES "SPHINX")
00080     basis_add_sphinx_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
00081   else ()
00082     message (FATAL_ERROR "Unknown documentation generator: ${ARGN_GENERATOR}.")
00083   endif ()
00084 endfunction ()
00085 
00086 # ----------------------------------------------------------------------------
00087 ## @brief Install documentation file(s).
00088 #
00089 # This function either adds an installation rule for a single documentation
00090 # file or a directory containing multiple documentation files.
00091 #
00092 # Example:
00093 # @code
00094 # basis_install_doc ("User Manual.pdf" OUTPUT_NAME "BASIS User Manual.pdf")
00095 # basis_install_doc (DeveloperManual.docx COMPONENT dev)
00096 # basis_install_doc (SourceManual.html    COMPONENT src)
00097 # @endcode
00098 #
00099 # @param [in] SOURCE Documentation file or directory to install.
00100 # @param [in] ARGN   List of optional arguments. Valid arguments are:
00101 # @par
00102 # <table border="0">
00103 #   <tr>
00104 #     @tp @b COMPONENT component @endtp
00105 #     <td>Name of the component this documentation belongs to.
00106 #         Defaults to @c BASIS_RUNTIME_COMPONENT.</td>
00107 #   </tr>
00108 #   <tr>
00109 #     @tp @b DESTINATION dir @endtp
00110 #     <td>Installation directory prefix. Defaults to @c INSTALL_DOC_DIR.</td>
00111 #   </tr>
00112 #   <tr>
00113 #     @tp @b OUTPUT_NAME name @endtp
00114 #     <td>Name of file or directory after installation.</td>
00115 #   </tr>
00116 # </table>
00117 #
00118 # @sa basis_add_doc()
00119 function (basis_install_doc SOURCE)
00120   CMAKE_PARSE_ARGUMENTS (ARGN "" "COMPONENT;DESTINATION;OUTPUT_NAME" "" ${ARGN})
00121 
00122   if (NOT IS_ABSOLUTE "${SOURCE}")
00123     get_filename_component (SOURCE "${SOURCE}" ABSOLUTE)
00124   endif ()
00125   if (NOT ARGN_DESTINATION)
00126     set (ARGN_DESTINATION "${INSTALL_DOC_DIR}")
00127   endif ()
00128   if (NOT ARGN_COMPONENT)
00129     set (ARGN_COMPONENT "${BASIS_RUNTIME_COMPONENT}")
00130   endif ()
00131   if (NOT ARGN_COMPONENT)
00132     set (ARGN_COMPONENT "Unspecified")
00133   endif ()
00134   if (NOT ARGN_OUTPUT_NAME)
00135     basis_get_filename_component (ARGN_OUTPUT_NAME "${SOURCE}" NAME)
00136   endif ()
00137 
00138   basis_get_relative_path (
00139     RELPATH
00140       "${CMAKE_SOURCE_DIR}"
00141       "${CMAKE_CURRENT_SOURCE_DIR}/${ARGN_OUTPUT_NAME}"
00142   )
00143 
00144   message (STATUS "Adding documentation ${RELPATH}...")
00145 
00146   if (IS_DIRECTORY "${SOURCE}")
00147     basis_install_directory (
00148       "${SOURCE}" "${ARGN_DESTINATION}/${ARGN_OUTPUT_NAME}"
00149       COMPONENT "${ARGN_COMPONENT}"
00150     )
00151   else ()
00152     install (
00153       FILES       "${SOURCE}"
00154       DESTINATION "${ARGN_DESTINATION}"
00155       COMPONENT   "${ARGN_COMPONENT}"
00156       RENAME      "${ARGN_OUTPUT_NAME}"
00157     )
00158   endif ()
00159 
00160   message (STATUS "Adding documentation ${RELPATH}... - done")
00161 endfunction ()
00162 
00163 # ----------------------------------------------------------------------------
00164 ## @brief Add documentation to be generated by Doxygen.
00165 #
00166 # This function adds a build target to generate documentation from in-source
00167 # code comments and other related project pages using
00168 # <a href="http://www.stack.nl/~dimitri/doxygen/index.html">Doxygen</a>.
00169 #
00170 # @param [in] TARGET_NAME Name of the documentation target.
00171 # @param [in] ARGN        List of arguments. The valid arguments are:
00172 # @par
00173 # <table border="0">
00174 #   <tr>
00175 #     @tp @b EXCLUDE_FROM_DOC @endtp
00176 #     <td>By default, the specified target is build as part of the global
00177 #         @c doc target. If this option is given, however, the added
00178 #         documentation will not be build as part of this target.</td>
00179 #   </tr>
00180 #   <tr>
00181 #     @tp @b COMPONENT component @endtp
00182 #     <td>Name of the component this documentation belongs to.
00183 #         Defaults to @c BASIS_LIBRARY_COMPONENT.</td>
00184 #   </tr>
00185 #   <tr>
00186 #     @tp @b DESTINATION dir @endtp
00187 #     <td>Installation directory prefix. Defaults to
00188 #         @c BASIS_INSTALL_&ltTARGET&gt;_DIR in case of HTML output if set.
00189 #         Otherwise, the generated HTML files are not installed.</td>
00190 #   </tr>
00191 #   <tr>
00192 #     @tp @b DOXYFILE file @endtp
00193 #     <td>Name of the template Doxyfile.</td>
00194 #   </tr>
00195 #   <tr>
00196 #     @tp @b PROJECT_NAME name @endtp
00197 #     <td>Value for Doxygen's @c PROJECT_NAME tag which is used to
00198 #         specify the project name.@n
00199 #         Default: @c PROJECT_NAME.</td>
00200 #   </tr>
00201 #   <tr>
00202 #     @tp @b PROJECT_NUMBER version @endtp
00203 #     <td>Value for Doxygen's @c PROJECT_NUMBER tag which is used
00204 #         to specify the project version number.@n
00205 #         Default: @c PROJECT_RELEASE.</td>
00206 #   </tr>
00207 #   <tr>
00208 #     @tp @b INPUT path1 [path2 ...] @endtp
00209 #     <td>Value for Doxygen's @c INPUT tag which is used to specify input
00210 #         directories/files. Any given input path is added to the default
00211 #         input paths.@n
00212 #         Default: @c PROJECT_CODE_DIR, @c BINARY_CODE_DIR,
00213 #                  @c PROJECT_INCLUDE_DIR, @c BINARY_INCLUDE_DIR.</td>
00214 #   </tr>
00215 #   <tr>
00216 #     @tp @b INPUT_FILTER filter @endtp
00217 #     <td>
00218 #       Value for Doxygen's @c INPUT_FILTER tag which can be used to
00219 #       specify a default filter for all input files.@n
00220 #       Default: @c doxyfilter of BASIS.
00221 #     </td>
00222 #   </tr>
00223 #   <tr>
00224 #     @tp @b FILTER_PATTERNS pattern1 [pattern2...] @endtp
00225 #     <td>Value for Doxygen's @c FILTER_PATTERNS tag which can be used to
00226 #         specify filters on a per file pattern basis.@n
00227 #         Default: None.</td>
00228 #   </tr>
00229 #   <tr>
00230 #     @tp @b INCLUDE_PATH path1 [path2...] @endtp
00231 #     <td>Doxygen's @c INCLUDE_PATH tag can be used to specify one or more
00232 #         directories that contain include files that are not input files
00233 #         but should be processed by the preprocessor. Any given directories
00234 #         are appended to the default include path considered.
00235 #         Default: Directories added by basis_include_directories().</td>
00236 #   </tr>
00237 #   <tr>
00238 #     @tp @b EXCLUDE_PATTERNS pattern1 [pattern2 ...] @endtp
00239 #     <td>Additional patterns used for Doxygen's @c EXCLUDE_PATTERNS tag
00240 #         which can be used to specify files and/or directories that
00241 #         should be excluded from the INPUT source files.@n
00242 #         Default: No exclude patterns.</td>
00243 #   </tr>
00244 #   <tr>
00245 #     @tp @b OUTPUT fmt @endtp
00246 #     <td>Specify output formats in which to generate the documentation.
00247 #         Currently, only @c html and @c xml are supported.</td>
00248 #   </tr>
00249 #   <tr>
00250 #     @tp @b OUTPUT_DIRECTORY dir @endtp
00251 #     <td>Value for Doxygen's @c OUTPUT_DIRECTORY tag which can be used to
00252 #         specify the output directory. The output files are written to
00253 #         subdirectories named "html", "latex", "rtf", and "man".@n
00254 #         Default: <tt>CMAKE_CURRENT_BINARY_DIR/TARGET_NAME</tt>.</td>
00255 #   </tr>
00256 #   <tr>
00257 #     @tp @b COLS_IN_ALPHA_INDEX n @endtp
00258 #     <td>Number of columns in alphabetical index. Default: 3.</td>
00259 #   </tr>
00260 #   <tr>
00261 #     @tp @b IGNORE_PREFIX prefix1 [prefix2...] @endtp
00262 #     <td>In case all classes in a project start with a common prefix, all 
00263 #         classes will be put under the same header in the alphabetical index. 
00264 #         The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
00265 #         should be ignored while generating the index headers.</td>
00266 #   </tr>
00267 # </table>
00268 # @n
00269 # See <a href="http://www.stack.nl/~dimitri/doxygen/config.html">here</a> for a
00270 # documentation of the Doxygen tags.
00271 # @n@n
00272 # Example:
00273 # @code
00274 # basis_add_doxygen_doc (
00275 #   apidoc
00276 #   DOXYFILE        "Doxyfile.in"
00277 #   PROJECT_NAME    "${PROJECT_NAME}"
00278 #   PROJECT_VERSION "${PROJECT_VERSION}"
00279 #   COMPONENT       dev
00280 # )
00281 # @endcode
00282 #
00283 # @sa basis_add_doc()
00284 function (basis_add_doxygen_doc TARGET_NAME)
00285   # check target name
00286   basis_check_target_name ("${TARGET_NAME}")
00287   basis_make_target_uid (TARGET_UID "${TARGET_NAME}")
00288   string (TOLOWER "${TARGET_NAME}" TARGET_NAME_L)
00289   string (TOUPPER "${TARGET_NAME}" TARGET_NAME_U)
00290   # verbose output
00291   message (STATUS "Adding documentation ${TARGET_UID}...")
00292   # find Doxygen
00293   find_package (Doxygen QUIET)
00294   if (NOT DOXYGEN_EXECUTABLE)
00295     if (BUILD_DOCUMENTATION)
00296       message (FATAL_ERROR "Doxygen not found! Either install Doxygen and/or set DOXYGEN_EXECUTABLE or disable BUILD_DOCUMENTATION.")
00297     endif ()
00298     message (STATUS "Doxygen not found. Generation of ${TARGET_UID} documentation disabled.")
00299     message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
00300     return ()
00301   endif ()
00302   # parse arguments
00303   CMAKE_PARSE_ARGUMENTS (
00304     DOXYGEN
00305       "EXCLUDE_FROM_DOC"
00306       "COMPONENT;DESTINATION;HTML_DESTINATION;MAN_DESTINATION;DOXYFILE;TAGFILE;PROJECT_NAME;PROJECT_NUMBER;OUTPUT_DIRECTORY;COLS_IN_ALPHA_INDEX;MAN_SECTION"
00307       "INPUT;OUTPUT;INPUT_FILTER;FILTER_PATTERNS;EXCLUDE_PATTERNS;INCLUDE_PATH;IGNORE_PREFIX"
00308       ${ARGN}
00309   )
00310   # default component
00311   if (NOT DOXYGEN_COMPONENT)
00312     set (DOXYGEN_COMPONENT "${BASIS_LIBRARY_COMPONENT}")
00313   endif ()
00314   if (NOT DOXYGEN_COMPONENT)
00315     set (DOXYGEN_COMPONENT "Unspecified")
00316   endif ()
00317   # configuration file
00318   if (NOT DOXYGEN_DOXYFILE)
00319     set (DOXYGEN_DOXYFILE "${BASIS_DOXYGEN_DOXYFILE}")
00320   endif ()
00321   if (NOT EXISTS "${DOXYGEN_DOXYFILE}")
00322     message (FATAL_ERROR "Missing option DOXYGEN_FILE or Doxyfile ${DOXYGEN_DOXYFILE} does not exist.")
00323   endif ()
00324   # project name
00325   if (NOT DOXYGEN_PROJECT_NAME)
00326     set (DOXYGEN_PROJECT_NAME "${PROJECT_NAME}")
00327   endif ()
00328   if (NOT DOXYGEN_PROJECT_NUMBER)
00329     set (DOXYGEN_PROJECT_NUMBER "${PROJECT_RELEASE}")
00330   endif ()
00331   # standard input files
00332   list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/BasisProject.cmake")
00333   if (EXISTS "${PROJECT_CONFIG_DIR}/Depends.cmake")
00334     list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Depends.cmake")
00335   endif ()
00336   if (EXISTS "${BINARY_CONFIG_DIR}/Directories.cmake")
00337     list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/Directories.cmake")
00338   endif ()
00339   if (EXISTS "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
00340     list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
00341   endif ()
00342   if (EXISTS "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
00343     list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
00344   endif ()
00345   if (EXISTS "${BINARY_CONFIG_DIR}/Settings.cmake")
00346     list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/Settings.cmake")
00347   elseif (EXISTS "${PROJECT_CONFIG_DIR}/Settings.cmake")
00348     list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Settings.cmake")
00349   endif ()
00350   if (EXISTS "${BASIS_SCRIPT_CONFIG_FILE}")
00351     list (APPEND DOXYGEN_INPUT "${BASIS_SCRIPT_CONFIG_FILE}")
00352   endif ()
00353   if (EXISTS "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
00354     list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
00355   endif ()
00356   if (EXISTS "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
00357     list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
00358   endif ()
00359   if (EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
00360     list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
00361   endif ()
00362   if (EXISTS "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
00363     list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
00364   endif ()
00365   # package configuration files - only exist *after* this function executed
00366   list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}Config.cmake")
00367   list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}ConfigVersion.cmake")
00368   list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}Use.cmake")
00369   # input directories
00370   if (EXISTS "${PROJECT_INCLUDE_DIR}")
00371     list (APPEND DOXYGEN_INPUT "${PROJECT_INCLUDE_DIR}")
00372   endif ()
00373   if (EXISTS "${BINARY_INCLUDE_DIR}")
00374     list (APPEND DOXYGEN_INPUT "${BINARY_INCLUDE_DIR}")
00375   endif ()
00376   if (EXISTS "${BINARY_CODE_DIR}")
00377     list (APPEND DOXYGEN_INPUT "${BINARY_CODE_DIR}")
00378   endif ()
00379   if (EXISTS "${PROJECT_CODE_DIR}")
00380     list (APPEND DOXYGEN_INPUT "${PROJECT_CODE_DIR}")
00381   endif ()
00382   basis_get_relative_path (INCLUDE_DIR "${PROJECT_SOURCE_DIR}" "${PROJECT_INCLUDE_DIR}")
00383   basis_get_relative_path (CODE_DIR    "${PROJECT_SOURCE_DIR}" "${PROJECT_CODE_DIR}")
00384   foreach (M IN LISTS PROJECT_MODULES_ENABLED)
00385     if (EXISTS "${PROJECT_MODULES_DIR}/${M}/${CODE_DIR}")
00386       list (APPEND DOXYGEN_INPUT "${PROJECT_MODULES_DIR}/${M}/${CODE_DIR}")
00387     endif ()
00388     if (EXISTS "${PROJECT_MODULES_DIR}/${M}/${INCLUDE_DIR}")
00389       list (APPEND DOXYGEN_INPUT "${BINARY_MODULES_DIR}/${M}/${INCLUDE_DIR}")
00390     endif ()
00391   endforeach ()
00392   # in case of scripts, have Doxygen process the configured versions for the
00393   # installation which are further located in proper subdirectories instead
00394   # of the original source files
00395   basis_get_project_property (TARGETS)
00396   foreach (T IN LISTS TARGETS)
00397     get_target_property (BASIS_TYPE ${T} BASIS_TYPE)
00398     get_target_property (TEST       ${T} TEST)
00399     if (NOT TEST AND BASIS_TYPE MATCHES "SCRIPT")
00400       get_target_property (SOURCES ${T} SOURCES)
00401       if (SOURCES)
00402         list (GET SOURCES 0 BUILD_DIR)
00403         list (REMOVE_AT SOURCES 0)
00404         list (APPEND DOXYGEN_INPUT "${BUILD_DIR}.dir/build")
00405         foreach (S IN LISTS SOURCES)
00406           list (APPEND DOXYGEN_EXCLUDE_PATTERNS "${S}")
00407         endforeach ()
00408       endif ()
00409     endif ()
00410   endforeach ()
00411   # add .dox files as input
00412   file (GLOB_RECURSE DOX_FILES "${PROJECT_DOC_DIR}/*.dox")
00413   list (SORT DOX_FILES) # alphabetic order
00414   list (APPEND DOXYGEN_INPUT ${DOX_FILES})
00415   # add .dox files of BASIS modules
00416   list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Modules.dox")
00417   # add .dox files of used BASIS utilities
00418   list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
00419   list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/CxxUtilities.dox")
00420   foreach (L IN ITEMS Cxx Java Python Perl Bash Matlab)
00421     string (TOUPPER "${L}" U)
00422     if (U MATCHES "CXX")
00423       if (BASIS_UTILITIES_ENABLED MATCHES "CXX")
00424         set (PROJECT_USES_CXX_UTILITIES TRUE)
00425       else ()
00426         set (PROJECT_USES_CXX_UTILITIES FALSE)
00427       endif ()
00428     else ()
00429       basis_get_project_property (USES_${U}_UTILITIES PROPERTY PROJECT_USES_${U}_UTILITIES)
00430     endif ()
00431     if (USES_${U}_UTILITIES)
00432       list (FIND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox" IDX)
00433       if (IDX EQUAL -1)
00434         list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
00435       endif ()
00436       list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/${L}Utilities.dox")
00437     endif ()
00438   endforeach ()
00439   # include path - Disabled as this increases the runtime of Doxygen but
00440   #                generally the source of third-party packages are not
00441   #                really referenced. Only the source files of this
00442   #                project have to be considered. This code is kept as it
00443   #                might be used again at a later point once it is figured
00444   #                how Doxygen can be only rerun if necessary.
00445   #basis_get_project_property (INCLUDE_DIRS PROPERTY PROJECT_INCLUDE_DIRS)
00446   #foreach (D IN LISTS INCLUDE_DIRS)
00447   #  list (FIND DOXYGEN_INPUT "${D}" IDX)
00448   #  if (IDX EQUAL -1)
00449   #    list (APPEND DOXYGEN_INCLUDE_PATH "${D}")
00450   #  endif ()
00451   #endforeach ()
00452   #basis_list_to_delimited_string (
00453   #  DOXYGEN_INCLUDE_PATH "\"\nINCLUDE_PATH          += \"" ${DOXYGEN_INCLUDE_PATH}
00454   #)
00455   #set (DOXYGEN_INCLUDE_PATH "\"${DOXYGEN_INCLUDE_PATH}\"")
00456   # make string from DOXYGEN_INPUT - after include path was set
00457   basis_list_to_delimited_string (
00458     DOXYGEN_INPUT "\"\nINPUT                 += \"" ${DOXYGEN_INPUT}
00459   )
00460   set (DOXYGEN_INPUT "\"${DOXYGEN_INPUT}\"")
00461   # outputs
00462   if (NOT DOXYGEN_OUTPUT_DIRECTORY)
00463     set (DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME_L}")
00464   endif ()
00465   if (DOXYGEN_TAGFILE MATCHES "^(None|NONE|none)$")
00466     set (DOXYGEN_TAGFILE)
00467   else ()
00468     set (DOXYGEN_TAGFILE "${DOXYGEN_OUTPUT_DIRECTORY}/Doxytags.${TARGET_NAME_L}")
00469   endif ()
00470   if (NOT DOXYGEN_OUTPUT)
00471     set (DOXYGEN_OUTPUT html)
00472   endif ()
00473   foreach (F IN ITEMS HTML XML RTF LATEX MAN)
00474     set (DOXYGEN_GENERATE_${F} NO)
00475   endforeach ()
00476   foreach (f IN LISTS DOXYGEN_OUTPUT)
00477     if (NOT f MATCHES "^(html|xml)$")
00478       message (FATAL_ERROR "Invalid/Unsupported Doxygen output format: ${f}")
00479     endif ()
00480     string (TOUPPER "${f}" F)
00481     set (DOXYGEN_GENERATE_${F} YES)  # enable generation of this output
00482     set (DOXYGEN_${F}_OUTPUT "${f}") # relative output directory
00483   endforeach ()
00484   # input filters
00485   if (NOT DOXYGEN_INPUT_FILTER)
00486     basis_get_target_uid (DOXYFILTER "basis.doxyfilter")
00487     if (TARGET "${DOXYFILTER}")
00488       basis_get_target_location (DOXYGEN_INPUT_FILTER ${DOXYFILTER} ABSOLUTE)
00489     endif ()
00490   else ()
00491     set (DOXYFILTER)
00492   endif ()
00493   if (DOXYGEN_INPUT_FILTER)
00494     if (WIN32)
00495       # Doxygen on Windows (XP, 32-bit) (at least up to version 1.8.0) seems
00496       # to have a problem of not calling filters which have a space character
00497       # in their file path correctly. The doxyfilter.bat Batch program is used
00498       # as a wrapper for the actual filter which is part of the BASIS build.
00499       # As this file is in the working directory of Doxygen, it can be
00500       # referenced relative to this working directory, i.e., without file paths.
00501       # The Batch program itself then calls the actual Doxygen filter with proper
00502       # quotes to ensure that spaces in the file path are handled correctly.
00503       # The file extension .bat shall distinguish this wrapper script from the actual
00504       # doxyfilter.cmd which is generated by BASIS on Windows.
00505       configure_file ("${BASIS_MODULE_PATH}/doxyfilter.bat.in" "${DOXYGEN_OUTPUT_DIRECTORY}/doxyfilter.bat" @ONLY)
00506       set (DOXYGEN_INPUT_FILTER "doxyfilter.bat")
00507     endif ()
00508   endif ()
00509   basis_list_to_delimited_string (
00510     DOXYGEN_FILTER_PATTERNS "\"\nFILTER_PATTERNS       += \"" ${DOXYGEN_FILTER_PATTERNS}
00511   )
00512   if (DOXYGEN_FILTER_PATTERNS)
00513     set (DOXYGEN_FILTER_PATTERNS "\"${DOXYGEN_FILTER_PATTERNS}\"")
00514   endif ()
00515   # exclude patterns
00516   list (APPEND DOXYGEN_EXCLUDE_PATTERNS "cmake_install.cmake")
00517   list (APPEND DOXYGEN_EXCLUDE_PATTERNS "CTestTestfile.cmake")
00518   basis_list_to_delimited_string (
00519     DOXYGEN_EXCLUDE_PATTERNS "\"\nEXCLUDE_PATTERNS      += \"" ${DOXYGEN_EXCLUDE_PATTERNS}
00520   )
00521   set (DOXYGEN_EXCLUDE_PATTERNS "\"${DOXYGEN_EXCLUDE_PATTERNS}\"")
00522   # section for man pages
00523   if (NOT DOXYGEN_MAN_SECTION)
00524     set (DOXYGEN_MAN_SECTION 3)
00525   endif ()
00526   # other settings
00527   if (NOT DOXYGEN_COLS_IN_ALPHA_INDEX OR DOXYGEN_COLS_IN_ALPHA_INDEX MATCHES "[^0-9]")
00528     set (DOXYGEN_COLS_IN_ALPHA_INDEX 1)
00529   endif ()
00530   basis_list_to_delimited_string (DOXYGEN_IGNORE_PREFIX " " ${DOXYGEN_IGNORE_PREFIX})
00531   # HTML style
00532   set (DOXYGEN_HTML_STYLESHEET "${BASIS_MODULE_PATH}/doxygen_sbia.css")
00533   set (DOXYGEN_HTML_HEADER     "${BASIS_MODULE_PATH}/doxygen_header.html")
00534   set (DOXYGEN_HTML_FOOTER     "${BASIS_MODULE_PATH}/doxygen_footer.html")
00535   # click & jump in emacs and Visual Studio
00536   if (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
00537     set (DOXYGEN_WARN_FORMAT "\"$file($line) : $text \"")
00538   else ()
00539     set (DOXYGEN_WARN_FORMAT "\"$file:$line: $text \"")
00540   endif ()
00541   # installation directories
00542   set (BASIS_INSTALL_${TARGET_NAME_U}_DIR "" CACHE PATH "Installation directory for Doxygen ${TARGET_NAME} target.")
00543   mark_as_advanced (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
00544   foreach (f IN LISTS DOXYGEN_OUTPUT)
00545     string (TOUPPER "${f}" F)
00546     if (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
00547       set (DOXYGEN_${F}_DESTINATION "${BASIS_INSTALL_${TARGET_NAME_U}_DIR}") # user setting
00548     endif ()
00549     if (NOT DOXYGEN_${F}_DESTINATION)
00550       if (DOXYGEN_DESTINATION)
00551         set (DOXYGEN_${F}_DESTINATION "${DOXYGEN_DESTINATION}") # common destination
00552       elseif (f MATCHES "man")
00553         if (INSTALL_MAN_DIR)
00554           set (DOXYGEN_MAN_DESTINATION "${INSTALL_MAN_DIR}/man${DOXYGEN_MAN_SECTION}") # default for manual pages
00555         endif ()
00556       elseif (NOT f MATCHES "html") # do not install excludes by default
00557         set (DOXYGEN_${F}_DESTINATION "${INSTALL_DOC_DIR}") # default destination
00558       endif ()
00559     endif ()
00560   endforeach ()
00561   # configure Doxyfile
00562   set (DOXYFILE "${DOXYGEN_OUTPUT_DIRECTORY}/Doxyfile.${TARGET_NAME_L}")
00563   configure_file ("${DOXYGEN_DOXYFILE}" "${DOXYFILE}" @ONLY)
00564   # add target
00565   set (LOGOS)
00566   if (DOXYGEN_GENERATE_HTML)
00567     set (LOGOS "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}/logo_sbia.png"
00568                "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}/logo_penn.png")
00569     add_custom_command (
00570       OUTPUT   ${LOGOS}
00571       COMMAND "${CMAKE_COMMAND}" -E copy_if_different
00572                 "${BASIS_MODULE_PATH}/logo_sbia.png"
00573                 "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}/logo_sbia.png"
00574       COMMAND "${CMAKE_COMMAND}" -E copy_if_different
00575                 "${BASIS_MODULE_PATH}/logo_penn.gif"
00576                 "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}/logo_penn.gif"
00577       COMMENT "Copying logos to ${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}/..."
00578     )
00579   endif ()
00580   set (OPTALL)
00581   if (BUILD_DOCUMENTATION AND BASIS_ALL_DOC)
00582     set (OPTALL "ALL")
00583   endif ()
00584   file (MAKE_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}")
00585   add_custom_target (
00586     ${TARGET_UID} ${OPTALL} "${DOXYGEN_EXECUTABLE}" "${DOXYFILE}"
00587     DEPENDS ${LOGOS}
00588     WORKING_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}"
00589     COMMENT "Building documentation ${TARGET_UID}..."
00590   )
00591   # memorize certain settings which might be useful to know by other functions
00592   # in particular, in case of the use of the XML output by other documentation
00593   # build tools such as Sphinx, the function that wants to make use of this
00594   # output can check if the Doxygen target has been configured properly and
00595   # further requires to know the location of the XML output
00596   set_target_properties (
00597     ${TARGET_UID}
00598     PROPERTIES
00599       BASIS_TYPE       Doxygen
00600       OUTPUT_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}"
00601       DOXYFILE         "${DOXYGEN_DOXYFILE}"
00602       TAGFILE          "${DOXYGEN_TAGFILE}"
00603       OUTPUT           "${DOXYGEN_OUTPUT}"
00604   )
00605   foreach (f IN LISTS DOXYGEN_OUTPUT)
00606     string (TOUPPER "${f}" F)
00607     set_target_properties (
00608       ${TARGET_UID}
00609       PROPERTIES
00610         ${F}_INSTALL_DIRECTORY "${DOXYGEN_${F}_DESTINATION}"
00611         ${F}_OUTPUT_DIRECTORY  "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_${F}_OUTPUT}"
00612     )
00613     set_property (
00614       DIRECTORY
00615       APPEND PROPERTY
00616         ADDITIONAL_MAKE_CLEAN_FILES
00617           "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_${F}_OUTPUT}"
00618     )
00619   endforeach ()
00620   if (DOXYGEN_TAGFILE)
00621     set_property (
00622       DIRECTORY
00623       APPEND PROPERTY
00624         ADDITIONAL_MAKE_CLEAN_FILES
00625           "${DOXYGEN_TAGFILE}"
00626     )
00627   endif ()
00628   # The Doxygen filter, if a build target of this project, has to be build
00629   # before the documentation can be generated.
00630   if (TARGET "${DOXYFILTER}")
00631     add_dependencies (${TARGET_UID} ${DOXYFILTER})
00632   endif ()
00633   # The public header files shall be configured/copied before.
00634   if (TARGET headers)
00635     add_dependencies (${TARGET_UID} headers)
00636   endif ()
00637   # The documentation shall be build after all other executable and library
00638   # targets have been build. For example, a .py.in script file shall first
00639   # be "build", i.e., configured before the documentation is being generated
00640   # from the configured .py file.
00641   basis_get_project_property (TARGETS PROPERTY TARGETS)
00642   foreach (_UID ${TARGETS})
00643     get_target_property (BASIS_TYPE ${_UID} "BASIS_TYPE")
00644     if (BASIS_TYPE MATCHES "SCRIPT|EXECUTABLE|LIBRARY")
00645       add_dependencies (${TARGET_UID} ${_UID})
00646     endif ()
00647   endforeach ()
00648   # add general "doc" target
00649   if (NOT DOXYGEN_EXCLUDE_FROM_DOC)
00650     if (NOT TARGET doc)
00651       add_custom_target (doc)
00652     endif ()
00653     add_dependencies (doc ${TARGET_UID})
00654   endif ()
00655   # install documentation
00656   install (
00657     CODE
00658       "
00659       set (HTML_DESTINATION \"${DOXYGEN_HTML_DESTINATION}\")
00660       set (MAN_DESTINATION  \"${DOXYGEN_MAN_DESTINATION}\")
00661 
00662       function (install_doxydoc FMT)
00663         string (TOUPPER \"\${FMT}\" FMT_U)
00664         set (CMAKE_INSTALL_PREFIX \"\${\${FMT_U}_DESTINATION}\")
00665         if (NOT CMAKE_INSTALL_PREFIX)
00666           return ()
00667         elseif (NOT IS_ABSOLUTE \"\${CMAKE_INSTALL_PREFIX}\")
00668           set (CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}/\${CMAKE_INSTALL_PREFIX}\")
00669         endif ()
00670         set (EXT)
00671         set (DIR \"\${FMT}\")
00672         if (FMT MATCHES \".pdf\")
00673           set (EXT \".pdf\")
00674           set (DIR \"latex\")
00675         elseif (FMT MATCHES \".rtf\")
00676           set (EXT \".rtf\")
00677         elseif (FMT MATCHES \"man\")
00678           set (EXT \".?\")
00679         endif ()
00680         file (
00681           GLOB_RECURSE
00682             FILES
00683           RELATIVE \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}\"
00684             \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/*\${EXT}\"
00685         )
00686         foreach (F IN LISTS FILES)
00687           execute_process (
00688             COMMAND \"${CMAKE_COMMAND}\" -E compare_files
00689                 \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/\${F}\"
00690                 \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
00691             RESULT_VARIABLE RC
00692             OUTPUT_QUIET
00693             ERROR_QUIET
00694           )
00695           if (RC EQUAL 0)
00696             message (STATUS \"Up-to-date: \${CMAKE_INSTALL_PREFIX}/\${F}\")
00697           else ()
00698             message (STATUS \"Installing: \${CMAKE_INSTALL_PREFIX}/\${F}\")
00699             execute_process (
00700               COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
00701                   \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/\${F}\"
00702                   \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
00703               RESULT_VARIABLE RC
00704               OUTPUT_QUIET
00705               ERROR_QUIET
00706             )
00707             if (RC EQUAL 0)
00708               list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${F}\")
00709             else ()
00710               message (STATUS \"Failed to install \${CMAKE_INSTALL_PREFIX}/\${F}\")
00711             endif ()
00712           endif ()
00713         endforeach ()
00714         if (FMT MATCHES \"html\" AND EXISTS \"${DOXYGEN_TAGFILE}\")
00715           get_filename_component (DOXYGEN_TAGFILE_NAME \"${DOXYGEN_TAGFILE}\" NAME)
00716           execute_process (
00717             COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
00718               \"${DOXYGEN_TAGFILE}\"
00719               \"\${CMAKE_INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\"
00720           )
00721           list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\")
00722         endif ()
00723       endfunction ()
00724 
00725       foreach (FMT IN ITEMS html pdf rtf man)
00726         install_doxydoc (\${FMT})
00727       endforeach ()
00728       "
00729   )
00730   # done
00731   message (STATUS "Adding documentation ${TARGET_UID}... - done")
00732 endfunction ()
00733 
00734 # ----------------------------------------------------------------------------
00735 ## @brief Add documentation target to be generated by Sphinx (sphinx-build).
00736 #
00737 # This function adds a build target to generate documentation from
00738 # <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>
00739 # (.rst files) using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
00740 #
00741 # @param [in] TARGET_NAME Name of the documentation target.
00742 # @param [in] ARGN        List of arguments. The valid arguments are:
00743 # @par
00744 # <table border="0">
00745 #   <tr>
00746 #     @tp @b EXCLUDE_FROM_DOC @endtp
00747 #     <td>By default, the specified target is build as part of the global
00748 #         @c doc target. If this option is given, however, the added
00749 #         documentation will not be build as part of this target.</td>
00750 #   </tr>
00751 #   <tr>
00752 #     @tp @b BUILDER(S) builder... @endtp
00753 #     <td>Sphinx builders to use. For each named builder, a build target
00754 #         named &lt;TARGET_NAME&gt;_&lt;builder&gt; is added.</td>
00755 #   </tr>
00756 #   <tr>
00757 #     @tp @b DEFAULT_BUILDER builder @endtp
00758 #     <td>Default Sphinx builder to associated with the @c TARGET_NAME
00759 #         build target. Defaults to the first builder named by @c BUILDERS.</td>
00760 #   </tr>
00761 #   <tr>
00762 #     @tp @b AUTHOR(S) name @endtp
00763 #     <td>Names of authors who wrote this documentation.
00764 #         (default: @c PROJECT_AUTHORS)</td>
00765 #   </tr>
00766 #   <tr>
00767 #     @tp @b COPYRIGHT text @endtp
00768 #     <td>Copyright statement for generated files. (default: @c PROJECT_COPYRIGHT)</td>
00769 #   </tr>
00770 #   <tr>
00771 #     @tp @b COMPONENT component @endtp
00772 #     <td>Name of the component this documentation belongs to.
00773 #         Defaults to @c BASIS_RUNTIME_COMPONENT.</td>
00774 #   </tr>
00775 #   <tr>
00776 #     @tp @b DESTINATION dir @endtp
00777 #     <td>Installation directory prefix. Used whenever there is no specific
00778 #         destination specified for a particular Sphinx builder. Defaults to
00779 #         @c BASIS_INSTALL_&ltTARGET&gt;_DIR in case of HTML output if set.
00780 #         Otherwise, the generated HTML files are not installed.</td>
00781 #   </tr>
00782 #   <tr>
00783 #     @tp @b &lt;BUILDER&gt;_DESTINATION dir @endtp
00784 #     <td>Installation directory for files generated by the specific builder.<td>
00785 #   </tr>
00786 #   <tr>
00787 #     @tp @b EXTENSIONS ext... @endtp
00788 #     <td>Names of Sphinx extensions to enable.</td>
00789 #   </tr>
00790 #   <tr>
00791 #     @tp @b BREATHE target... @endtp
00792 #     <td>Adds a project for the breathe extension which allows the
00793 #         inclusion of in-source code documentation extracted by Doxygen.
00794 #         For this to work, the specified Doxygen target has to be
00795 #         configured with the XML output enabled.</td>
00796 #   </tr>
00797 #   <tr>
00798 #     @tp @b DOXYLINK target... @endtp
00799 #     <td>Adds a role for the doxylink Sphinx extension which allows to cross-reference
00800 #         generated HTML API documentation generated by Doxygen.</td>
00801 #   </tr>
00802 #   <tr>
00803 #     @tp @b DOXYLINK_URL url @endtp
00804 #     <td>URL to Doxygen documentation. Use DOXYLINK_PREFIX and/or DOXYLINK_SUFFIX
00805 #         instead if you use multiple Doxygen targets, where the target name is
00806 #         part of the URL.</td>
00807 #   </tr>
00808 #   <tr>
00809 #     @tp @b DOXYLINK_PREFIX url @endtp
00810 #     <td>Prefix to use for links to Doxygen generated documentation pages
00811 #         as generated by the doxylink Sphinx extension. If this prefix does
00812 #         not start with a protocol such as http:// or https://, it is prefixed
00813 #         to the default path determined by this function relative to the build
00814 #         or installed Doxygen documentation.</td>
00815 #   </tr>
00816 #   <tr>
00817 #     @tp @b DOXYLINK_SUFFIX suffix @endtp
00818 #     <td>Suffix for links to Doxygen generated documentation pages as generated
00819 #         by the doxylink Sphinx extension.</td>
00820 #   </tr>
00821 #   <tr>
00822 #     @tp @b DOXYDOC target... @endtp
00823 #     <td>Alias for both @c BREATHE and @c DOXYLINK options.</td>
00824 #   </tr>
00825 #   <tr>
00826 #     @tp @b CONFIG_FILE file @endtp
00827 #     <td>Sphinx configuration file. Defaults to @c BASIS_SPHINX_CONFIG.</td>
00828 #   </tr>
00829 #   <tr>
00830 #     @tp @b SOURCE_DIRECTORY @endtp
00831 #     <td>Root directory of Sphinx source files.
00832 #         Defaults to the current source directory or, if a subdirectory
00833 #         named @c TARGET_NAME in lowercase only exists, to this subdirectory.</td>
00834 #   </tr>
00835 #   <tr>
00836 #     @tp @b OUTPUT_NAME @endtp
00837 #     <td>Output name for generated documentation such as PDF document or MAN page.
00838 #         Defaults to @c PROJECT_NAME.</td>
00839 #   </tr>
00840 #   <tr>
00841 #     @tp @b OUTPUT_DIRECTORY @endtp
00842 #     <td>Root output directory for generated files. Defaults to the binary
00843 #         directory corresponding to the set @c SOURCE_DIRECTORY.</td>
00844 #   </tr>
00845 #   <tr>
00846 #     @tp @b TAG tag @endtp
00847 #     <td>Tag argument of <tt>sphinx-build</tt>.</td>
00848 #   </tr>
00849 #   <tr>
00850 #     @tp @b TEMPLATES_PATH @endtp
00851 #     <td>Path to template files. Defaults to <tt>SOURCE_DIRECTORY/templates/</tt>.</td>
00852 #   </tr>
00853 #   <tr>
00854 #     @tp @b MASTER_DOC name @endtp
00855 #     <td>Name of master document. Defaults to <tt>index</tt>.</td>
00856 #   </tr>
00857 #   <tr>
00858 #     @tp @b HTML_TITLE title @endtp
00859 #     <td>Title of HTML web site.</td>
00860 #   </tr>
00861 #   <tr>
00862 #     @tp @b HTML_THEME theme @endtp
00863 #     <td>Name of HTML theme. Defaults to the @c sbia theme included with BASIS.</td>
00864 #   </tr>
00865 #   <tr>
00866 #     @tp @b HTML_THEME_PATH dir @endtp
00867 #     <td>Directory of HTML theme. Defaults to @c BASIS_SPHINX_HTML_THEME_PATH.</td>
00868 #   </tr>
00869 #   <tr>
00870 #     @tp @b HTML_LOGO file @endtp
00871 #     <td>Logo to display in sidebar of HTML pages.</td>
00872 #   </tr>
00873 #   <tr>
00874 #     @tp @b HTML_STATIC_PATH dir @endtp
00875 #     <td>Directory for static files of HTML pages. Defaults to <tt>SOURCE_DIRECTORY/static/</tt>.</td>
00876 #   </tr>
00877 #   <tr>
00878 #     @tp @b HTML_STYLE css @endtp
00879 #     <td>The style sheet to use for HTML pages. A file of that name must exist either in Sphinx'
00880 #         default static/ path or the specified @c HTML_STATIC_PATH. Default is the stylesheet
00881 #         given by the selected theme. If you only want to add or override a few things compared
00882 #         to the theme’s stylesheet, use CSS \@import to import the theme’s stylesheet.</td>
00883 #   </tr>
00884 #   <tr>
00885 #     @tp @b HTML_SIDEBARS name... @endtp
00886 #     <td>Names of HTML template files for sidebar(s). Defaults to none if not specified.
00887 #         Valid default templates are @c localtoc, @c globaltoc, @c searchbox, @c relations,
00888 #         @c sourcelink. See <a href="http://sphinx.pocoo.org/config.html#confval-html_sidebars">
00889 #         Shinx documentation of html_sidebars option</a>. Custom templates can be used as
00890 #         well by copying the template <tt>.html</tt> file to the @c TEMPLATES_PATH directory.</td>
00891 #   </tr>
00892 #   <tr>
00893 #     @tp @b LATEX_TITLE title @endtp
00894 #     <td>Title for LaTeX/PDF output. Defaults to title of <tt>index.rst</tt>.</td>
00895 #   </tr>
00896 #   <tr>
00897 #     @tp @b LATEX_LOGO file @endtp
00898 #     <td>Logo to display above title in generated LaTeX/PDF output.</td>
00899 #   </tr>
00900 #   <tr>
00901 #     @tp @b LATEX_DOCUMENT_CLASS howto|manual @endtp
00902 #     <td>Document class to use by @c latex builder.</td>
00903 #   </tr>
00904 #   <tr>
00905 #     @tp @b LATEX_SHOW_URLS @endtp
00906 #     <td>See Sphinx documentation of the
00907 #         <a href="http://sphinx.pocoo.org/config.html#confval-latex_show_urls">latex_show_urls</a> option.</td>
00908 #   </tr>
00909 #   <tr>
00910 #     @tp @b LATEX_SHOW_PAGEREFS @endtp
00911 #     <td>See Sphinx documentation of the
00912 #         <a href="">latex_show_pagerefs</a> option.</td>
00913 #   </tr>
00914 #   <tr>
00915 #     @tp @b MAN_SECTION num @endtp
00916 #     <td>Section number for manual pages generated by @c man builder.</td>
00917 #   </tr>
00918 # </table>
00919 #
00920 # @sa basis_add_doc()
00921 function (basis_add_sphinx_doc TARGET_NAME)
00922   # check target name
00923   basis_check_target_name ("${TARGET_NAME}")
00924   basis_make_target_uid (TARGET_UID "${TARGET_NAME}")
00925   string (TOLOWER "${TARGET_NAME}" TARGET_NAME_L)
00926   string (TOUPPER "${TARGET_NAME}" TARGET_NAME_U)
00927   # verbose output
00928   message (STATUS "Adding documentation ${TARGET_UID}...")
00929   # parse arguments
00930   set (ONE_ARG_OPTIONS
00931     COMPONENT
00932     DEFAUL_BUILDER
00933     DESTINATION HTML_DESTINATION MAN_DESTINATION TEXINFO_DESTINATION
00934     CONFIG_FILE
00935     SOURCE_DIRECTORY OUTPUT_DIRECTORY OUTPUT_NAME TAG
00936     COPYRIGHT MASTER_DOC
00937     HTML_TITLE HTML_THEME HTML_LOGO HTML_THEME_PATH HTML_STYLE
00938     LATEX_TITLE LATEX_LOGO LATEX_DOCUMENT_CLASS LATEX_SHOW_URLS LATEX_SHOW_PAGEREFS
00939     MAN_SECTION
00940     DOXYLINK_URL DOXYLINK_PREFIX DOXYLINK_SUFFIX
00941   )
00942   # note that additional multiple value arguments are parsed later on below
00943   # this is necessary b/c all unparsed arguments are considered to be options
00944   # of the used HTML theme
00945   CMAKE_PARSE_ARGUMENTS (SPHINX "EXCLUDE_FROM_DOC" "${ONE_ARG_OPTIONS}" "" ${ARGN})
00946   # source directory
00947   if (NOT SPHINX_SOURCE_DIRECTORY)
00948     if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}")
00949       set (SPHINX_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}")
00950     else ()
00951       set (SPHINX_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
00952     endif ()
00953   elseif (NOT IS_ABSOLUTE "${SPHINX_SOURCE_DIRECTORY}")
00954     get_filename_component (SPHINX_SOURCE_DIRECTORY "${SPHINX_SOURCE_DIRECTORY}" ABSOLUTE)
00955   endif ()
00956   # component
00957   if (NOT SPHINX_COMPONENT)
00958     set (SPHINX_COMPONENT "${BASIS_RUNTIME_COMPONENT}")
00959   endif ()
00960   if (NOT SPHINX_COMPONENT)
00961     set (SPHINX_COMPONENT "Unspecified")
00962   endif ()
00963   # find Sphinx
00964   find_package (Sphinx COMPONENTS build QUIET)
00965   if (NOT Sphinx-build_EXECUTABLE)
00966     if (BUILD_DOCUMENTATION)
00967       message (FATAL_ERROR "Command sphinx-build not found! Either install Sphinx and/or set Sphinx-build_EXECUTABLE or disable BUILD_DOCUMENTATION.")
00968     endif ()
00969     message (STATUS "Command sphinx-build not found. Generation of ${TARGET_UID} documentation disabled.")
00970     message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
00971     return ()
00972   endif ()
00973   if (DEFINED Sphinx_VERSION_MAJOR AND Sphinx_VERSION_MAJOR LESS 1)
00974     if (BUILD_DOCUMENTATION)
00975       message (FATAL_ERROR "Found sphinx-build is too old (v${Sphinx_VERSION_STRING})! Please install a more recent version and/or set Sphinx-build_EXECUTABLE to a newer version or disable BUILD_DOCUMENTATION.")
00976     endif ()
00977     message (STATUS "Command sphinx-build is too old (v${Sphinx_VERSION_STRING}). Generation of ${TARGET_UID} documentation disabled.")
00978     message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
00979     return ()
00980   endif ()
00981   # parse remaining arguments
00982   set (SPHINX_HTML_THEME_OPTIONS)
00983   set (SPHINX_BUILDERS)
00984   set (SPHINX_AUTHORS)
00985   set (SPHINX_EXTENSIONS)
00986   set (SPHINX_BREATHE_TARGETS)
00987   set (SPHINX_DOXYLINK_TARGETS)
00988   set (SPHINX_HTML_SIDEBARS)
00989   set (SPHINX_TEMPLATES_PATH)
00990   set (SPHINX_HTML_STATIC_PATH)
00991   set (SPHINX_EXCLUDE_PATTERNS)
00992   set (SPHINX_DEPENDS)
00993   set (OPTION_NAME)
00994   set (OPTION_VALUE)
00995   set (OPTION_PATTERN "(authors?|builders?|extensions|breathe|doxylink|doxydoc|html_sidebars|templates_path|html_static_path|exclude_patterns)")
00996   foreach (ARG IN LISTS SPHINX_UNPARSED_ARGUMENTS)
00997     if (NOT OPTION_NAME OR ARG MATCHES "^[A-Z_]+$")
00998       # SPHINX_HTML_THEME_OPTIONS
00999       if (OPTION_NAME AND NOT OPTION_NAME MATCHES "^${OPTION_PATTERN}$")
01000         if (NOT OPTION_VALUE)
01001           message (FATAL_ERROR "Option ${OPTION_NAME} is missing an argument!")
01002         endif ()
01003         list (LENGTH OPTION_VALUE NUM)
01004         if (NUM GREATER 1)
01005           basis_list_to_delimited_string (OPTION_VALUE ", " NOAUTOQUOTE ${OPTION_VALUE})
01006           set (OPTION_VALUE "[${OPTION_VALUE}]")
01007         endif ()
01008         list (APPEND SPHINX_HTML_THEME_OPTIONS "'${OPTION_NAME}': ${OPTION_VALUE}")
01009       endif ()
01010       # name of next option
01011       set (OPTION_NAME "${ARG}")
01012       set (OPTION_VALUE)
01013       string (TOLOWER "${OPTION_NAME}" OPTION_NAME)
01014     # BUILDER option
01015     elseif (OPTION_NAME MATCHES "^builders?$")
01016       if (ARG MATCHES "html dirhtml singlehtml pdf latex man text texinfo linkcheck")
01017         message (FATAL_ERROR "Invalid/Unsupported Sphinx builder: ${ARG}")
01018       endif ()
01019       list (APPEND SPHINX_BUILDERS "${ARG}")
01020     # AUTHORS option
01021     elseif (OPTION_NAME MATCHES "^authors?$")
01022       list (APPEND SPHINX_AUTHORS "'${ARG}'")
01023     # EXTENSIONS option
01024     elseif (OPTION_NAME MATCHES "^extensions$")
01025       # built-in extension
01026       if (ARG MATCHES "^(autodoc|autosummary|doctest|intersphinx|pngmath|jsmath|mathjax|graphvis|inheritance_graph|ifconfig|coverage|todo|extlinks|viewcode)$")
01027         set (ARG "sphinx.ext.${CMAKE_MATCH_0}")
01028       # map originial name of extensions included with BASIS
01029       elseif (ARG MATCHES "^sphinx-contrib.(doxylink)$")
01030         set (ARG "${CMAKE_MATCH_1}")
01031       endif ()
01032       list (APPEND SPHINX_EXTENSIONS "'${ARG}'")
01033     # DOXYDOC
01034     elseif (OPTION_NAME MATCHES "^doxydoc$")
01035       list (APPEND SPHINX_BREATHE_TARGETS  "${ARG}")
01036       list (APPEND SPHINX_DOXYLINK_TARGETS "${ARG}")
01037     # BREATHE
01038     elseif (OPTION_NAME MATCHES "^breathe$")
01039       list (APPEND SPHINX_BREATHE_TARGETS "${ARG}")
01040     # DOXYLINK
01041     elseif (OPTION_NAME MATCHES "^doxylink$")
01042       list (APPEND SPHINX_DOXYLINK_TARGETS "${ARG}")
01043     # HTML_SIDEBARS
01044     elseif (OPTION_NAME MATCHES "^html_sidebars$")
01045       if (NOT ARG MATCHES "\\.html?$")
01046         set (ARG "${ARG}.html")
01047       endif ()
01048       list (APPEND SPHINX_HTML_SIDEBARS "'${ARG}'")
01049     # TEMPLATES_PATH
01050     elseif (OPTION_NAME MATCHES "^templates_path$")
01051       if (NOT IS_ABSOLUTE "${ARG}")
01052         set (ARG "${SPHINX_SOURCE_DIRECTORY}/${ARG}")
01053       endif ()
01054       list (APPEND SPHINX_TEMPLATES_PATH "'${ARG}'")
01055     # HTML_STATIC_PATH
01056     elseif (OPTION_NAME MATCHES "^html_static_path$")
01057       if (NOT IS_ABSOLUTE "${ARG}")
01058         set (ARG "${SPHINX_SOURCE_DIRECTORY}/${ARG}")
01059       endif ()
01060       list (APPEND SPHINX_HTML_STATIC_PATH "'${ARG}'")
01061     # EXCLUDE_PATTERNS
01062     elseif (OPTION_NAME MATCHES "^exclude_patterns$")
01063       list (APPEND SPHINX_EXCLUDE_PATTERNS "'${ARG}'")
01064     # value of theme option
01065     else ()
01066       if (ARG MATCHES "^(TRUE|FALSE)$")
01067         string (TOLOWER "${ARG}" "${ARG}")
01068       endif ()
01069       if (NOT ARG MATCHES "^\\[.*\\]$|^{.*}$")
01070         set (ARG "'${ARG}'")
01071       endif ()
01072       list (APPEND OPTION_VALUE "${ARG}")
01073     endif ()
01074   endforeach ()
01075   # append parsed option setting to SPHINX_HTML_THEME_OPTIONS
01076   if (OPTION_NAME AND NOT OPTION_NAME MATCHES "^${OPTION_PATTERN}$")
01077     if (NOT OPTION_VALUE)
01078       message (FATAL_ERROR "Option ${OPTION_NAME} is missing an argument!")
01079     endif ()
01080     list (LENGTH OPTION_VALUE NUM)
01081     if (NUM GREATER 1)
01082       basis_list_to_delimited_string (OPTION_VALUE ", " NOAUTOQUOTE ${OPTION_VALUE})
01083       set (OPTION_VALUE "[${OPTION_VALUE}]")
01084     endif ()
01085     list (APPEND SPHINX_HTML_THEME_OPTIONS "'${OPTION_NAME}': ${OPTION_VALUE}")
01086   endif ()
01087   # authors
01088   if (NOT SPHINX_AUTHORS)
01089     foreach (AUTHOR IN LISTS PROJECT_AUTHORS)
01090       list (APPEND SPHINX_AUTHORS "'${AUTHOR}'")
01091     endforeach ()
01092   endif ()
01093   if (NOT SPHINX_COPYRIGHT)
01094     set (SPHINX_COPYRIGHT "${PROJECT_COPYRIGHT}")
01095   endif ()
01096   # default builders
01097   if (NOT SPHINX_BUILDERS)
01098     set (SPHINX_BUILDERS html dirhtml singlehtml man pdf texinfo text linkcheck)
01099   endif ()
01100   if (SPHINX_DEFAULT_BUILDER)
01101     list (FIND SPHINX_BUILDERS "${SPHINX_DEFAULT_BUILDER}" IDX)
01102     if (IDX EQUAL -1)
01103       list (INSERT SPHINX_BUILDERS 0 "${SPHINX_DEFAULT_BUILDER}")
01104     endif ()
01105   else ()
01106     list (GET SPHINX_BUILDERS 0 SPHINX_DEFAULT_BUILDER)
01107   endif ()
01108   # output directories
01109   if (NOT SPHINX_OUTPUT_NAME)
01110     set (SPHINX_OUTPUT_NAME "${PROJECT_NAME}")
01111   endif ()
01112   if (NOT SPHINX_OUTPUT_DIRECTORY)
01113     if (IS_ABSOLUTE "${SPHINX_OUTPUT_NAME}")
01114       get_filename_component (SPHINX_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_NAME}" PATH)
01115     else ()
01116       basis_get_relative_path (SPHINX_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${SPHINX_SOURCE_DIRECTORY}")
01117     endif ()
01118   endif ()
01119   if (NOT IS_ABSOLUTE "${SPHINX_OUTPUT_DIRECTORY}")
01120     set (SPHINX_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${SPHINX_OUTPUT_DIRECTORY}")
01121   endif ()
01122   foreach (b IN LISTS SPHINX_BUILDERS)
01123     string (TOUPPER "${b}" B)
01124     if (SPHINX_${B}_OUTPUT_DIRECTORY)
01125       if (NOT IS_ABSOLUTE "${SPHINX_${B}_OUTPUT_DIRECTORY}")
01126         set (SPHINX_${B}_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_${B}_OUTPUT_DIRECTORY}")
01127       endif ()
01128     else ()
01129       set (SPHINX_${B}_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}/${b}")
01130     endif ()
01131   endforeach ()
01132   if (IS_ABSOLUTE "${SPHINX_OUTPUT_NAME}")
01133     basis_get_relative_path (SPHINX_OUTPUT_NAME "${SPHINX_OUTPUT_DIRECTORY}" NAME_WE)
01134   endif ()
01135   # configuration directory
01136   basis_get_relative_path (SPHINX_CONFIG_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${SPHINX_SOURCE_DIRECTORY}")
01137   set (SPHINX_CONFIG_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${SPHINX_CONFIG_DIRECTORY}")
01138   # build configuration
01139   if (NOT SPHINX_MASTER_DOC)
01140     set (SPHINX_MASTER_DOC "index")
01141   endif ()
01142   if (NOT SPHINX_TEMPLATES_PATH AND EXISTS "${SPHINX_SOURCE_DIRECTORY}/templates")
01143     set (SPHINX_TEMPLATES_PATH "'${SPHINX_SOURCE_DIRECTORY}/templates'")
01144   endif ()
01145   if (NOT SPHINX_HTML_STATIC_PATH AND EXISTS "${SPHINX_SOURCE_DIRECTORY}/static")
01146     set (SPHINX_HTML_STATIC_PATH "'${SPHINX_SOURCE_DIRECTORY}/static'")
01147   endif ()
01148   if (NOT SPHINX_HTML_THEME)
01149     set (SPHINX_HTML_THEME "${BASIS_SPHINX_HTML_THEME}")
01150   endif ()
01151   if (NOT SPHINX_UNPARSED_ARGUMENTS AND SPHINX_HTML_THEME STREQUAL BASIS_SPHINX_HTML_THEME)
01152     set (SPHINX_UNPARSED_ARGUMENTS ${BASIS_SPHINX_HTML_THEME_OPTIONS})
01153   endif () 
01154   if (NOT SPHINX_LATEX_DOCUMENT_CLASS)
01155     set (SPHINX_LATEX_DOCUMENT_CLASS "howto")
01156   endif ()
01157   if (NOT SPHINX_MAN_SECTION)
01158     set (SPHINX_MAN_SECTION 1)
01159   endif ()
01160   # installation directories
01161   set (BASIS_INSTALL_${TARGET_NAME_U}_DIR "" CACHE PATH "Installation directory for documentation ${TARGET_NAME} target.")
01162   mark_as_advanced (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
01163   foreach (b IN LISTS SPHINX_BUILDERS)
01164     string (TOUPPER "${b}" B)
01165     if (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
01166       set (SPHINX_${B}_DESTINATION "${BASIS_INSTALL_${TARGET_NAME_U}_DIR}") # user setting
01167     endif ()
01168     if (NOT SPHINX_${B}_DESTINATION)
01169       if (SPHINX_DESTINATION)                           
01170         set (SPHINX_${B}_DESTINATION "${DESTINATION}") # common destination
01171       elseif (b MATCHES "text")
01172         set (SPHINX_${B}_DESTINATION "${INSTALL_DOC_DIR}/${TARGET_NAME_L}")
01173       elseif (b MATCHES "man")
01174         if (INSTALL_MAN_DIR)
01175           set (SPHINX_${B}_DESTINATION "${INSTALL_MAN_DIR}/man${SPHINX_MAN_SECTION}") # default for manual pages
01176         endif ()
01177       elseif (b MATCHES "texinfo")
01178         if (INSTALL_TEXINFO_DIR)
01179           set (SPHINX_${B}_DESTINATION "${INSTALL_TEXINFO_DIR}") # default for Texinfo files
01180         endif ()
01181       elseif (NOT b MATCHES "html") # do not install excludes by default
01182         set (SPHINX_${B}_DESTINATION "${INSTALL_DOC_DIR}") # default location
01183       endif ()
01184     endif ()
01185   endforeach ()
01186   if (SPHINX_HTML_DESTINATION)
01187     foreach (b IN LISTS SPHINX_BUILDERS)
01188       if (b MATCHES "(dir|single)html")
01189         string (TOUPPER "${b}" B)
01190         if (NOT SPHINX_${B}_DESTINATION)
01191           set (SPHINX_${B}_DESTINATION "${SPHINX_HTML_DESTINATION}")
01192         endif ()
01193       endif ()
01194     endforeach ()
01195   endif ()
01196   # enable required extension
01197   if (SPHINX_DOXYLINK_TARGETS AND NOT SPHINX_EXTENSIONS MATCHES "(^|;)?doxylink(;|$)?")
01198     list (APPEND SPHINX_EXTENSIONS "'doxylink'")
01199   endif ()
01200   if (SPHINX_BREATHE_TARGETS AND NOT SPHINX_EXTENSIONS MATCHES "(^|;)?breathe(;|$)?")
01201     list (APPEND SPHINX_EXTENSIONS "'breathe'")
01202   endif ()
01203   # doxylink configuration
01204   foreach (TARGET IN LISTS SPHINX_DOXYLINK_TARGETS)
01205     basis_get_target_uid (UID "${TARGET}")
01206     get_target_property (TYPE ${UID} BASIS_TYPE)
01207     if (NOT TYPE MATCHES "Doxygen")
01208       message (FATAL_ERROR "Invalid argument for DOXYLINK: Target ${UID} either unknown or it is not a Doxygen target!")
01209     endif ()
01210     get_target_property (DOXYGEN_OUTPUT ${UID} OUTPUT)
01211     if (NOT DOXYGEN_OUTPUT MATCHES "html")
01212       message (FATAL_ERROR "Doxygen target ${UID} was not configured to generate HTML output! This output is required by the doxylink Sphinx extension.")
01213     endif ()
01214     get_target_property (DOXYGEN_TAGFILE        ${UID} TAGFILE)
01215     get_target_property (DOXYGEN_HTML_DIRECTORY ${UID} HTML_INSTALL_DIRECTORY)
01216     set (DOXYLINK_PATH)
01217     if (SPHINX_DOXYLINK_URL)
01218       set (DOXYLINK_PATH "${SPHINX_DOXYLINK_URL}")
01219     elseif (SPHINX_DOXYLINK_PREFIX MATCHES "^[a-z]://")
01220       set (DOXYLINK_PATH "${SPHINX_DOXYLINK_PREFIX}${TARGET}${SPHINX_DOXYLINK_SUFFIX}")
01221     else ()
01222       set (DOXYLINK_BASE_DIR)
01223       if (DOXYGEN_HTML_DIRECTORY)
01224         if (SPHINX_DOXYLINK_BASE_DIR)
01225           set (DOXYLINK_BASE_DIR "${SPHINX_DOXYLINK_BASE_DIR}")
01226         elseif (SPHINX_HTML_INSTALL_DIRECTORY)
01227           set (DOXYLINK_BASE_DIR "${SPHINX_HTML_INSTALL_DIRECTORY}")
01228         endif ()
01229       else ()
01230         get_target_property (DOXYGEN_HTML_DIRECTORY ${UID} HTML_OUTPUT_DIRECTORY)
01231         if (SPHINX_DOXYLINK_BASE_DIR)
01232           set (DOXYLINK_BASE_DIR "${SPHINX_DOXYLINK_BASE_DIR}")
01233         else ()
01234           set (DOXYLINK_BASE_DIR "${SPHINX_HTML_OUTPUT_DIRECTORY}")
01235         endif ()
01236       endif ()
01237       if (DOXYLINK_BASE_DIR)
01238         basis_get_relative_path (DOXYLINK_PATH "${DOXYLINK_BASE_DIR}" "${DOXYGEN_HTML_DIRECTORY}")
01239       else ()
01240         set (DOXYLINK_PATH "${TARGET}") # safe fall back
01241       endif ()
01242       set (DOXYLINK_PATH "${SPHINX_DOXYLINK_PREFIX}${DOXYLINK_PATH}${SPHINX_DOXYLINK_SUFFIX}")
01243     endif ()
01244     list (APPEND SPHINX_DOXYLINK "'${TARGET}': ('${DOXYGEN_TAGFILE}', '${DOXYLINK_PATH}')")
01245     list (APPEND SPHINX_DEPENDS ${UID})
01246   endforeach ()
01247   # breathe configuration
01248   set (SPHINX_BREATHE_PROJECTS)
01249   set (SPHINX_BREATHE_DEFAULT_PROJECT)
01250   foreach (TARGET IN LISTS SPHINX_BREATHE_TARGETS)
01251     basis_get_target_uid (UID "${TARGET}")
01252     get_target_property (TYPE ${UID} BASIS_TYPE)
01253     if (NOT TYPE MATCHES "Doxygen")
01254       message (FATAL_ERROR "Invalid argument for BREATHE_PROJECTS: Target ${UID} either unknown or it is not a Doxygen target!")
01255     endif ()
01256     get_target_property (DOXYGEN_OUTPUT ${UID} OUTPUT)
01257     if (NOT DOXYGEN_OUTPUT MATCHES "xml")
01258       message (FATAL_ERROR "Doxygen target ${UID} was not configured to generate XML output! This output is required by the Sphinx extension breathe.")
01259     endif ()
01260     get_target_property (DOXYGEN_OUTPUT_DIRECTORY ${UID} XML_OUTPUT_DIRECTORY)
01261     list (APPEND SPHINX_BREATHE_PROJECTS "'${TARGET}': '${DOXYGEN_OUTPUT_DIRECTORY}'")
01262     if (NOT SPHINX_BREATHE_DEFAULT_PROJECT)
01263       set (SPHINX_BREATHE_DEFAULT_PROJECT "${TARGET}")
01264     endif ()
01265     list (APPEND SPHINX_DEPENDS ${UID})
01266   endforeach ()
01267   # LaTeX output options
01268   if (NOT SPHINX_LATEX_SHOW_URLS)
01269     set (SPHINX_LATEX_SHOW_URLS "no")
01270   endif ()
01271   if (SPHINX_LATEX_SHOW_PAGEREFS)
01272     set (SPHINX_LATEX_SHOW_PAGEREFS "True")
01273   else ()
01274     set (SPHINX_LATEX_SHOW_PAGEREFS "False")
01275   endif ()
01276   # turn html_logo and latex_logo into absolute file path
01277   foreach (L IN ITEMS HTML LATEX)
01278     if (SPHINX_${L}_LOGO AND NOT IS_ABSOLUTE "${SPHINX_${L}_LOGO}")
01279       if (EXISTS "${SPHINX_SOURCE_DIRECTORY}/${SPHINX_${L}_LOGO}")
01280         set (SPHINX_${L}_LOGO "${SPHINX_SOURCE_DIRECTORY}/${SPHINX_${L}_LOGO}")
01281       else ()
01282         foreach (D IN LISTS SPHINX_${L}_STATIC_PATH)
01283           string (REGEX REPLACE "^'|'$" "" D "${D}")
01284           if (EXISTS "${D}/${SPHINX_${L}_LOGO}")
01285             set (SPHINX_${L}_LOGO "${D}/${SPHINX_${L}_LOGO}")
01286             break ()
01287           endif ()
01288         endforeach ()
01289       endif ()
01290     endif ()
01291   endforeach ()
01292   # turn CMake lists into Python lists
01293   basis_list_to_delimited_string (SPHINX_EXTENSIONS         ", " NOAUTOQUOTE ${SPHINX_EXTENSIONS})
01294   basis_list_to_delimited_string (SPHINX_HTML_THEME_OPTIONS ", " NOAUTOQUOTE ${SPHINX_HTML_THEME_OPTIONS})
01295   basis_list_to_delimited_string (SPHINX_AUTHORS            ", " NOAUTOQUOTE ${SPHINX_AUTHORS})
01296   basis_list_to_delimited_string (SPHINX_DOXYLINK           ", " NOAUTOQUOTE ${SPHINX_DOXYLINK})
01297   basis_list_to_delimited_string (SPHINX_BREATHE_PROJECTS   ", " NOAUTOQUOTE ${SPHINX_BREATHE_PROJECTS})
01298   basis_list_to_delimited_string (SPHINX_HTML_SIDEBARS      ", " NOAUTOQUOTE ${SPHINX_HTML_SIDEBARS})
01299   basis_list_to_delimited_string (SPHINX_TEMPLATES_PATH     ", " NOAUTOQUOTE ${SPHINX_TEMPLATES_PATH})
01300   basis_list_to_delimited_string (SPHINX_HTML_STATIC_PATH   ", " NOAUTOQUOTE ${SPHINX_HTML_STATIC_PATH})
01301   basis_list_to_delimited_string (SPHINX_EXCLUDE_PATTERNS   ", " NOAUTOQUOTE ${SPHINX_EXCLUDE_PATTERNS})
01302   # configuration file
01303   if (NOT SPHINX_CONFIG_FILE)
01304     set (SPHINX_CONFIG_FILE "${BASIS_SPHINX_CONFIG}")
01305   endif ()
01306   get_filename_component (SPHINX_CONFIG_FILE "${SPHINX_CONFIG_FILE}" ABSOLUTE)
01307   if (EXISTS "${SPHINX_CONFIG_FILE}")
01308     configure_file ("${SPHINX_CONFIG_FILE}" "${SPHINX_CONFIG_DIRECTORY}/conf.py" @ONLY)
01309   elseif (EXISTS "${SPHINX_CONFIG_FILE}.in")
01310     configure_file ("${SPHINX_CONFIG_FILE}.in" "${SPHINX_CONFIG_DIRECTORY}/conf.py" @ONLY)
01311   else ()
01312     message (FATAL_ERROR "Missing Sphinx configuration file ${SPHINX_CONFIG_FILE}!")
01313   endif ()
01314   # add target to build documentation
01315   set (OPTIONS -a -N -n)
01316   if (NOT BASIS_VERBOSE)
01317     list (APPEND OPTIONS "-q")
01318   endif ()
01319   foreach (TAG IN LISTS SPHINX_TAG)
01320     list (APPEND OPTIONS "-t" "${TAG}")
01321   endforeach ()
01322   add_custom_target (${TARGET_UID}_all) # target to run all builders
01323   foreach (BUILDER IN LISTS SPHINX_BUILDERS)
01324     set (SPHINX_BUILDER "${BUILDER}")
01325     set (SPHINX_POST_COMMAND)
01326     if (BUILDER MATCHES "pdf|texinfo")
01327       if (BUILDER MATCHES "pdf")
01328         set (SPHINX_BUILDER "latex")
01329       endif ()
01330       set (SPHINX_POST_COMMAND COMMAND make -C "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}")
01331     endif ()
01332     if (Sphinx_PYTHON_EXECUTABLE)
01333       add_custom_target (
01334         ${TARGET_UID}_${BUILDER}
01335             "${Sphinx_PYTHON_EXECUTABLE}" ${Sphinx_PYTHON_OPTIONS}
01336                 "${Sphinx-build_EXECUTABLE}" ${OPTIONS}
01337                   -b ${SPHINX_BUILDER}
01338                   -c "${SPHINX_CONFIG_DIRECTORY}"
01339                   -d "${SPHINX_CONFIG_DIRECTORY}/doctrees"
01340                   "${SPHINX_SOURCE_DIRECTORY}"
01341                   "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}"
01342             ${SPHINX_POST_COMMAND}
01343             ${OPTDEPENDS}
01344         WORKING_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
01345         COMMENT "Building documentation ${TARGET_UID} (${BUILDER})..."
01346       )
01347     elseif (UNIX)
01348       add_custom_target (
01349         ${TARGET_UID}_${BUILDER}
01350             "${Sphinx-build_EXECUTABLE}" ${OPTIONS}
01351                   -b ${SPHINX_BUILDER}
01352                   -c "${SPHINX_CONFIG_DIRECTORY}"
01353                   -d "${SPHINX_CONFIG_DIRECTORY}/doctrees"
01354                   "${SPHINX_SOURCE_DIRECTORY}"
01355                   "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}"
01356             ${SPHINX_POST_COMMAND}
01357             ${OPTDEPENDS}
01358         WORKING_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
01359         COMMENT "Building documentation ${TARGET_UID} (${BUILDER})..."
01360       )
01361     else ()
01362       message (FATAL_ERROR "Python executable required to run Sphinx could not be determined by FindSphinx.cmake!"
01363                            " Set the advanced PYTHON_EXECUTABLE variable and try again.")
01364     endif ()
01365     if (SPHINX_DEPENDS)
01366       add_dependencies (${TARGET_UID}_${BUILDER} ${SPHINX_DEPENDS})
01367     endif ()
01368     add_dependencies (${TARGET_UID}_all ${TARGET_UID}_${BUILDER})
01369     # cleanup on "make clean"
01370     set_property (
01371       DIRECTORY
01372       APPEND PROPERTY
01373         ADDITIONAL_MAKE_CLEAN_FILES
01374           "${SPHINX_OUTPUT_DIRECTORY}"
01375     )
01376   endforeach ()
01377   # add general target which depends on default builder only
01378   if (BUILD_DOCUMENTATION AND BASIS_ALL_DOC)
01379     add_custom_target (${TARGET_UID} ALL)
01380   else ()
01381     add_custom_target (${TARGET_UID})
01382   endif ()
01383   add_dependencies (${TARGET_UID} ${TARGET_UID}_${SPHINX_DEFAULT_BUILDER})
01384   # add general "doc" target
01385   if (NOT SPHINX_EXCLUDE_FROM_DOC)
01386     if (NOT TARGET doc)
01387       add_custom_target (doc)
01388     endif ()
01389     add_dependencies (doc ${TARGET_UID}_${SPHINX_DEFAULT_BUILDER})
01390   endif ()
01391   # memorize important target properties
01392   set_target_properties (
01393     ${TARGET_UID}
01394     PROPERTIES
01395       BASIS_TYPE       Sphinx
01396       BUILDERS         "${SPHINX_BUILDERS}"
01397       SOURCE_DIRECTORY "${SPHINX_SOURCE_DIRECTORY}"
01398       OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}"
01399       CONFIG_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
01400   )
01401   foreach (b IN LISTS SPHINX_BUILDERS)
01402     string (TOUPPER ${b} B)
01403     set_target_properties (${TARGET_UID} PROPERTIES ${B}_INSTALL_DIRECTORY "${SPHINX_${B}_DESTINATION}")
01404   endforeach ()
01405   # cleanup on "make clean"
01406   set_property (
01407     DIRECTORY
01408     APPEND PROPERTY
01409       ADDITIONAL_MAKE_CLEAN_FILES
01410         "${SPHINX_CONFIG_DIRECTORY}/doctrees"
01411   )
01412   # install documentation
01413   install (
01414     CODE
01415       "
01416       set (HTML_DESTINATION    \"${SPHINX_HTML_DESTINATION}\")
01417       set (PDF_DESTINATION     \"${SPHINX_PDF_DESTINATION}\")
01418       set (LATEX_DESTINATION   \"${SPHINX_LATEX_DESTINATION}\")
01419       set (MAN_DESTINATION     \"${SPHINX_MAN_DESTINATION}\")
01420       set (TEXINFO_DESTINATION \"${SPHINX_TEXINFO_DESTINATION}\")
01421       set (TEXT_DESTINATION    \"${SPHINX_TEXT_DESTINATION}\")
01422 
01423       function (install_sphinx_doc BUILDER)
01424         if (BUILDER MATCHES \"pdf\")
01425           set (SPHINX_BUILDER \"latex\")
01426         else ()
01427           set (SPHINX_BUILDER \"\${BUILDER}\")
01428         endif ()
01429         string (TOUPPER \"\${BUILDER}\" BUILDER_U)
01430         set (CMAKE_INSTALL_PREFIX \"\${\${BUILDER_U}_DESTINATION}\")
01431         if (NOT CMAKE_INSTALL_PREFIX)
01432           return ()
01433         elseif (NOT IS_ABSOLUTE \"\${CMAKE_INSTALL_PREFIX}\")
01434           set (CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}/\${CMAKE_INSTALL_PREFIX}\")
01435         endif ()
01436         set (EXT)
01437         if (BUILDER MATCHES \"pdf\")
01438           set (EXT \".pdf\")
01439         elseif (BUILDER MATCHES \"man\")
01440           set (EXT \".?\")
01441         elseif (BUILDER MATCHES \"texinfo\")
01442           set (EXT \".info\")
01443         endif ()
01444         file (
01445           GLOB_RECURSE
01446             FILES
01447           RELATIVE \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}\"
01448             \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/*\${EXT}\"
01449         )
01450         foreach (F IN LISTS FILES)
01451           if (NOT F MATCHES \"\\\\.buildinfo\")
01452             set (RC 1)
01453             if (NOT BUILDER MATCHES \"texinfo\")
01454               execute_process (
01455                 COMMAND \"${CMAKE_COMMAND}\" -E compare_files
01456                     \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
01457                     \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
01458                 RESULT_VARIABLE RC
01459                 OUTPUT_QUIET
01460                 ERROR_QUIET
01461               )
01462             endif ()
01463             if (RC EQUAL 0)
01464               message (STATUS \"Up-to-date: \${CMAKE_INSTALL_PREFIX}/\${F}\")
01465             else ()
01466               message (STATUS \"Installing: \${CMAKE_INSTALL_PREFIX}/\${F}\")
01467               if (BUILDER MATCHES \"texinfo\")
01468                 if (EXISTS \"\${CMAKE_INSTALL_PREFIX}/dir\")
01469                   execute_process (
01470                     COMMAND install-info
01471                         \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
01472                         \"\${CMAKE_INSTALL_PREFIX}/dir\"
01473                     RESULT_VARIABLE RC
01474                     OUTPUT_QUIET
01475                     ERROR_QUIET
01476                   )
01477                 else ()
01478                   execute_process (
01479                     COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
01480                         \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
01481                         \"\${CMAKE_INSTALL_PREFIX}/dir\"
01482                     RESULT_VARIABLE RC
01483                     OUTPUT_QUIET
01484                     ERROR_QUIET
01485                   )
01486                 endif ()
01487               else ()
01488                 execute_process (
01489                   COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
01490                       \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
01491                       \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
01492                   RESULT_VARIABLE RC
01493                   OUTPUT_QUIET
01494                   ERROR_QUIET
01495                 )
01496               endif ()
01497               if (RC EQUAL 0)
01498                 # also remember .info files for deinstallation via install-info --delete
01499                 list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${F}\")
01500               else ()
01501                 message (STATUS \"Failed to install \${CMAKE_INSTALL_PREFIX}/\${F}\")
01502               endif ()
01503             endif ()
01504           endif ()
01505         endforeach ()
01506       endfunction ()
01507 
01508       set (BUILDERS \"${SPHINX_BUILDERS}\")
01509       set (HTML_INSTALLED FALSE)
01510       foreach (BUILDER IN LISTS BUILDERS)
01511         if ((BUILDER MATCHES \"html\" AND NOT HTML_INSTALLED) OR
01512               (BUILDER MATCHES \"texinfo|man\" AND UNIX) OR
01513               NOT BUILDER MATCHES \"html|texinfo|man|latex|linkcheck\")
01514           install_sphinx_doc (\${BUILDER})
01515           if (BUILDER MATCHES \"html\")
01516             set (HTML_INSTALLED TRUE)
01517           endif ()
01518         endif ()
01519       endforeach ()
01520       "
01521   )
01522   # done
01523   message (STATUS "Adding documentation ${TARGET_UID}... - done")
01524 endfunction ()
01525 
01526 # ============================================================================
01527 # change log
01528 # ============================================================================
01529 
01530 # ----------------------------------------------------------------------------
01531 ## @brief Add target for generation of ChangeLog file.
01532 #
01533 # The ChangeLog is either generated from the Subversion or Git log depending
01534 # on which revision control system is used by the project. Moreover, the
01535 # project's source directory must be either a Subversion working copy or
01536 # the root of a Git repository, respectively. In case of Subversion, if the
01537 # command-line tool svn2cl(.sh) is installed, it is used to output a nicer
01538 # formatted change log.
01539 function (basis_add_changelog)
01540   basis_make_target_uid (TARGET_UID changelog)
01541 
01542   option (BUILD_CHANGELOG "Request build and/or installation of the ChangeLog." OFF)
01543   mark_as_advanced (BUILD_CHANGELOG)
01544   set (CHANGELOG_FILE "${PROJECT_BINARY_DIR}/ChangeLog")
01545 
01546   message (STATUS "Adding ChangeLog...")
01547 
01548   if (NOT PROJECT_IS_MODULE AND BUILD_CHANGELOG)
01549     set (_ALL "ALL")
01550   else ()
01551     set (_ALL)
01552   endif ()
01553 
01554   set (DISABLE_BUILD_CHANGELOG FALSE)
01555 
01556   # --------------------------------------------------------------------------
01557   # generate ChangeLog from Subversion history
01558   if (EXISTS "${PROJECT_SOURCE_DIR}/.svn")
01559     find_package (Subversion QUIET)
01560     if (Subversion_FOUND)
01561 
01562       if (_ALL)
01563         message ("Generation of ChangeLog enabled as part of ALL."
01564                  " Be aware that the ChangeLog generation from the Subversion"
01565                  " commit history can take several minutes and may require the"
01566                  " input of your Subversion repository credentials during the"
01567                  " build. If you would like to build the ChangeLog separate"
01568                  " from the rest of the software package, disable the option"
01569                  " BUILD_CHANGELOG. You can then build the changelog target"
01570                  " separate from ALL.")
01571       endif ()
01572 
01573       # using svn2cl command
01574       find_program (
01575         SVN2CL_EXECUTABLE
01576           NAMES svn2cl svn2cl.sh
01577           DOC   "The command line tool svn2cl."
01578       )
01579       mark_as_advanced (SVN2CL_EXECUTABLE)
01580       if (SVN2CL_EXECUTABLE)
01581         add_custom_target (
01582           ${TARGET_UID} ${_ALL}
01583           COMMAND "${SVN2CL_EXECUTABLE}"
01584               "--output=${CHANGELOG_FILE}"
01585               "--linelen=79"
01586               "--reparagraph"
01587               "--group-by-day"
01588               "--include-actions"
01589               "--separate-daylogs"
01590               "${PROJECT_SOURCE_DIR}"
01591           COMMAND "${CMAKE_COMMAND}"
01592               "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN2CL
01593               -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
01594           WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
01595           COMMENT "Generating ChangeLog from Subversion log (using svn2cl)..."
01596         )
01597       # otherwise, use svn log output directly
01598       else ()
01599         add_custom_target (
01600           ${TARGET_UID} ${_ALL}
01601           COMMAND "${CMAKE_COMMAND}"
01602               "-DCOMMAND=${Subversion_SVN_EXECUTABLE};log"
01603               "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
01604               "-DOUTPUT_FILE=${CHANGELOG_FILE}"
01605               -P "${BASIS_SCRIPT_EXECUTE_PROCESS}"
01606           COMMAND "${CMAKE_COMMAND}"
01607               "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN
01608               -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
01609           COMMENT "Generating ChangeLog from Subversion log..."
01610           VERBATIM
01611         )
01612       endif ()
01613 
01614     else ()
01615       if (BASIS_VERBOSE)
01616         message (STATUS "Project is SVN working copy but Subversion executable was not found."
01617                         " Generation of ChangeLog disabled.")
01618       endif ()
01619       set (DISABLE_BUILD_CHANGELOG TRUE)
01620     endif ()
01621 
01622   # --------------------------------------------------------------------------
01623   # generate ChangeLog from Git log
01624   elseif (EXISTS "${PROJECT_SOURCE_DIR}/.git")
01625     find_package (Git QUIET)
01626     if (GIT_FOUND)
01627 
01628       add_custom_target (
01629         ${TARGET_UID} ${_ALL}
01630         COMMAND "${CMAKE_COMMAND}"
01631             "-DCOMMAND=${GIT_EXECUTABLE};log;--date-order;--date=short;--pretty=format:%ad\ \ %an%n%n%w(79,8,10)* %s%n%n%b%n"
01632             "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
01633             "-DOUTPUT_FILE=${CHANGELOG_FILE}"
01634             -P "${BASIS_SCRIPT_EXECUTE_PROCESS}"
01635         COMMAND "${CMAKE_COMMAND}"
01636             "-DCHANGELOG_FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=GIT
01637             -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
01638         COMMENT "Generating ChangeLog from Git log..."
01639         VERBATIM
01640       )
01641 
01642     else ()
01643       if (BASIS_VERBOSE)
01644         message (STATUS "Project is Git repository but Git executable was not found."
01645                         " Generation of ChangeLog disabled.")
01646       endif ()
01647       set (DISABLE_BUILD_CHANGELOG TRUE)
01648     endif ()
01649 
01650   # --------------------------------------------------------------------------
01651   # neither SVN nor Git repository
01652   else ()
01653     if (BASIS_VERBOSE)
01654       message (STATUS "Project source directory ${PROJECT_SOURCE_DIR} is neither"
01655                       " SVN working copy nor Git repository. Generation of ChangeLog disabled.")
01656     endif ()
01657     set (DISABLE_BUILD_CHANGELOG TRUE)
01658   endif ()
01659 
01660   # --------------------------------------------------------------------------
01661   # disable changelog target
01662   if (DISABLE_BUILD_CHANGELOG)
01663     set (BUILD_CHANGELOG OFF CACHE INTERNAL "" FORCE)
01664     message (STATUS "Adding ChangeLog... - skipped")
01665     return ()
01666   endif ()
01667 
01668   # --------------------------------------------------------------------------
01669   # cleanup on "make clean"
01670   set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CHANGELOG_FILE}")
01671 
01672   # --------------------------------------------------------------------------
01673   # install ChangeLog
01674   get_filename_component (CHANGELOG_NAME "${CHANGELOG_FILE}" NAME)
01675   if (PROJECT_IS_MODULE)
01676     set (CHANGELOG_NAME "${CHANGELOG_NAME}-${PROJECT_NAME}")
01677   endif ()
01678 
01679   install (
01680     FILES       "${CHANGELOG_FILE}"
01681     DESTINATION "${BASIS_INSTALL_DOC_DIR}"
01682     COMPONENT   "${BASIS_RUNTIME_COMPONENT}"
01683     RENAME      "${CHANGELOG_NAME}"
01684     OPTIONAL
01685   )
01686 
01687   message (STATUS "Adding ChangeLog... - done")
01688 endfunction ()