DocTools.cmake
Go to the documentation of this file.
1 # ============================================================================
2 # Copyright (c) 2011-2012 University of Pennsylvania
3 # Copyright (c) 2013-2014 Carnegie Mellon University
4 # Copyright (c) 2013-2016 Andreas Schuh
5 # All rights reserved.
6 #
7 # See COPYING file for license information or visit
8 # https://cmake-basis.github.io/download.html#license
9 # ============================================================================
10 
11 ##############################################################################
12 # @file DocTools.cmake
13 # @brief Tools related to gnerating or adding software documentation.
14 #
15 # @ingroup CMakeTools
16 ##############################################################################
17 
19  return ()
20 else ()
22 endif ()
23 
24 
25 # ============================================================================
26 # adding / generating documentation
27 # ============================================================================
28 
29 # ----------------------------------------------------------------------------
30 ## @brief Add documentation target.
31 #
32 # This function is used to add a software documentation files to the project
33 # which are either just copied to the installation or generated from input
34 # files such as in particular source code files and documentation files
35 # marked up using one of the supported lightweight markup languages.
36 #
37 # The supported generators are:
38 # <table border="0">
39 # <tr>
40 # @tp @b None @endtp
41 # <td>This generator simply installs the given file or all files within
42 # the specified directory.</td>
43 # </tr>
44 # <tr>
45 # @tp @b Doxygen @endtp
46 # <td>Used to generate API documentation from in-source code comments and
47 # other related files marked up using Doxygen comments. See
48 # basis_add_doxygen_doc() for more details.</td>
49 # </tr>
50 # <tr>
51 # @tp @b Sphinx @endtp
52 # <td>Used to generate documentation such as a web site from reStructuredText.
53 # See basis_add_sphinx_doc() for more details.</td>
54 # </tr>
55 # </table>
56 #
57 # @param [in] TARGET_NAME Name of the documentation target or file.
58 # @param [in] ARGN Documentation generator as "GENERATOR generator" option
59 # and additional arguments for the particular generator.
60 # The case of the generator name is ignored, i.e.,
61 # @c Doxygen, @c DOXYGEN, @c doxYgen are all valid arguments
62 # which select the @c Doxygen generator. The default generator
63 # is the @c None generator.</td>
64 #
65 # @returns Adds a custom target @p TARGET_NAME for the generation of the
66 # documentation.
67 #
68 # @sa basis_install_doc()
69 # @sa basis_add_doxygen_doc()
70 # @sa basis_add_sphinx_doc()
71 #
72 # @ingroup CMakeAPI
73 function (basis_add_doc TARGET_NAME)
74  CMAKE_PARSE_ARGUMENTS (ARGN "" "GENERATOR" "" ${ARGN})
75  if (NOT ARGN_GENERATOR)
76  set (ARGN_GENERATOR "NONE")
77  else ()
78  string (TOUPPER "${ARGN_GENERATOR}" ARGN_GENERATOR)
79  endif ()
80  if (ARGN_GENERATOR MATCHES "NONE")
81  basis_install_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
82  elseif (ARGN_GENERATOR MATCHES "DOXYGEN")
83  basis_add_doxygen_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
84  elseif (ARGN_GENERATOR MATCHES "SPHINX")
85  basis_add_sphinx_doc (${TARGET_NAME} ${ARGN_UNPARSED_ARGUMENTS})
86  else ()
87  message (FATAL_ERROR "Unknown documentation generator: ${ARGN_GENERATOR}.")
88  endif ()
89 endfunction ()
90 
91 # ----------------------------------------------------------------------------
92 ## @brief Install documentation file(s).
93 #
94 # This function either adds an installation rule for a single documentation
95 # file or a directory containing multiple documentation files.
96 #
97 # Example:
98 # @code
99 # basis_install_doc ("User Manual.pdf" OUTPUT_NAME "BASIS User Manual.pdf")
100 # basis_install_doc (DeveloperManual.docx COMPONENT dev)
101 # basis_install_doc (SourceManual.html COMPONENT src)
102 # @endcode
103 #
104 # @param [in] SOURCE Documentation file or directory to install.
105 # @param [in] ARGN List of optional arguments. Valid arguments are:
106 # @par
107 # <table border="0">
108 # <tr>
109 # @tp @b COMPONENT component @endtp
110 # <td>Name of the component this documentation belongs to.
111 # Defaults to @c BASIS_RUNTIME_COMPONENT.</td>
112 # </tr>
113 # <tr>
114 # @tp @b DESTINATION dir @endtp
115 # <td>Installation directory prefix. Defaults to @c INSTALL_DOC_DIR.</td>
116 # </tr>
117 # <tr>
118 # @tp @b OUTPUT_NAME name @endtp
119 # <td>Name of file or directory after installation.</td>
120 # </tr>
121 # </table>
122 #
123 # @sa basis_add_doc()
124 function (basis_install_doc SOURCE)
125  CMAKE_PARSE_ARGUMENTS (ARGN "" "COMPONENT;DESTINATION;OUTPUT_NAME" "" ${ARGN})
126 
127  if (NOT IS_ABSOLUTE "${SOURCE}")
128  get_filename_component (SOURCE "${SOURCE}" ABSOLUTE)
129  endif ()
130  if (NOT ARGN_DESTINATION)
131  set (ARGN_DESTINATION "${INSTALL_DOC_DIR}")
132  endif ()
133  if (NOT ARGN_COMPONENT)
134  set (ARGN_COMPONENT "${BASIS_RUNTIME_COMPONENT}")
135  endif ()
136  if (NOT ARGN_COMPONENT)
137  set (ARGN_COMPONENT "Unspecified")
138  endif ()
139  if (NOT ARGN_OUTPUT_NAME)
140  basis_get_filename_component (ARGN_OUTPUT_NAME "${SOURCE}" NAME)
141  endif ()
142 
144  RELPATH
145  "${CMAKE_SOURCE_DIR}"
146  "${CMAKE_CURRENT_SOURCE_DIR}/${ARGN_OUTPUT_NAME}"
147  )
148 
149  message (STATUS "Adding documentation ${RELPATH}...")
150 
151  if (IS_DIRECTORY "${SOURCE}")
153  "${SOURCE}" "${ARGN_DESTINATION}/${ARGN_OUTPUT_NAME}"
154  COMPONENT "${ARGN_COMPONENT}"
155  )
156  else ()
157  install (
158  FILES "${SOURCE}"
159  DESTINATION "${ARGN_DESTINATION}"
160  COMPONENT "${ARGN_COMPONENT}"
161  RENAME "${ARGN_OUTPUT_NAME}"
162  )
163  endif ()
164 
165  message (STATUS "Adding documentation ${RELPATH}... - done")
166 endfunction ()
167 
168 # ----------------------------------------------------------------------------
169 ## @brief Add documentation to be generated by Doxygen.
170 #
171 # This function adds a build target to generate documentation from in-source
172 # code comments and other related project pages using
173 # <a href="http://www.stack.nl/~dimitri/doxygen/index.html">Doxygen</a>.
174 #
175 # @param [in] TARGET_NAME Name of the documentation target.
176 # @param [in] ARGN List of arguments. The valid arguments are:
177 # @par
178 # <table border="0">
179 # <tr>
180 # @tp @b EXCLUDE_FROM_DOC @endtp
181 # <td>By default, the specified target is build as part of the global
182 # @c doc target. If this option is given, however, the added
183 # documentation will not be build as part of this target.</td>
184 # </tr>
185 # <tr>
186 # @tp @b COMPONENT component @endtp
187 # <td>Name of the component this documentation belongs to.
188 # Defaults to @c BASIS_LIBRARY_COMPONENT.</td>
189 # </tr>
190 # <tr>
191 # @tp @b DESTINATION dir @endtp
192 # <td>Installation directory prefix. Defaults to
193 # @c BASIS_INSTALL_&ltTARGET&gt;_DIR in case of HTML output if set.
194 # Otherwise, the generated HTML files are not installed.</td>
195 # </tr>
196 # <tr>
197 # @tp @b DOXYFILE file @endtp
198 # <td>Name of the template Doxyfile.</td>
199 # </tr>
200 # <tr>
201 # @tp @b PROJECT_NAME name @endtp
202 # <td>Value for Doxygen's @c PROJECT_NAME tag which is used to
203 # specify the project name.@n
204 # Default: @c PROJECT_NAME.</td>
205 # </tr>
206 # <tr>
207 # @tp @b PROJECT_NUMBER version @endtp
208 # <td>Value for Doxygen's @c PROJECT_NUMBER tag which is used
209 # to specify the project version number.@n
210 # Default: @c PROJECT_RELEASE.</td>
211 # </tr>
212 # <tr>
213 # @tp @b PROJECT_WEBSITE url @endtp
214 # <td>Used for links to project website.@n
215 # Default: @c PROJECT_PACKAGE_WEBSITE </td>
216 # </tr>
217 # <tr>
218 # @tp @b INPUT path1 [path2 ...] @endtp
219 # <td>Value for Doxygen's @c INPUT tag which is used to specify input
220 # directories/files. Any given input path is added to the default
221 # input paths.@n
222 # Default: @c PROJECT_CODE_DIRS, @c BINARY_CODE_DIR,
223 # @c PROJECT_INCLUDE_DIRS, @c BINARY_INCLUDE_DIR.</td>
224 # </tr>
225 # <tr>
226 # @tp @b EXCLUDE_BASIS_MODULES @endtp
227 # <td>Do not add project CMake files used and generated by BASIS to @b INPUT.</td>
228 # </tr>
229 # <tr>
230 # @tp @b EXCLUDE_BASIS_UTILITIES @endtp
231 # <td>Do not add documentation (.dox) files for used CMake BASIS Utilities to @b INPUT.</td>
232 # </tr>
233 # <tr>
234 # @tp @b INPUT_FILTER filter @endtp
235 # <td>
236 # Value for Doxygen's @c INPUT_FILTER tag which can be used to
237 # specify a default filter for all input files.@n
238 # Default: @c doxyfilter of BASIS.
239 # </td>
240 # </tr>
241 # <tr>
242 # @tp @b FILTER_PATTERNS pattern1 [pattern2...] @endtp
243 # <td>Value for Doxygen's @c FILTER_PATTERNS tag which can be used to
244 # specify filters on a per file pattern basis.@n
245 # Default: None.</td>
246 # </tr>
247 # <tr>
248 # @tp @b INCLUDE_PATH path1 [path2...] @endtp
249 # <td>Doxygen's @c INCLUDE_PATH tag can be used to specify one or more
250 # directories that contain include files that are not input files
251 # but should be processed by the preprocessor. Any given directories
252 # are appended to the default include path considered.
253 # Default: Directories added by basis_include_directories().</td>
254 # </tr>
255 # <tr>
256 # @tp @b EXCLUDE_PATTERNS pattern1 [pattern2 ...] @endtp
257 # <td>Additional patterns used for Doxygen's @c EXCLUDE_PATTERNS tag
258 # which can be used to specify files and/or directories that
259 # should be excluded from the INPUT source files.@n
260 # Default: No exclude patterns.</td>
261 # </tr>
262 # <tr>
263 # @tp @b PREDEFINED name1|name1=value1 [name2|name2=value2...] @endtp
264 # <td>Add preprocessor definitions to be expanded by Doxygen.</td>
265 # </tr>
266 # <tr>
267 # @tp @b OUTPUT fmt @endtp
268 # <td>Specify output formats in which to generate the documentation.
269 # Currently, only @c html and @c xml are supported.</td>
270 # </tr>
271 # <tr>
272 # @tp @b OUTPUT_DIRECTORY dir @endtp
273 # <td>Value for Doxygen's @c OUTPUT_DIRECTORY tag which can be used to
274 # specify the output directory. The output files are written to
275 # subdirectories named "html", "latex", "rtf", and "man".@n
276 # Default: <tt>CMAKE_CURRENT_BINARY_DIR/TARGET_NAME</tt>.</td>
277 # </tr>
278 # <tr>
279 # @tp @b COLS_IN_ALPHA_INDEX n @endtp
280 # <td>Number of columns in alphabetical index. Default: 3.</td>
281 # </tr>
282 # <tr>
283 # @tp @b IGNORE_PREFIX prefix1 [prefix2...] @endtp
284 # <td>In case all classes in a project start with a common prefix, all
285 # classes will be put under the same header in the alphabetical index.
286 # The IGNORE_PREFIX tag can be used to specify one or more prefixes that
287 # should be ignored while generating the index headers.</td>
288 # </tr>
289 # <tr>
290 # @tp @b PROVIDER_NAME name @endtp
291 # <td>Value for provider name, such as a company name,
292 # that will be used for pages in the doxygen output.@n
293 # Default: @c PROJECT_PROVIDER_NAME.</td>
294 # </tr>
295 # <tr>
296 # @tp @b PROVIDER_WEBSITE url @endtp
297 # <td>Value for provider website, such as a company website,
298 # that will be used for pages in the doxygen output.@n
299 # Default: @c PROJECT_PROVIDER_WEBSITE.</td>
300 # </tr>
301 # <tr>
302 # @tp @b PROVIDER_LOGO image_file @endtp
303 # <td>Value for provider logo file, such as a company logo,
304 # that will be used for pages in the doxygen output.@n
305 # Default: @c PROJECT_PROVIDER_LOGO.</td>
306 # </tr>
307 # <tr>
308 # @tp @b DIVISION_NAME name @endtp
309 # <td>Value for division name, such as a company division name,
310 # that will be used for pages in the doxygen output.@n
311 # Default: @c PROJECT_DIVISION_NAME.</td>
312 # </tr>
313 # <tr>
314 # @tp @b DIVISION_WEBSITE url @endtp
315 # <td>Value for division website, such as a company division website,
316 # that will be used for pages in the doxygen output.@n
317 # Default: @c PROJECT_DIVISION_WEBSITE.</td>
318 # </tr>
319 # <tr>
320 # @tp @b DIVISION_LOGO image_file @endtp
321 # <td>Value for division logo file, such as a company division logo,
322 # that will be used for pages in the doxygen output.@n
323 # Default: @c PROJECT_DIVISION_LOGO.</td>
324 # </tr>
325 # <tr>
326 # @tp @b ENABLED_SECTIONS section1 [section2 ...] @endtp
327 # <td>The ENABLED_SECTIONS tag can be used to enable conditional
328 # documentation sections, marked by "\if sectionname ... \endif".</td>
329 # </tr>
330 # <tr>
331 # @tp @b HTML_HEADER html_file @endtp
332 # <td>The HTML_HEADER tag can be used to specify a personal HTML header for
333 # each generated HTML page. If none specified, the
334 # @c "PROJECT_SOURCE_DIR/doc/doxygen_header.html(.in)?" file is used if present.
335 # Otherwise, a default header is used. Specify the value @c Doxygen to use the
336 # standard header generated by Doxygen instead.</td>
337 # </tr>
338 # <tr>
339 # @tp @b HTML_FOOTER html_file @endtp
340 # <td>The HTML_FOOTER tag can be used to specify a personal HTML footer for
341 # each generated HTML page. If none specified, the
342 # @c "PROJECT_SOURCE_DIR/doc/doxygen_footer.html(.in)?" file is used if present.
343 # Otherwise, a default footer is used. Specify the value @c Doxygen to use the
344 # standard footer generated by Doxygen instead.</td>
345 # </tr>
346 # <tr>
347 # @tp @b HTML_EXTRA_STYLESHEET css_file @endtp
348 # <td>The HTML_EXTRA_STYLESHEET tag can be used to specify a user-defined cascading
349 # style sheet that is used by each HTML page. It can be used to
350 # fine-tune the look of the HTML output. If none specified, the
351 # @c "PROJECT_SOURCE_DIR/doc/doxygen_extra.css(.in)?" file is used if present.</td>
352 # </tr>
353 # <tr>
354 # @tp @b HTML_EXTRA_FILES file1 [file2...] @endtp
355 # <td>The HTML_EXTRA_FILES tag can be used to specify additional files needed
356 # for the HTML output of the API documentation.</td>
357 # </tr>
358 # <tr>
359 # @tp @b DISABLE_PROJECT_NAME_DISPLAY@endtp
360 # <td>The DISABLE_PROJECT_NAME_DISPLAY option causes Doxygen's
361 # @c PROJECT_NAME text not to be displayed in the header.
362 # Use this if the project name is already part of the logo
363 # so it won't be there twice in the logo image and title text.</td>
364 # </tr>
365 # </table>
366 # @n
367 # See <a href="http://www.stack.nl/~dimitri/doxygen/manual/config.html">here</a> for a
368 # documentation of the Doxygen tags.
369 # @n@n
370 # Example:
371 # @code
372 # basis_add_doxygen_doc (
373 # apidoc
374 # DOXYFILE "Doxyfile.in"
375 # PROJECT_NAME "${PROJECT_NAME}"
376 # PROJECT_VERSION "${PROJECT_VERSION}"
377 # COMPONENT dev
378 # )
379 # @endcode
380 #
381 # @sa basis_add_doc()
382 function (basis_add_doxygen_doc TARGET_NAME)
383  # check target name
384  basis_check_target_name ("${TARGET_NAME}")
385  basis_make_target_uid (TARGET_UID "${TARGET_NAME}")
386  string (TOLOWER "${TARGET_NAME}" TARGET_NAME_L)
387  string (TOUPPER "${TARGET_NAME}" TARGET_NAME_U)
388  # verbose output
389  message (STATUS "Adding documentation ${TARGET_UID}...")
390  # find Doxygen
391  find_package (Doxygen QUIET)
392  if (NOT DOXYGEN_EXECUTABLE)
394  message (FATAL_ERROR "Doxygen not found! Either install Doxygen and/or set DOXYGEN_EXECUTABLE or disable BUILD_DOCUMENTATION.")
395  endif ()
396  message (STATUS "Doxygen not found. Generation of ${TARGET_UID} documentation disabled.")
397  message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
398  return ()
399  endif ()
400  # parse arguments
401  set (VALUEARGS
402  PROJECT_NAME
403  PROJECT_NUMBER
404  PROJECT_WEBSITE
405  PROVIDER_NAME
406  PROVIDER_WEBSITE
407  DIVISION_NAME
408  DIVISION_WEBSITE
409  COMPONENT
410  DESTINATION
411  HTML_DESTINATION
412  MAN_DESTINATION
413  OUTPUT_DIRECTORY
414  COLS_IN_ALPHA_INDEX
415  MAN_SECTION
416  )
417  set (OPTIONAL_FILE_OPTIONS
418  HTML_FOOTER
419  HTML_HEADER
420  HTML_EXTRA_STYLESHEET
421  PROJECT_LOGO
422  PROVIDER_LOGO
423  DIVISION_LOGO
424  DOXYFILE
425  TAGFILE
426  )
427  CMAKE_PARSE_ARGUMENTS (
428  DOXYGEN
429  "EXCLUDE_FROM_DOC;DISABLE_PROJECT_NAME_DISPLAY;EXCLUDE_BASIS_MODULES;EXCLUDE_BASIS_UTILITIES"
430  "${VALUEARGS};${OPTIONAL_FILE_OPTIONS}"
431  "INPUT;OUTPUT;INPUT_FILTER;FILTER_PATTERNS;EXCLUDE_PATTERNS;INCLUDE_PATH;IGNORE_PREFIX;ENABLED_SECTIONS;PREDEFINED;HTML_EXTRA_FILES"
432  ${ARGN}
433  )
434  unset (VALUEARGS)
435  # handle special arguments
436  set (DOXYGEN_HTML_HEADER_IS_DEFAULT FALSE)
437  if (DOXYGEN_HTML_HEADER MATCHES "^(Doxygen|doxygen|DOXYGEN|none|None|NONE)$")
438  set (DOXYGEN_HTML_HEADER)
439  elseif (NOT DOXYGEN_HTML_HEADER OR DOXYGEN_HTML_HEADER MATCHES "^(Default|default|DEFAULT)$")
440  set (DOXYGEN_HTML_HEADER "${BASIS_MODULE_PATH}/doxygen_header.html.in")
441  set (DOXYGEN_HTML_HEADER_IS_DEFAULT TRUE)
442  endif ()
443  if (DOXYGEN_HTML_FOOTER MATCHES "^(Doxygen|doxygen|DOXYGEN|none|None|NONE)$")
444  set (DOXYGEN_HTML_FOOTER)
445  elseif (NOT DOXYGEN_HTML_FOOTER OR DOXYGEN_HTML_FOOTER MATCHES "^(Default|default|DEFAULT)$")
446  set (DOXYGEN_HTML_FOOTER "${BASIS_MODULE_PATH}/doxygen_footer.html.in")
447  endif ()
448  # make file paths absolute and check if files exist
449  foreach (opt IN LISTS OPTIONAL_FILE_OPTIONS)
450  if (DOXYGEN_${opt})
451  get_filename_component (DOXYGEN_${opt} "${DOXYGEN_${opt}}" ABSOLUTE)
452  if (NOT EXISTS "${DOXYGEN_${opt}}")
453  message (FATAL_ERROR "File ${DOXYGEN_${opt}} does not exist. Check value of the ${opt} option and make sure the file is present.")
454  endif ()
455  endif ()
456  endforeach ()
457  set (TMP_DOXYGEN_HTML_EXTRA_FILES)
458  foreach (path IN LISTS DOXYGEN_HTML_EXTRA_FILES)
459  get_filename_component (abspath "${path}" ABSOLUTE)
460  if (NOT EXISTS "${path}")
461  message (FATAL_ERROR "File ${path} does not exist. Check value of the HTML_EXTRA_FILES option and make sure the file is present.")
462  endif ()
463  list (APPEND TMP_DOXYGEN_HTML_EXTRA_FILES "${path}")
464  endforeach ()
465  set (DOXYGEN_HTML_EXTRA_FILES "${TMP_DOXYGEN_HTML_EXTRA_FILES}")
466  unset (TMP_DOXYGEN_HTML_EXTRA_FILES)
467  # default component
468  if (NOT DOXYGEN_COMPONENT)
469  set (DOXYGEN_COMPONENT "${BASIS_LIBRARY_COMPONENT}")
470  endif ()
471  if (NOT DOXYGEN_COMPONENT)
472  set (DOXYGEN_COMPONENT "Unspecified")
473  endif ()
474  # configuration file
475  if (NOT DOXYGEN_DOXYFILE)
476  set (DOXYGEN_DOXYFILE "${BASIS_DOXYGEN_DOXYFILE}")
477  endif ()
478  if (NOT EXISTS "${DOXYGEN_DOXYFILE}")
479  message (FATAL_ERROR "Missing option DOXYGEN_FILE or Doxyfile ${DOXYGEN_DOXYFILE} does not exist.")
480  endif ()
481  # default project attributes and logos
482  if (NOT DOXYGEN_PROJECT_NAME)
483  set (DOXYGEN_PROJECT_NAME "${PROJECT_NAME}")
484  endif ()
485  if (NOT DOXYGEN_PROJECT_NUMBER)
486  set (DOXYGEN_PROJECT_NUMBER "${PROJECT_RELEASE}")
487  endif ()
488  if (NOT DOXYGEN_PROJECT_LOGO)
489  set (DOXYGEN_PROJECT_LOGO "${PROJECT_PACKAGE_LOGO}")
490  elseif (DOXYGEN_PROJECT_LOGO MATCHES "^None|none|NONE$")
491  set (DOXYGEN_PROJECT_LOGO)
492  endif ()
493  if (NOT DOXYGEN_PROJECT_WEBSITE)
494  set (DOXYGEN_PROJECT_WEBSITE "${PROJECT_PACKAGE_WEBSITE}")
495  endif ()
496  if (NOT DOXYGEN_PROVIDER_NAME)
497  set (DOXYGEN_PROVIDER_NAME "${PROJECT_PROVIDER_NAME}")
498  endif ()
499  if (NOT DOXYGEN_PROVIDER_WEBSITE)
500  set (DOXYGEN_PROVIDER_WEBSITE "${PROJECT_PROVIDER_WEBSITE}")
501  endif ()
502  if (NOT DOXYGEN_PROVIDER_LOGO)
503  set (DOXYGEN_PROVIDER_LOGO "${PROJECT_PROVIDER_LOGO}")
504  endif ()
505  if (NOT DOXYGEN_DIVISION_NAME)
506  set (DOXYGEN_DIVISION_NAME "${PROJECT_DIVISION_NAME}")
507  endif ()
508  if (NOT DOXYGEN_DIVISION_WEBSITE)
509  set (DOXYGEN_DIVISION_WEBSITE "${PROJECT_DIVISION_WEBSITE}")
510  endif ()
511  if (NOT DOXYGEN_DIVISION_LOGO)
512  set (DOXYGEN_DIVISION_LOGO "${PROJECT_DIVISION_LOGO}")
513  endif ()
514  # set visibility property of project logos
515  if (DOXYGEN_PROJECT_LOGO)
516  set (DOXYGEN_PROJECT_LOGO_DISPLAY "block")
517  else ()
518  set (DOXYGEN_PROJECT_LOGO_DISPLAY "none")
519  endif ()
520  if (DOXYGEN_PROVIDER_LOGO)
521  set (DOXYGEN_PROVIDER_LOGO_DISPLAY "inline")
522  else ()
523  set (DOXYGEN_PROVIDER_LOGO_DISPLAY "block")
524  endif ()
525  if (DOXYGEN_DIVISION_LOGO)
526  set (DOXYGEN_DIVISION_LOGO_DISPLAY "inline")
527  else ()
528  set (DOXYGEN_DIVISION_LOGO_DISPLAY "block")
529  endif ()
530  # allow the user to disable the text header if desired
531  if(DOXYGEN_DISABLE_PROJECT_NAME_DISPLAY)
532  set (DOXYGEN_PROJECT_NAME_DISPLAY "none")
533  else()
534  set (DOXYGEN_PROJECT_NAME_DISPLAY "inline")
535  endif()
536  # standard input files
537  if (NOT EXCLUDE_BASIS_MODULES)
538  list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/BasisProject.cmake")
539  if (EXISTS "${PROJECT_CONFIG_DIR}/Depends.cmake")
540  list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Depends.cmake")
541  endif ()
542  if (EXISTS "${BINARY_CONFIG_DIR}/Directories.cmake")
543  list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/Directories.cmake")
544  endif ()
545  if (EXISTS "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
546  list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/BasisSettings.cmake")
547  endif ()
548  if (EXISTS "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
549  list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ProjectSettings.cmake")
550  endif ()
551  if (EXISTS "${BINARY_CONFIG_DIR}/Settings.cmake")
552  list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/Settings.cmake")
553  elseif (EXISTS "${PROJECT_CONFIG_DIR}/Settings.cmake")
554  list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/Settings.cmake")
555  endif ()
556  if (EXISTS "${BASIS_SCRIPT_CONFIG_FILE}")
557  list (APPEND DOXYGEN_INPUT "${BASIS_SCRIPT_CONFIG_FILE}")
558  endif ()
559  if (EXISTS "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
560  list (APPEND DOXYGEN_INPUT "${BINARY_CONFIG_DIR}/ScriptConfig.cmake")
561  endif ()
562  if (EXISTS "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
563  list (APPEND DOXYGEN_INPUT "${PROJECT_CONFIG_DIR}/ConfigSettings.cmake")
564  endif ()
565  if (EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
566  list (APPEND DOXYGEN_INPUT "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
567  endif ()
568  if (EXISTS "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
569  list (APPEND DOXYGEN_INPUT "${PROJECT_BINARY_DIR}/CTestCustom.cmake")
570  endif ()
571  # package configuration files - only exist *after* this function executed
572  list (APPEND DOXYGEN_INPUT "${BINARY_LIBCONF_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}Config.cmake")
573  list (APPEND DOXYGEN_INPUT "${BINARY_LIBCONF_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}ConfigVersion.cmake")
574  list (APPEND DOXYGEN_INPUT "${BINARY_LIBCONF_DIR}/${PROJECT_PACKAGE_CONFIG_PREFIX}Use.cmake")
575  # add .dox files with definition of BASIS Modules groups
576  if (BASIS_DIR)
577  list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Modules.dox")
578  endif ()
579  endif ()
580  # input directories
581  foreach (_DIR IN LISTS BINARY_INCLUDE_DIR PROJECT_INCLUDE_DIRS BINARY_CODE_DIR PROJECT_CODE_DIRS)
582  if (IS_DIRECTORY ${_DIR})
583  list (APPEND DOXYGEN_INPUT "${_DIR}")
584  endif ()
585  endforeach ()
586  foreach (M IN LISTS PROJECT_MODULES_ENABLED)
587  foreach (_DIR IN LISTS ${M}_INCLUDE_DIRS ${M}_CODE_DIRS)
588  if (IS_DIRECTORY ${_DIR})
589  list (APPEND DOXYGEN_INPUT "${_DIR}")
590  endif ()
591  endforeach ()
592  endforeach ()
593  # in case of scripts, have Doxygen process the configured versions for the
594  # installation which are further located in proper subdirectories instead
595  # of the original source files
597  foreach (T IN LISTS TARGETS)
598  get_target_property (BASIS_TYPE ${T} BASIS_TYPE)
599  get_target_property (IS_TEST ${T} TEST)
600  if (NOT IS_TEST AND BASIS_TYPE MATCHES "SCRIPT")
601  get_target_property (SOURCES ${T} SOURCES)
602  if (SOURCES)
603  list (GET SOURCES 0 BUILD_DIR) # CMake <3.1 stores path to internal build directory here
604  if (BUILD_DIR MATCHES "CMakeFiles")
605  list (REMOVE_AT SOURCES 0)
606  endif ()
607  get_target_property (BUILD_DIR ${T} BUILD_DIRECTORY)
608  list (APPEND DOXYGEN_INPUT "${BUILD_DIR}.dir/install")
609  foreach (S IN LISTS SOURCES)
610  list (APPEND DOXYGEN_EXCLUDE_PATTERNS "${S}")
611  list (APPEND DOXYGEN_EXCLUDE_PATTERNS "${BUILD_DIR}.dir/build")
612  endforeach ()
613  endif ()
614  endif ()
615  endforeach ()
616  # add .dox files as input
617  file (GLOB_RECURSE DOX_FILES "${PROJECT_DOC_DIR}/*.dox")
618  list (SORT DOX_FILES) # alphabetic order
619  list (APPEND DOXYGEN_INPUT ${DOX_FILES})
620  # add .dox files of used BASIS utilities
621  if (BASIS_DIR AND NOT EXCLUDE_BASIS_UTILITIES)
622  list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
623  list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/CxxUtilities.dox")
624  foreach (L IN ITEMS Cxx Java Python Perl Bash Matlab)
625  string (TOUPPER "${L}" U)
626  basis_get_project_property (USES_${U}_UTILITIES PROPERTY PROJECT_USES_${U}_UTILITIES)
627  if (USES_${U}_UTILITIES)
628  list (FIND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox" IDX)
629  if (IDX EQUAL -1)
630  list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/Utilities.dox")
631  endif ()
632  list (APPEND DOXYGEN_INPUT "${BASIS_MODULE_PATH}/${L}Utilities.dox")
633  endif ()
634  endforeach ()
635  endif ()
636  # include path - Disabled as this increases the runtime of Doxygen but
637  # generally the source of third-party packages are not
638  # really referenced. Only the source files of this
639  # project have to be considered. This code is kept as it
640  # might be used again at a later point once it is figured
641  # how Doxygen can be only rerun if necessary.
642  #basis_get_project_property (INCLUDE_DIRS PROPERTY PROJECT_INCLUDE_DIRS)
643  #foreach (D IN LISTS INCLUDE_DIRS)
644  # list (FIND DOXYGEN_INPUT "${D}" IDX)
645  # if (IDX EQUAL -1)
646  # list (APPEND DOXYGEN_INCLUDE_PATH "${D}")
647  # endif ()
648  #endforeach ()
649  #basis_list_to_delimited_string (
650  # DOXYGEN_INCLUDE_PATH "\"\nINCLUDE_PATH += \"" ${DOXYGEN_INCLUDE_PATH}
651  #)
652  #set (DOXYGEN_INCLUDE_PATH "\"${DOXYGEN_INCLUDE_PATH}\"")
653  # make string from DOXYGEN_INPUT - after include path was set
655  DOXYGEN_INPUT "\"\nINPUT += \"" ${DOXYGEN_INPUT}
656  )
657  set (DOXYGEN_INPUT "\"${DOXYGEN_INPUT}\"")
658  # preprocessor definitions
660  DOXYGEN_PREDEFINED "\"\nPREDEFINED += \"" ${DOXYGEN_PREDEFINED}
661  )
662  set (DOXYGEN_PREDEFINED "\"${DOXYGEN_PREDEFINED}\"")
663  # outputs
664  if (NOT DOXYGEN_OUTPUT_DIRECTORY)
665  set (DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME_L}")
666  endif ()
667  if (DOXYGEN_TAGFILE MATCHES "^(None|NONE|none)$")
668  set (DOXYGEN_TAGFILE)
669  else ()
670  set (DOXYGEN_TAGFILE "${DOXYGEN_OUTPUT_DIRECTORY}/Doxytags.${TARGET_NAME_L}")
671  endif ()
672  if (NOT DOXYGEN_OUTPUT)
673  set (DOXYGEN_OUTPUT html)
674  endif ()
675  foreach (F IN ITEMS HTML XML RTF LATEX MAN)
676  set (DOXYGEN_GENERATE_${F} NO)
677  endforeach ()
678  foreach (f IN LISTS DOXYGEN_OUTPUT)
679  if (NOT f MATCHES "^(html|xml)$")
680  message (FATAL_ERROR "Invalid/Unsupported Doxygen output format: ${f}")
681  endif ()
682  string (TOUPPER "${f}" F)
683  set (DOXYGEN_GENERATE_${F} YES) # enable generation of this output
684  set (DOXYGEN_${F}_OUTPUT "${f}") # relative output directory
685  endforeach ()
686  # input filters
687  if (NOT DOXYGEN_INPUT_FILTER)
688  basis_get_target_uid (DOXYFILTER "basis.doxyfilter")
689  if (TARGET "${DOXYFILTER}")
690  basis_get_target_location (DOXYGEN_INPUT_FILTER ${DOXYFILTER} ABSOLUTE)
691  else ()
692  basis_get_target_uid (DOXYFILTER "doxyfilter")
693  if (TARGET "${DOXYFILTER}")
694  basis_get_target_location (DOXYGEN_INPUT_FILTER ${DOXYFILTER} ABSOLUTE)
695  endif ()
696  endif ()
697  else ()
698  set (DOXYFILTER)
699  endif ()
700  if (DOXYGEN_INPUT_FILTER)
701  if (WIN32)
702  # Doxygen on Windows (XP, 32-bit) (at least up to version 1.8.0) seems
703  # to have a problem of not calling filters which have a space character
704  # in their file path correctly. The doxyfilter.bat Batch program is used
705  # as a wrapper for the actual filter which is part of the BASIS build.
706  # As this file is in the working directory of Doxygen, it can be
707  # referenced relative to this working directory, i.e., without file paths.
708  # The Batch program itself then calls the actual Doxygen filter with proper
709  # quotes to ensure that spaces in the file path are handled correctly.
710  # The file extension .bat shall distinguish this wrapper script from the actual
711  # doxyfilter.cmd which is generated by BASIS on Windows.
712  configure_file ("${BASIS_MODULE_PATH}/doxyfilter.bat.in" "${DOXYGEN_OUTPUT_DIRECTORY}/doxyfilter.bat" @ONLY)
713  set (DOXYGEN_INPUT_FILTER "doxyfilter.bat")
714  endif ()
715  endif ()
717  DOXYGEN_FILTER_PATTERNS "\"\nFILTER_PATTERNS += \"" ${DOXYGEN_FILTER_PATTERNS}
718  )
719  if (DOXYGEN_FILTER_PATTERNS)
720  set (DOXYGEN_FILTER_PATTERNS "\"${DOXYGEN_FILTER_PATTERNS}\"")
721  endif ()
722  # exclude patterns
723  list (APPEND DOXYGEN_EXCLUDE_PATTERNS "cmake_install.cmake")
724  list (APPEND DOXYGEN_EXCLUDE_PATTERNS "CTestTestfile.cmake")
726  DOXYGEN_EXCLUDE_PATTERNS "\"\nEXCLUDE_PATTERNS += \"" ${DOXYGEN_EXCLUDE_PATTERNS}
727  )
728  set (DOXYGEN_EXCLUDE_PATTERNS "\"${DOXYGEN_EXCLUDE_PATTERNS}\"")
729  # section for man pages
730  if (NOT DOXYGEN_MAN_SECTION)
731  set (DOXYGEN_MAN_SECTION 3)
732  endif ()
733  # other settings
734  if (NOT DOXYGEN_COLS_IN_ALPHA_INDEX OR DOXYGEN_COLS_IN_ALPHA_INDEX MATCHES "[^0-9]")
735  set (DOXYGEN_COLS_IN_ALPHA_INDEX 1)
736  endif ()
737  basis_list_to_delimited_string (DOXYGEN_IGNORE_PREFIX " " ${DOXYGEN_IGNORE_PREFIX})
738  # click & jump in emacs and Visual Studio
739  if (CMAKE_BUILD_TOOL MATCHES "(msdev|devenv)")
740  set (DOXYGEN_WARN_FORMAT "\"$file($line) : $text \"")
741  else ()
742  set (DOXYGEN_WARN_FORMAT "\"$file:$line: $text \"")
743  endif ()
744  # installation directories
745  set (BASIS_INSTALL_${TARGET_NAME_U}_DIR "" CACHE PATH "Installation directory for Doxygen ${TARGET_NAME} target.")
746  mark_as_advanced (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
747  foreach (f IN LISTS DOXYGEN_OUTPUT)
748  string (TOUPPER "${f}" F)
749  if (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
750  set (DOXYGEN_${F}_DESTINATION "${BASIS_INSTALL_${TARGET_NAME_U}_DIR}") # user setting
751  endif ()
752  if (NOT DOXYGEN_${F}_DESTINATION)
753  if (DOXYGEN_DESTINATION)
754  set (DOXYGEN_${F}_DESTINATION "${DOXYGEN_DESTINATION}") # common destination
755  elseif (f MATCHES "man")
756  if (INSTALL_MAN_DIR)
757  set (DOXYGEN_MAN_DESTINATION "${INSTALL_MAN_DIR}/man${DOXYGEN_MAN_SECTION}") # default for manual pages
758  endif ()
759  elseif (NOT f MATCHES "html") # do not install excludes by default
760  set (DOXYGEN_${F}_DESTINATION "${INSTALL_DOC_DIR}") # default destination
761  endif ()
762  endif ()
763  endforeach ()
764  # determine tool to generate pdf documentation, see USE_PDFLATEX in Doxyfile.in
765  find_package (LATEX QUIET)
766  if (PDFLATEX_COMPILER)
767  set (DOXYGEN_USE_PDFLATEX YES)
768  else ()
769  set (DOXYGEN_USE_PDFLATEX NO)
770  message (STATUS "pdflatex not found. For higher quality PDFs make sure pdflatex is installed and found on the PATH.")
771  endif ()
772  # use default custom HTML files if available and none explicitly specified
773  if (NOT DOXYGEN_HTML_EXTRA_STYLESHEET)
774  if (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_extra.css.in")
775  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOCRES_DIR}/doxygen_extra.css.in")
776  elseif (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_extra.css")
777  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOCRES_DIR}/doxygen_extra.css")
778  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_extra.css.in")
779  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOC_DIR}/doxygen_extra.css.in")
780  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_extra.css")
781  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOC_DIR}/doxygen_extra.css")
782  elseif (EXISTS "${PROJECT_DOCRES_DIR}/doxygen.css.in")
783  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOCRES_DIR}/doxygen.css.in")
784  elseif (EXISTS "${PROJECT_DOCRES_DIR}/doxygen.css")
785  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOCRES_DIR}/doxygen.css")
786  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen.css.in")
787  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOC_DIR}/doxygen.css.in")
788  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen.css")
789  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${PROJECT_DOC_DIR}/doxygen.css")
790  endif ()
791  endif ()
792  if (DOXYGEN_HTML_HEADER_IS_DEFAULT AND NOT DOXYGEN_HTML_EXTRA_STYLESHEET)
793  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${BASIS_MODULE_PATH}/doxygen_extra.css.in")
794  endif ()
795  if (NOT DOXYGEN_HTML_HEADER)
796  if (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_header.html.in")
797  set (DOXYGEN_HTML_HEADER "${PROJECT_DOCRES_DIR}/doxygen_header.html.in")
798  elseif (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_header.html")
799  set (DOXYGEN_HTML_HEADER "${PROJECT_DOCRES_DIR}/doxygen_header.html")
800  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_header.html.in")
801  set (DOXYGEN_HTML_HEADER "${PROJECT_DOC_DIR}/doxygen_header.html.in")
802  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_header.html")
803  set (DOXYGEN_HTML_HEADER "${PROJECT_DOC_DIR}/doxygen_header.html")
804  endif ()
805  endif ()
806  if (NOT DOXYGEN_HTML_FOOTER)
807  if (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_footer.html.in")
808  set (DOXYGEN_HTML_FOOTER "${PROJECT_DOCRES_DIR}/doxygen_footer.html.in")
809  elseif (EXISTS "${PROJECT_DOCRES_DIR}/doxygen_footer.html")
810  set (DOXYGEN_HTML_FOOTER "${PROJECT_DOCRES_DIR}/doxygen_footer.html")
811  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_footer.html.in")
812  set (DOXYGEN_HTML_FOOTER "${PROJECT_DOC_DIR}/doxygen_footer.html.in")
813  elseif (EXISTS "${PROJECT_DOC_DIR}/doxygen_footer.html")
814  set (DOXYGEN_HTML_FOOTER "${PROJECT_DOC_DIR}/doxygen_footer.html")
815  endif ()
816  endif ()
817  # configure/copy custom HTML ressource files
818  if (DOXYGEN_GENERATE_HTML)
819  set (DOXYGEN_HTML_EXTRA_STYLESHEET_NAME "doxygen_extra.css")
820  set (OUTPUT_HTML_EXTRA_STYLESHEET "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_EXTRA_STYLESHEET_NAME}")
821  set (OUTPUT_HTML_HEADER "${DOXYGEN_OUTPUT_DIRECTORY}/doxygen_header.html")
822  set (OUTPUT_HTML_FOOTER "${DOXYGEN_OUTPUT_DIRECTORY}/doxygen_footer.html")
823  foreach (res IN ITEMS EXTRA_STYLESHEET HEADER FOOTER)
824  if (EXISTS "${DOXYGEN_HTML_${res}}")
825  if (DOXYGEN_HTML_${res} MATCHES "\\.in$")
826  configure_file (${DOXYGEN_HTML_${res}} "${OUTPUT_HTML_${res}}" @ONLY)
827  elseif (DOXYGEN_HTML_${res})
828  configure_file (${DOXYGEN_HTML_${res}} "${OUTPUT_HTML_${res}}" COPYONLY)
829  else ()
830  set (OUTPUT_HTML_${res})
831  endif ()
832  endif ()
833  endforeach ()
834  set (DOXYGEN_HTML_EXTRA_STYLESHEET "${OUTPUT_HTML_EXTRA_STYLESHEET}")
835  set (DOXYGEN_HTML_HEADER "${OUTPUT_HTML_HEADER}")
836  set (DOXYGEN_HTML_FOOTER "${OUTPUT_HTML_FOOTER}")
837  else ()
838  set (DOXYGEN_HTML_EXTRA_STYLESHEET)
839  set (DOXYGEN_HTML_FOOTER)
840  set (DOXYGEN_HTML_HEADER)
841  endif ()
842  if (DOXYGEN_PROVIDER_LOGO)
843  list (APPEND DOXYGEN_HTML_EXTRA_FILES "${DOXYGEN_PROVIDER_LOGO}")
844  endif()
845  if (DOXYGEN_DIVISION_LOGO)
846  list (APPEND DOXYGEN_HTML_EXTRA_FILES "${DOXYGEN_DIVISION_LOGO}")
847  endif()
848  if (DOXYGEN_HTML_EXTRA_FILES)
850  DOXYGEN_HTML_EXTRA_FILES "\"\nHTML_EXTRA_FILES += \"" ${DOXYGEN_HTML_EXTRA_FILES}
851  )
852  endif ()
853  # list of enabled Doxygen comment sections
854  basis_join ("${DOXYGEN_ENABLED_SECTIONS}" " " DOXYGEN_ENABLED_SECTIONS)
855  # configure Doxygen configuration file
856  set (DOXYFILE "${DOXYGEN_OUTPUT_DIRECTORY}/Doxyfile.${TARGET_NAME_L}")
857  configure_file ("${DOXYGEN_DOXYFILE}" "${DOXYFILE}" @ONLY)
858  if (CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
859  file (READ "${DOXYFILE}" DOXYFILE_CONTENT)
860  foreach (CONFIG IN LISTS CMAKE_CONFIGURATION_TYPES)
861  string (REPLACE "$<${BASIS_GE_CONFIG}>" "${CONFIG}" DOXYFILE_CONTENT_CONFIG "${DOXYFILE_CONTENT}")
862  file (WRITE "${DOXYFILE}.${CONFIG}" "${DOXYFILE_CONTENT_CONFIG}")
863  endforeach ()
864  unset (DOXYFILE_CONTENT)
865  unset (DOXYFILE_CONTENT_CONFIG)
866  set (DOXYFILE "${DOXYFILE}.$<${BASIS_GE_CONFIG}>")
867  endif ()
868  # add build target
869  set (OPTALL)
871  set (OPTALL "ALL")
872  endif ()
873  file (MAKE_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}")
874  add_custom_target (
875  ${TARGET_UID} ${OPTALL} "${DOXYGEN_EXECUTABLE}" "${DOXYFILE}"
876  WORKING_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}"
877  COMMENT "Building documentation ${TARGET_UID}..."
878  )
879  # memorize certain settings which might be useful to know by other functions
880  # in particular, in case of the use of the XML output by other documentation
881  # build tools such as Sphinx, the function that wants to make use of this
882  # output can check if the Doxygen target has been configured properly and
883  # further requires to know the location of the XML output
885  ${TARGET_UID}
886  PROPERTIES
887  BASIS_TYPE Doxygen
888  OUTPUT_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}"
889  DOXYFILE "${DOXYGEN_DOXYFILE}"
890  TAGFILE "${DOXYGEN_TAGFILE}"
891  OUTPUT "${DOXYGEN_OUTPUT}"
892  )
893  foreach (f IN LISTS DOXYGEN_OUTPUT)
894  string (TOUPPER "${f}" F)
896  ${TARGET_UID}
897  PROPERTIES
898  ${F}_INSTALL_DIRECTORY "${DOXYGEN_${F}_DESTINATION}"
899  ${F}_OUTPUT_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_${F}_OUTPUT}"
900  )
901  set_property (
902  DIRECTORY
903  APPEND PROPERTY
904  ADDITIONAL_MAKE_CLEAN_FILES
905  "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_${F}_OUTPUT}"
906  )
907  endforeach ()
908  if (DOXYGEN_TAGFILE)
909  set_property (
910  DIRECTORY
911  APPEND PROPERTY
912  ADDITIONAL_MAKE_CLEAN_FILES
913  "${DOXYGEN_TAGFILE}"
914  )
915  endif ()
916  # The Doxygen filter, if a build target of this project, has to be build
917  # before the documentation can be generated.
918  if (TARGET "${DOXYFILTER}")
919  add_dependencies (${TARGET_UID} ${DOXYFILTER})
920  endif ()
921  # The public header files shall be configured/copied before.
922  if (TARGET headers)
923  add_dependencies (${TARGET_UID} headers)
924  endif ()
925  # The documentation shall be build after all other executable and library
926  # targets have been build. For example, a .py.in script file shall first
927  # be "build", i.e., configured before the documentation is being generated
928  # from the configured .py file.
929  basis_get_project_property (TARGETS PROPERTY TARGETS)
930  foreach (_UID ${TARGETS})
931  get_target_property (BASIS_TYPE ${_UID} "BASIS_TYPE")
932  if (BASIS_TYPE MATCHES "SCRIPT|EXECUTABLE|LIBRARY")
933  add_dependencies (${TARGET_UID} ${_UID})
934  endif ()
935  endforeach ()
936  # add general "doc" target
937  if (NOT DOXYGEN_EXCLUDE_FROM_DOC)
938  if (NOT TARGET doc)
939  add_custom_target (doc)
940  endif ()
941  add_dependencies (doc ${TARGET_UID})
942  endif ()
943  # install documentation
944  install (
945  CODE
946  "
947  set (HTML_DESTINATION \"${DOXYGEN_HTML_DESTINATION}\")
948  set (MAN_DESTINATION \"${DOXYGEN_MAN_DESTINATION}\")
949 
950  function (install_doxydoc FMT)
951  string (TOUPPER \"\${FMT}\" FMT_U)
952  set (CMAKE_INSTALL_PREFIX \"\${\${FMT_U}_DESTINATION}\")
953  if (NOT CMAKE_INSTALL_PREFIX)
954  return ()
955  elseif (NOT IS_ABSOLUTE \"\${CMAKE_INSTALL_PREFIX}\")
956  set (CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}/\${CMAKE_INSTALL_PREFIX}\")
957  endif ()
958  set (EXT)
959  set (DIR \"\${FMT}\")
960  if (FMT MATCHES \".pdf\")
961  set (EXT \".pdf\")
962  set (DIR \"latex\")
963  elseif (FMT MATCHES \".rtf\")
964  set (EXT \".rtf\")
965  elseif (FMT MATCHES \"man\")
966  set (EXT \".?\")
967  endif ()
968  file (
969  GLOB_RECURSE
970  FILES
971  RELATIVE \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}\"
972  \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/*\${EXT}\"
973  )
974  foreach (F IN LISTS FILES)
975  execute_process (
976  COMMAND \"${CMAKE_COMMAND}\" -E compare_files
977  \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/\${F}\"
978  \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
979  RESULT_VARIABLE RC
980  OUTPUT_QUIET
981  ERROR_QUIET
982  )
983  if (RC EQUAL 0)
984  message (STATUS \"Up-to-date: \${CMAKE_INSTALL_PREFIX}/\${F}\")
985  else ()
986  message (STATUS \"Installing: \${CMAKE_INSTALL_PREFIX}/\${F}\")
987  execute_process (
988  COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
989  \"${DOXYGEN_OUTPUT_DIRECTORY}/\${DIR}/\${F}\"
990  \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
991  RESULT_VARIABLE RC
992  OUTPUT_QUIET
993  ERROR_QUIET
994  )
995  if (RC EQUAL 0)
996  list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${F}\")
997  else ()
998  message (STATUS \"Failed to install \${CMAKE_INSTALL_PREFIX}/\${F}\")
999  endif ()
1000  endif ()
1001  endforeach ()
1002  if (FMT MATCHES \"html\" AND EXISTS \"${DOXYGEN_TAGFILE}\")
1003  get_filename_component (DOXYGEN_TAGFILE_NAME \"${DOXYGEN_TAGFILE}\" NAME)
1004  execute_process (
1005  COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
1006  \"${DOXYGEN_TAGFILE}\"
1007  \"\${CMAKE_INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\"
1008  )
1009  list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${DOXYGEN_TAGFILE_NAME}\")
1010  endif ()
1011  endfunction ()
1012 
1013  foreach (FMT IN ITEMS html pdf rtf man)
1014  install_doxydoc (\${FMT})
1015  endforeach ()
1016  "
1017  )
1018  # done
1019  message (STATUS "Adding documentation ${TARGET_UID}... - done")
1020 endfunction ()
1021 
1022 # ----------------------------------------------------------------------------
1023 ## @brief Add documentation target to be generated by Sphinx (sphinx-build).
1024 #
1025 # This function adds a build target to generate documentation from
1026 # <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>
1027 # (.rst files) using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
1028 #
1029 # @param [in] TARGET_NAME Name of the documentation target.
1030 # @param [in] ARGN List of arguments. The valid arguments are:
1031 # @par
1032 # <table border="0">
1033 # <tr>
1034 # @tp @b EXCLUDE_FROM_DOC @endtp
1035 # <td>By default, the specified target is build as part of the global
1036 # @c doc target. If this option is given, however, the added
1037 # documentation will not be build as part of this target.</td>
1038 # </tr>
1039 # <tr>
1040 # @tp @b BUILDER(S) builder... @endtp
1041 # <td>Sphinx builders to use. For each named builder, a build target
1042 # named &lt;TARGET_NAME&gt;_&lt;builder&gt; is added.</td>
1043 # </tr>
1044 # <tr>
1045 # @tp @b DEFAULT_BUILDER builder @endtp
1046 # <td>Default Sphinx builder to associated with the @c TARGET_NAME
1047 # build target. Defaults to the first builder named by @c BUILDERS.</td>
1048 # </tr>
1049 # <tr>
1050 # @tp @b AUTHOR(S) name @endtp
1051 # <td>Names of authors who wrote this documentation.
1052 # (default: @c PROJECT_AUTHORS)</td>
1053 # </tr>
1054 # <tr>
1055 # @tp @b COPYRIGHT text @endtp
1056 # <td>Copyright statement for generated files. (default: @c PROJECT_COPYRIGHT)</td>
1057 # </tr>
1058 # <tr>
1059 # @tp @b COMPONENT component @endtp
1060 # <td>Name of the component this documentation belongs to.
1061 # Defaults to @c BASIS_RUNTIME_COMPONENT.</td>
1062 # </tr>
1063 # <tr>
1064 # @tp @b DESTINATION dir @endtp
1065 # <td>Installation directory prefix. Used whenever there is no specific
1066 # destination specified for a particular Sphinx builder. Defaults to
1067 # @c BASIS_INSTALL_&ltTARGET&gt;_DIR in case of HTML output if set.
1068 # Otherwise, the generated HTML files are not installed.</td>
1069 # </tr>
1070 # <tr>
1071 # @tp @b &lt;BUILDER&gt;_DESTINATION dir @endtp
1072 # <td>Installation directory for files generated by the specific builder.<td>
1073 # </tr>
1074 # <tr>
1075 # @tp @b EXTENSIONS ext... @endtp
1076 # <td>Names of Sphinx extensions to enable.</td>
1077 # </tr>
1078 # <tr>
1079 # @tp @b BREATHE target... @endtp
1080 # <td>Adds a project for the breathe extension which allows the
1081 # inclusion of in-source code documentation extracted by Doxygen.
1082 # For this to work, the specified Doxygen target has to be
1083 # configured with the XML output enabled.</td>
1084 # </tr>
1085 # <tr>
1086 # @tp @b DOXYLINK target... @endtp
1087 # <td>Adds a role for the doxylink Sphinx extension which allows to cross-reference
1088 # generated HTML API documentation generated by Doxygen.</td>
1089 # </tr>
1090 # <tr>
1091 # @tp @b DOXYLINK_URL url @endtp
1092 # <td>URL to Doxygen documentation. Use DOXYLINK_PREFIX and/or DOXYLINK_SUFFIX
1093 # instead if you use multiple Doxygen targets, where the target name is
1094 # part of the URL.</td>
1095 # </tr>
1096 # <tr>
1097 # @tp @b DOXYLINK_PREFIX url @endtp
1098 # <td>Prefix to use for links to Doxygen generated documentation pages
1099 # as generated by the doxylink Sphinx extension. If this prefix does
1100 # not start with a protocol such as http:// or https://, it is prefixed
1101 # to the default path determined by this function relative to the build
1102 # or installed Doxygen documentation.</td>
1103 # </tr>
1104 # <tr>
1105 # @tp @b DOXYLINK_SUFFIX suffix @endtp
1106 # <td>Suffix for links to Doxygen generated documentation pages as generated
1107 # by the doxylink Sphinx extension.</td>
1108 # </tr>
1109 # <tr>
1110 # @tp @b DOXYDOC target... @endtp
1111 # <td>Alias for both @c BREATHE and @c DOXYLINK options.</td>
1112 # </tr>
1113 # <tr>
1114 # @tp @b CONFIG_FILE file @endtp
1115 # <td>Sphinx configuration file. Defaults to @c BASIS_SPHINX_CONFIG.</td>
1116 # </tr>
1117 # <tr>
1118 # @tp @b SOURCE_DIRECTORY @endtp
1119 # <td>Root directory of Sphinx source files.
1120 # Defaults to the current source directory or, if a subdirectory
1121 # named @c TARGET_NAME in lowercase only exists, to this subdirectory.</td>
1122 # </tr>
1123 # <tr>
1124 # @tp @b OUTPUT_NAME @endtp
1125 # <td>Output name for generated documentation such as PDF document or MAN page.
1126 # Defaults to @c PROJECT_NAME.</td>
1127 # </tr>
1128 # <tr>
1129 # @tp @b OUTPUT_DIRECTORY @endtp
1130 # <td>Root output directory for generated files. Defaults to the binary
1131 # directory corresponding to the set @c SOURCE_DIRECTORY.</td>
1132 # </tr>
1133 # <tr>
1134 # @tp @b TAG tag @endtp
1135 # <td>Tag argument of <tt>sphinx-build</tt>.</td>
1136 # </tr>
1137 # <tr>
1138 # @tp @b TEMPLATES_PATH @endtp
1139 # <td>Path to template files. Defaults to <tt>SOURCE_DIRECTORY/templates/</tt>.</td>
1140 # </tr>
1141 # <tr>
1142 # @tp @b MASTER_DOC name @endtp
1143 # <td>Name of master document. Defaults to <tt>index</tt>.</td>
1144 # </tr>
1145 # <tr>
1146 # @tp @b EXCLUDE_PATTERN pattern @endtp
1147 # <td>A glob-style pattern that should be excluded when looking for source files.
1148 # Specify this option more than once to specify multiple exclude patterns.
1149 # They are matched against the source file names relative to the source directory,
1150 # using slashes as directory separators on all platforms.</td>
1151 # </tr>
1152 # <tr>
1153 # @tp @b HTML_TITLE title @endtp
1154 # <td>Title of HTML web site.</td>
1155 # </tr>
1156 # <tr>
1157 # @tp @b HTML_THEME theme @endtp
1158 # <td>Name of HTML theme. Defaults to the @c sbia theme included with BASIS.</td>
1159 # </tr>
1160 # <tr>
1161 # @tp @b HTML_THEME_PATH dir @endtp
1162 # <td>Directory of HTML theme. Defaults to @c BASIS_SPHINX_HTML_THEME_PATH.</td>
1163 # </tr>
1164 # <tr>
1165 # @tp @b HTML_LOGO file @endtp
1166 # <td>Logo to display in sidebar of HTML pages.</td>
1167 # </tr>
1168 # <tr>
1169 # @tp @b HTML_FAVICON file @endtp
1170 # <td>Favorite square icon often displayed by browsers in the tab bar.
1171 # Should be a @c .ico file.</td>
1172 # </tr>
1173 # <tr>
1174 # @tp @b HTML_STATIC_PATH dir @endtp
1175 # <td>Directory for static files of HTML pages. Defaults to <tt>SOURCE_DIRECTORY/static/</tt>.</td>
1176 # </tr>
1177 # <tr>
1178 # @tp @b HTML_STYLE css @endtp
1179 # <td>The style sheet to use for HTML pages. A file of that name must exist either in Sphinx'
1180 # default static/ path or the specified @c HTML_STATIC_PATH. Default is the stylesheet
1181 # given by the selected theme. If you only want to add or override a few things compared
1182 # to the theme’s stylesheet, use CSS \@import to import the theme’s stylesheet.</td>
1183 # </tr>
1184 # <tr>
1185 # @tp @b HTML_SIDEBARS name... @endtp
1186 # <td>Names of HTML template files for sidebar(s). Defaults to none if not specified.
1187 # Valid default templates are @c localtoc, @c globaltoc, @c searchbox, @c relations,
1188 # @c sourcelink. See <a href="http://sphinx.pocoo.org/config.html#confval-html_sidebars">
1189 # Shinx documentation of html_sidebars option</a>. Custom templates can be used as
1190 # well by copying the template <tt>.html</tt> file to the @c TEMPLATES_PATH directory.</td>
1191 # </tr>
1192 # <tr>
1193 # @tp @b NO_HTML_DOMAIN_INDICES @endtp
1194 # <td>Set Sphinx configuration option @c html_domain_indices to @c False. (Default: @c True)</td>
1195 # </tr>
1196 # <tr>
1197 # @tp @b NO_HTML_MODINDEX @endtp
1198 # <td>Set Sphinx configuration option @c html_use_modindex to @c False. (Default: @c True)</td>
1199 # </tr>
1200 # <tr>
1201 # @tp @b NO_HTML_INDEX @endtp
1202 # <td>Set Sphinx configuration option @c html_use_index to @c False. (Default: @c True)</td>
1203 # </tr>
1204 # <tr>
1205 # @tp @b LATEX_MASTER_DOC name @endtp
1206 # <td>Name of master document for LaTeX builder. Defaults to <tt>MASTER_DOC</tt>.</td>
1207 # </tr>
1208 # <tr>
1209 # @tp @b LATEX_TITLE title @endtp
1210 # <td>Title for LaTeX/PDF output. Defaults to title of <tt>index.rst</tt>.</td>
1211 # </tr>
1212 # <tr>
1213 # @tp @b LATEX_LOGO file @endtp
1214 # <td>Logo to display above title in generated LaTeX/PDF output.</td>
1215 # </tr>
1216 # <tr>
1217 # @tp @b LATEX_DOCUMENT_CLASS howto|manual @endtp
1218 # <td>Document class to use by @c latex builder.</td>
1219 # </tr>
1220 # <tr>
1221 # @tp @b LATEX_SHOW_URLS @endtp
1222 # <td>See Sphinx documentation of the
1223 # <a href="http://sphinx.pocoo.org/config.html#confval-latex_show_urls">latex_show_urls</a> option.</td>
1224 # </tr>
1225 # <tr>
1226 # @tp @b LATEX_SHOW_PAGEREFS @endtp
1227 # <td>See Sphinx documentation of the
1228 # <a href="">latex_show_pagerefs</a> option.</td>
1229 # </tr>
1230 # <tr>
1231 # @tp @b MAN_SECTION num @endtp
1232 # <td>Section number for manual pages generated by @c man builder.</td>
1233 # </tr>
1234 # </table>
1235 #
1236 # @sa basis_add_doc()
1237 function (basis_add_sphinx_doc TARGET_NAME)
1238  # check target name
1239  basis_check_target_name ("${TARGET_NAME}")
1240  basis_make_target_uid (TARGET_UID "${TARGET_NAME}")
1241  string (TOLOWER "${TARGET_NAME}" TARGET_NAME_L)
1242  string (TOUPPER "${TARGET_NAME}" TARGET_NAME_U)
1243  # verbose output
1244  message (STATUS "Adding documentation ${TARGET_UID}...")
1245  # parse arguments
1246  set (ONE_ARG_OPTIONS
1247  COMPONENT
1248  DEFAUL_BUILDER
1249  DESTINATION HTML_DESTINATION MAN_DESTINATION TEXINFO_DESTINATION
1250  CONFIG_FILE
1251  SOURCE_DIRECTORY OUTPUT_DIRECTORY OUTPUT_NAME TAG
1252  COPYRIGHT MASTER_DOC
1253  HTML_TITLE HTML_THEME HTML_LOGO HTML_FAVICON HTML_THEME_PATH HTML_STYLE
1254  LATEX_MASTER_DOC LATEX_TITLE LATEX_LOGO LATEX_DOCUMENT_CLASS LATEX_SHOW_URLS LATEX_SHOW_PAGEREFS
1255  MAN_SECTION
1256  DOXYLINK_URL DOXYLINK_PREFIX DOXYLINK_SUFFIX
1257  )
1258  # note that additional multiple value arguments are parsed later on below
1259  # this is necessary b/c all unparsed arguments are considered to be options
1260  # of the used HTML theme
1261  CMAKE_PARSE_ARGUMENTS (SPHINX
1262  "EXCLUDE_FROM_DOC;NO_HTML_DOMAIN_INDICES;NO_HTML_MODINDEX;NO_HTML_INDEX"
1263  "${ONE_ARG_OPTIONS}"
1264  ""
1265  ${ARGN}
1266  )
1267  # source directory
1268  if (NOT SPHINX_SOURCE_DIRECTORY)
1269  if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}")
1270  set (SPHINX_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${TARGET_NAME}")
1271  else ()
1272  set (SPHINX_SOURCE_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
1273  endif ()
1274  elseif (NOT IS_ABSOLUTE "${SPHINX_SOURCE_DIRECTORY}")
1275  get_filename_component (SPHINX_SOURCE_DIRECTORY "${SPHINX_SOURCE_DIRECTORY}" ABSOLUTE)
1276  endif ()
1277  # component
1278  if (NOT SPHINX_COMPONENT)
1279  set (SPHINX_COMPONENT "${BASIS_RUNTIME_COMPONENT}")
1280  endif ()
1281  if (NOT SPHINX_COMPONENT)
1282  set (SPHINX_COMPONENT "Unspecified")
1283  endif ()
1284  # find Sphinx
1285  find_package (Sphinx COMPONENTS build QUIET)
1286  if (NOT Sphinx-build_EXECUTABLE)
1287  if (BUILD_DOCUMENTATION)
1288  message (FATAL_ERROR "Command sphinx-build not found! Either install Sphinx and/or set Sphinx-build_EXECUTABLE or disable BUILD_DOCUMENTATION.")
1289  endif ()
1290  message (STATUS "Command sphinx-build not found. Generation of ${TARGET_UID} documentation disabled.")
1291  message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
1292  return ()
1293  endif ()
1294  if (DEFINED Sphinx_VERSION_MAJOR AND Sphinx_VERSION_MAJOR LESS 1)
1295  if (BUILD_DOCUMENTATION)
1296  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.")
1297  endif ()
1298  message (STATUS "Command sphinx-build is too old (v${Sphinx_VERSION_STRING}). Generation of ${TARGET_UID} documentation disabled.")
1299  message (STATUS "Adding documentation ${TARGET_UID}... - skipped")
1300  return ()
1301  endif ()
1302  # parse remaining arguments
1303  set (SPHINX_HTML_THEME_OPTIONS)
1304  set (SPHINX_BUILDERS)
1305  set (SPHINX_AUTHORS)
1306  set (SPHINX_EXTENSIONS)
1307  set (SPHINX_BREATHE_TARGETS)
1308  set (SPHINX_DOXYLINK_TARGETS)
1309  set (SPHINX_HTML_SIDEBARS)
1310  set (SPHINX_TEMPLATES_PATH)
1311  set (SPHINX_HTML_STATIC_PATH)
1312  set (SPHINX_EXCLUDE_PATTERNS)
1313  set (SPHINX_DEPENDS)
1314  set (OPTION_NAME)
1315  set (OPTION_VALUE)
1316  set (OPTION_PATTERN "(authors?|builders?|extensions|breathe|doxylink|doxydoc|html_sidebars|templates_path|html_static_path|exclude_pattern)")
1317  foreach (ARG IN LISTS SPHINX_UNPARSED_ARGUMENTS)
1318  if (NOT OPTION_NAME OR ARG MATCHES "^[A-Z_]+$")
1319  # SPHINX_HTML_THEME_OPTIONS
1320  if (OPTION_NAME AND NOT OPTION_NAME MATCHES "^${OPTION_PATTERN}$")
1321  if (NOT OPTION_VALUE)
1322  message (FATAL_ERROR "Option ${OPTION_NAME} is missing an argument!")
1323  endif ()
1324  list (LENGTH OPTION_VALUE NUM)
1325  if (NUM GREATER 1)
1326  basis_list_to_delimited_string (OPTION_VALUE ", " NOAUTOQUOTE ${OPTION_VALUE})
1327  set (OPTION_VALUE "[${OPTION_VALUE}]")
1328  endif ()
1329  list (APPEND SPHINX_HTML_THEME_OPTIONS "'${OPTION_NAME}': ${OPTION_VALUE}")
1330  endif ()
1331  # name of next option
1332  set (OPTION_NAME "${ARG}")
1333  set (OPTION_VALUE)
1334  string (TOLOWER "${OPTION_NAME}" OPTION_NAME)
1335  # BUILDER option
1336  elseif (OPTION_NAME MATCHES "^builders?$")
1337  if (ARG MATCHES "html dirhtml singlehtml pdf latex man text texinfo linkcheck")
1338  message (FATAL_ERROR "Invalid/Unsupported Sphinx builder: ${ARG}")
1339  endif ()
1340  list (APPEND SPHINX_BUILDERS "${ARG}")
1341  # AUTHORS option
1342  elseif (OPTION_NAME MATCHES "^authors?$")
1343  list (APPEND SPHINX_AUTHORS "'${ARG}'")
1344  # EXTENSIONS option
1345  elseif (OPTION_NAME MATCHES "^extensions$")
1346  # built-in extension
1347  if (ARG MATCHES "^(autodoc|autosummary|doctest|intersphinx|pngmath|jsmath|mathjax|graphvis|inheritance_graph|ifconfig|coverage|todo|extlinks|viewcode)$")
1348  set (ARG "sphinx.ext.${CMAKE_MATCH_0}")
1349  # map originial name of extensions included with BASIS
1350  elseif (BASIS_SPHINX_EXTENSIONS_PATH AND ARG MATCHES "^sphinxcontrib.(doxylink)$")
1351  set (ARG "${CMAKE_MATCH_1}")
1352  endif ()
1353  list (APPEND SPHINX_EXTENSIONS "'${ARG}'")
1354  # DOXYDOC
1355  elseif (OPTION_NAME MATCHES "^doxydoc$")
1356  list (APPEND SPHINX_BREATHE_TARGETS "${ARG}")
1357  list (APPEND SPHINX_DOXYLINK_TARGETS "${ARG}")
1358  # BREATHE
1359  elseif (OPTION_NAME MATCHES "^breathe$")
1360  list (APPEND SPHINX_BREATHE_TARGETS "${ARG}")
1361  # DOXYLINK
1362  elseif (OPTION_NAME MATCHES "^doxylink$")
1363  list (APPEND SPHINX_DOXYLINK_TARGETS "${ARG}")
1364  # HTML_SIDEBARS
1365  elseif (OPTION_NAME MATCHES "^html_sidebars$")
1366  if (NOT ARG MATCHES "\\.html?$")
1367  set (ARG "${ARG}.html")
1368  endif ()
1369  list (APPEND SPHINX_HTML_SIDEBARS "'${ARG}'")
1370  # TEMPLATES_PATH
1371  elseif (OPTION_NAME MATCHES "^templates_path$")
1372  if (NOT IS_ABSOLUTE "${ARG}")
1373  set (ARG "${SPHINX_SOURCE_DIRECTORY}/${ARG}")
1374  endif ()
1375  list (APPEND SPHINX_TEMPLATES_PATH "'${ARG}'")
1376  # HTML_STATIC_PATH
1377  elseif (OPTION_NAME MATCHES "^html_static_path$")
1378  if (NOT IS_ABSOLUTE "${ARG}")
1379  set (ARG "${SPHINX_SOURCE_DIRECTORY}/${ARG}")
1380  endif ()
1381  list (APPEND SPHINX_HTML_STATIC_PATH "'${ARG}'")
1382  # EXCLUDE_PATTERN
1383  elseif (OPTION_NAME MATCHES "^exclude_pattern$")
1384  list (APPEND SPHINX_EXCLUDE_PATTERNS "'${ARG}'")
1385  # value of theme option
1386  else ()
1387  if (ARG MATCHES "^(TRUE|FALSE)$")
1388  string (TOLOWER "${ARG}" "${ARG}")
1389  endif ()
1390  if (NOT ARG MATCHES "^\\[.*\\]$|^{.*}$")
1391  set (ARG "'${ARG}'")
1392  endif ()
1393  list (APPEND OPTION_VALUE "${ARG}")
1394  endif ()
1395  endforeach ()
1396  # append parsed option setting to SPHINX_HTML_THEME_OPTIONS
1397  if (OPTION_NAME AND NOT OPTION_NAME MATCHES "^${OPTION_PATTERN}$")
1398  if (NOT OPTION_VALUE)
1399  message (FATAL_ERROR "Option ${OPTION_NAME} is missing an argument!")
1400  endif ()
1401  list (LENGTH OPTION_VALUE NUM)
1402  if (NUM GREATER 1)
1403  basis_list_to_delimited_string (OPTION_VALUE ", " NOAUTOQUOTE ${OPTION_VALUE})
1404  set (OPTION_VALUE "[${OPTION_VALUE}]")
1405  endif ()
1406  list (APPEND SPHINX_HTML_THEME_OPTIONS "'${OPTION_NAME}': ${OPTION_VALUE}")
1407  endif ()
1408  # authors
1409  if (NOT SPHINX_AUTHORS)
1410  foreach (AUTHOR IN LISTS PROJECT_AUTHORS)
1411  list (APPEND SPHINX_AUTHORS "'${AUTHOR}'")
1412  endforeach ()
1413  endif ()
1414  if (NOT SPHINX_COPYRIGHT)
1415  set (SPHINX_COPYRIGHT "${PROJECT_COPYRIGHT}")
1416  endif ()
1417  # default builders
1418  if (NOT SPHINX_BUILDERS)
1419  set (SPHINX_BUILDERS html dirhtml singlehtml man pdf texinfo text linkcheck)
1420  endif ()
1421  if (SPHINX_DEFAULT_BUILDER)
1422  list (FIND SPHINX_BUILDERS "${SPHINX_DEFAULT_BUILDER}" IDX)
1423  if (IDX EQUAL -1)
1424  list (INSERT SPHINX_BUILDERS 0 "${SPHINX_DEFAULT_BUILDER}")
1425  endif ()
1426  else ()
1427  list (GET SPHINX_BUILDERS 0 SPHINX_DEFAULT_BUILDER)
1428  endif ()
1429  # output directories
1430  if (NOT SPHINX_OUTPUT_NAME)
1431  set (SPHINX_OUTPUT_NAME "${PROJECT_NAME}")
1432  endif ()
1433  if (NOT SPHINX_OUTPUT_DIRECTORY)
1434  if (IS_ABSOLUTE "${SPHINX_OUTPUT_NAME}")
1435  get_filename_component (SPHINX_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_NAME}" PATH)
1436  else ()
1437  basis_get_relative_path (SPHINX_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${SPHINX_SOURCE_DIRECTORY}")
1438  endif ()
1439  endif ()
1440  if (NOT IS_ABSOLUTE "${SPHINX_OUTPUT_DIRECTORY}")
1441  set (SPHINX_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${SPHINX_OUTPUT_DIRECTORY}")
1442  endif ()
1443  foreach (b IN LISTS SPHINX_BUILDERS)
1444  string (TOUPPER "${b}" B)
1445  if (SPHINX_${B}_OUTPUT_DIRECTORY)
1446  if (NOT IS_ABSOLUTE "${SPHINX_${B}_OUTPUT_DIRECTORY}")
1447  set (SPHINX_${B}_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_${B}_OUTPUT_DIRECTORY}")
1448  endif ()
1449  else ()
1450  set (SPHINX_${B}_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}/${b}")
1451  endif ()
1452  endforeach ()
1453  if (IS_ABSOLUTE "${SPHINX_OUTPUT_NAME}")
1454  basis_get_relative_path (SPHINX_OUTPUT_NAME "${SPHINX_OUTPUT_DIRECTORY}" NAME_WE)
1455  endif ()
1456  # configuration directory
1457  basis_get_relative_path (SPHINX_CONFIG_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" "${SPHINX_SOURCE_DIRECTORY}")
1458  set (SPHINX_CONFIG_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${SPHINX_CONFIG_DIRECTORY}")
1459  # build configuration
1460  if (NOT SPHINX_MASTER_DOC)
1461  set (SPHINX_MASTER_DOC "index")
1462  endif ()
1463  if (NOT SPHINX_LATEX_MASTER_DOC)
1464  set (SPHINX_LATEX_MASTER_DOC "${SPHINX_MASTER_DOC}")
1465  endif ()
1466  if (NOT SPHINX_TEMPLATES_PATH AND EXISTS "${SPHINX_SOURCE_DIRECTORY}/templates")
1467  set (SPHINX_TEMPLATES_PATH "'${SPHINX_SOURCE_DIRECTORY}/templates'")
1468  endif ()
1469  if (NOT SPHINX_HTML_STATIC_PATH AND EXISTS "${SPHINX_SOURCE_DIRECTORY}/static")
1470  set (SPHINX_HTML_STATIC_PATH "'${SPHINX_SOURCE_DIRECTORY}/static'")
1471  endif ()
1472  if (NOT SPHINX_HTML_THEME)
1473  set (SPHINX_HTML_THEME "${BASIS_SPHINX_HTML_THEME}")
1474  endif ()
1475  if (NOT SPHINX_UNPARSED_ARGUMENTS AND SPHINX_HTML_THEME STREQUAL BASIS_SPHINX_HTML_THEME)
1476  set (SPHINX_UNPARSED_ARGUMENTS ${BASIS_SPHINX_HTML_THEME_OPTIONS})
1477  endif ()
1478  if (NOT SPHINX_LATEX_DOCUMENT_CLASS)
1479  set (SPHINX_LATEX_DOCUMENT_CLASS "howto")
1480  endif ()
1481  if (NOT SPHINX_MAN_SECTION)
1482  set (SPHINX_MAN_SECTION 1)
1483  endif ()
1484  # installation directories
1485  set (BASIS_INSTALL_${TARGET_NAME_U}_DIR "" CACHE PATH "Installation directory for documentation ${TARGET_NAME} target.")
1486  mark_as_advanced (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
1487  foreach (b IN LISTS SPHINX_BUILDERS)
1488  string (TOUPPER "${b}" B)
1489  if (BASIS_INSTALL_${TARGET_NAME_U}_DIR)
1490  set (SPHINX_${B}_DESTINATION "${BASIS_INSTALL_${TARGET_NAME_U}_DIR}") # user setting
1491  endif ()
1492  if (NOT SPHINX_${B}_DESTINATION)
1493  if (SPHINX_DESTINATION)
1494  set (SPHINX_${B}_DESTINATION "${DESTINATION}") # common destination
1495  elseif (b MATCHES "text")
1496  set (SPHINX_${B}_DESTINATION "${INSTALL_DOC_DIR}/${TARGET_NAME_L}")
1497  elseif (b MATCHES "man")
1498  if (INSTALL_MAN_DIR)
1499  set (SPHINX_${B}_DESTINATION "${INSTALL_MAN_DIR}/man${SPHINX_MAN_SECTION}") # default for manual pages
1500  endif ()
1501  elseif (b MATCHES "texinfo")
1502  if (INSTALL_TEXINFO_DIR)
1503  set (SPHINX_${B}_DESTINATION "${INSTALL_TEXINFO_DIR}") # default for Texinfo files
1504  endif ()
1505  elseif (NOT b MATCHES "html") # do not install excludes by default
1506  set (SPHINX_${B}_DESTINATION "${INSTALL_DOC_DIR}") # default location
1507  endif ()
1508  endif ()
1509  endforeach ()
1510  if (SPHINX_HTML_DESTINATION)
1511  foreach (b IN LISTS SPHINX_BUILDERS)
1512  if (b MATCHES "(dir|single)html")
1513  string (TOUPPER "${b}" B)
1514  if (NOT SPHINX_${B}_DESTINATION)
1515  set (SPHINX_${B}_DESTINATION "${SPHINX_HTML_DESTINATION}")
1516  endif ()
1517  endif ()
1518  endforeach ()
1519  endif ()
1520  # enable required extension
1521  if (SPHINX_DOXYLINK_TARGETS)
1522  if (BASIS_SPHINX_EXTENSIONS_PATH)
1523  if (NOT SPHINX_EXTENSIONS MATCHES "(^|;)?doxylink(;|$)?")
1524  list (APPEND SPHINX_EXTENSIONS "'doxylink'")
1525  endif ()
1526  else ()
1527  if (NOT SPHINX_EXTENSIONS MATCHES "(^|;)?sphinxcontrib.doxylink(;|$)?")
1528  list (APPEND SPHINX_EXTENSIONS "'sphinxcontrib.doxylink'")
1529  endif ()
1530  endif ()
1531  endif ()
1532  if (SPHINX_BREATHE_TARGETS AND NOT SPHINX_EXTENSIONS MATCHES "(^|;)?breathe(;|$)?")
1533  list (APPEND SPHINX_EXTENSIONS "'breathe'")
1534  endif ()
1535  # doxylink configuration
1536  foreach (TARGET IN LISTS SPHINX_DOXYLINK_TARGETS)
1537  basis_get_target_uid (UID "${TARGET}")
1538  get_target_property (TYPE ${UID} BASIS_TYPE)
1539  if (NOT TYPE MATCHES "Doxygen")
1540  message (FATAL_ERROR "Invalid argument for DOXYLINK: Target ${UID} either unknown or it is not a Doxygen target!")
1541  endif ()
1542  get_target_property (DOXYGEN_OUTPUT ${UID} OUTPUT)
1543  if (NOT DOXYGEN_OUTPUT MATCHES "html")
1544  message (FATAL_ERROR "Doxygen target ${UID} was not configured to generate HTML output! This output is required by the doxylink Sphinx extension.")
1545  endif ()
1546  get_target_property (DOXYGEN_TAGFILE ${UID} TAGFILE)
1547  get_target_property (DOXYGEN_HTML_DIRECTORY ${UID} HTML_INSTALL_DIRECTORY)
1548  set (DOXYLINK_PATH)
1549  if (SPHINX_DOXYLINK_URL)
1550  set (DOXYLINK_PATH "${SPHINX_DOXYLINK_URL}")
1551  elseif (SPHINX_DOXYLINK_PREFIX MATCHES "^[a-z]://")
1552  set (DOXYLINK_PATH "${SPHINX_DOXYLINK_PREFIX}${TARGET}${SPHINX_DOXYLINK_SUFFIX}")
1553  else ()
1554  set (DOXYLINK_BASE_DIR)
1555  if (DOXYGEN_HTML_DIRECTORY)
1556  if (SPHINX_DOXYLINK_BASE_DIR)
1557  set (DOXYLINK_BASE_DIR "${SPHINX_DOXYLINK_BASE_DIR}")
1558  elseif (SPHINX_HTML_INSTALL_DIRECTORY)
1559  set (DOXYLINK_BASE_DIR "${SPHINX_HTML_INSTALL_DIRECTORY}")
1560  endif ()
1561  else ()
1562  get_target_property (DOXYGEN_HTML_DIRECTORY ${UID} HTML_OUTPUT_DIRECTORY)
1563  if (SPHINX_DOXYLINK_BASE_DIR)
1564  set (DOXYLINK_BASE_DIR "${SPHINX_DOXYLINK_BASE_DIR}")
1565  else ()
1566  set (DOXYLINK_BASE_DIR "${SPHINX_HTML_OUTPUT_DIRECTORY}")
1567  endif ()
1568  endif ()
1569  if (DOXYLINK_BASE_DIR)
1570  basis_get_relative_path (DOXYLINK_PATH "${DOXYLINK_BASE_DIR}" "${DOXYGEN_HTML_DIRECTORY}")
1571  else ()
1572  set (DOXYLINK_PATH "${TARGET}") # safe fall back
1573  endif ()
1574  set (DOXYLINK_PATH "${SPHINX_DOXYLINK_PREFIX}${DOXYLINK_PATH}${SPHINX_DOXYLINK_SUFFIX}")
1575  endif ()
1576  list (APPEND SPHINX_DOXYLINK "'${TARGET}': ('${DOXYGEN_TAGFILE}', '${DOXYLINK_PATH}')")
1577  list (APPEND SPHINX_DEPENDS ${UID})
1578  endforeach ()
1579  # breathe configuration
1580  set (SPHINX_BREATHE_PROJECTS)
1581  set (SPHINX_BREATHE_DEFAULT_PROJECT)
1582  foreach (TARGET IN LISTS SPHINX_BREATHE_TARGETS)
1583  basis_get_target_uid (UID "${TARGET}")
1584  get_target_property (TYPE ${UID} BASIS_TYPE)
1585  if (NOT TYPE MATCHES "Doxygen")
1586  message (FATAL_ERROR "Invalid argument for BREATHE_PROJECTS: Target ${UID} either unknown or it is not a Doxygen target!")
1587  endif ()
1588  get_target_property (DOXYGEN_OUTPUT ${UID} OUTPUT)
1589  if (NOT DOXYGEN_OUTPUT MATCHES "xml")
1590  message (FATAL_ERROR "Doxygen target ${UID} was not configured to generate XML output! This output is required by the Sphinx extension breathe.")
1591  endif ()
1592  get_target_property (DOXYGEN_OUTPUT_DIRECTORY ${UID} XML_OUTPUT_DIRECTORY)
1593  list (APPEND SPHINX_BREATHE_PROJECTS "'${TARGET}': '${DOXYGEN_OUTPUT_DIRECTORY}'")
1594  if (NOT SPHINX_BREATHE_DEFAULT_PROJECT)
1595  set (SPHINX_BREATHE_DEFAULT_PROJECT "${TARGET}")
1596  endif ()
1597  list (APPEND SPHINX_DEPENDS ${UID})
1598  endforeach ()
1599  # HTML output options
1600  if (SPHINX_NO_HTML_DOMAIN_INDICES)
1601  set (SPHINX_USE_DOMAIN_INDICES False)
1602  else ()
1603  set (SPHINX_USE_DOMAIN_INDICES True)
1604  endif ()
1605  if (SPHINX_NO_HTML_MODINDEX)
1606  set (SPHINX_USE_MODINDEX False)
1607  else ()
1608  set (SPHINX_USE_MODINDEX True)
1609  endif ()
1610  if (SPHINX_NO_HTML_INDEX)
1611  set (SPHINX_USE_INDEX False)
1612  else ()
1613  set (SPHINX_USE_INDEX True)
1614  endif ()
1615  # LaTeX output options
1616  if (NOT SPHINX_LATEX_SHOW_URLS)
1617  set (SPHINX_LATEX_SHOW_URLS "no")
1618  endif ()
1619  if (SPHINX_LATEX_SHOW_PAGEREFS)
1620  set (SPHINX_LATEX_SHOW_PAGEREFS "True")
1621  else ()
1622  set (SPHINX_LATEX_SHOW_PAGEREFS "False")
1623  endif ()
1624  # turn html_logo, html_favicon, and latex_logo into absolute file path
1625  foreach (L IN ITEMS HTML_LOGO HTML_FAVICON LATEX_LOGO)
1626  if (SPHINX_${L} AND NOT IS_ABSOLUTE "${SPHINX_${L}}")
1627  if (EXISTS "${SPHINX_SOURCE_DIRECTORY}/${SPHINX_${L}}")
1628  set (SPHINX_${L} "${SPHINX_SOURCE_DIRECTORY}/${SPHINX_${L}}")
1629  elseif (L MATCHES "^HTML|^LATEX")
1630  foreach (D IN LISTS SPHINX_${CMAKE_MATCH_0}_STATIC_PATH)
1631  string (REGEX REPLACE "^'|'$" "" D "${D}")
1632  if (EXISTS "${D}/${SPHINX_${L}}")
1633  set (SPHINX_${L} "${D}/${SPHINX_${L}}")
1634  break ()
1635  endif ()
1636  endforeach ()
1637  endif ()
1638  endif ()
1639  endforeach ()
1640  # turn CMake lists into Python lists
1641  basis_list_to_delimited_string (SPHINX_EXTENSIONS ", " NOAUTOQUOTE ${SPHINX_EXTENSIONS})
1642  basis_list_to_delimited_string (SPHINX_HTML_THEME_OPTIONS ", " NOAUTOQUOTE ${SPHINX_HTML_THEME_OPTIONS})
1643  basis_list_to_delimited_string (SPHINX_AUTHORS ", " NOAUTOQUOTE ${SPHINX_AUTHORS})
1644  basis_list_to_delimited_string (SPHINX_DOXYLINK ", " NOAUTOQUOTE ${SPHINX_DOXYLINK})
1645  basis_list_to_delimited_string (SPHINX_BREATHE_PROJECTS ", " NOAUTOQUOTE ${SPHINX_BREATHE_PROJECTS})
1646  basis_list_to_delimited_string (SPHINX_HTML_SIDEBARS ", " NOAUTOQUOTE ${SPHINX_HTML_SIDEBARS})
1647  basis_list_to_delimited_string (SPHINX_TEMPLATES_PATH ", " NOAUTOQUOTE ${SPHINX_TEMPLATES_PATH})
1648  basis_list_to_delimited_string (SPHINX_HTML_STATIC_PATH ", " NOAUTOQUOTE ${SPHINX_HTML_STATIC_PATH})
1649  basis_list_to_delimited_string (SPHINX_EXCLUDE_PATTERNS ", " NOAUTOQUOTE ${SPHINX_EXCLUDE_PATTERNS})
1650  # configuration file
1651  if (NOT SPHINX_CONFIG_FILE)
1652  set (SPHINX_CONFIG_FILE "${BASIS_SPHINX_CONFIG}")
1653  endif ()
1654  get_filename_component (SPHINX_CONFIG_FILE "${SPHINX_CONFIG_FILE}" ABSOLUTE)
1655  if (EXISTS "${SPHINX_CONFIG_FILE}")
1656  configure_file ("${SPHINX_CONFIG_FILE}" "${SPHINX_CONFIG_DIRECTORY}/conf.py" @ONLY)
1657  elseif (EXISTS "${SPHINX_CONFIG_FILE}.in")
1658  configure_file ("${SPHINX_CONFIG_FILE}.in" "${SPHINX_CONFIG_DIRECTORY}/conf.py" @ONLY)
1659  else ()
1660  message (FATAL_ERROR "Missing Sphinx configuration file ${SPHINX_CONFIG_FILE}!")
1661  endif ()
1662  # add target to build documentation
1663  set (OPTIONS -a -N -n)
1664  if (NOT BASIS_VERBOSE)
1665  list (APPEND OPTIONS "-q")
1666  endif ()
1667  foreach (TAG IN LISTS SPHINX_TAG)
1668  list (APPEND OPTIONS "-t" "${TAG}")
1669  endforeach ()
1670  add_custom_target (${TARGET_UID}_all) # target to run all builders
1671  foreach (BUILDER IN LISTS SPHINX_BUILDERS)
1672  set (SPHINX_BUILDER "${BUILDER}")
1673  set (SPHINX_POST_COMMAND)
1674  if (BUILDER MATCHES "pdf|texinfo")
1675  if (UNIX)
1676  set (SPHINX_MAKE_COMMAND "make")
1677  if (BUILDER MATCHES "pdf")
1678  set (SPHINX_BUILDER "latex")
1679  configure_file ("${BASIS_MODULE_PATH}/sphinx_make.sh.in" "${SPHINX_CONFIG_DIRECTORY}/make.sh" @ONLY)
1680  set (SPHINX_MAKE_COMMAND "${SPHINX_CONFIG_DIRECTORY}/make.sh")
1681  execute_process (COMMAND chmod +x "${SPHINX_CONFIG_DIRECTORY}/make.sh")
1682  endif ()
1683  set (SPHINX_POST_COMMAND COMMAND "${SPHINX_MAKE_COMMAND}" -C "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}")
1684  elseif (BUILDER MATCHES "pdf")
1685  message (WARNING "Target ${TARGET_UID} requires the execution of pdflatex which is currently"
1686  " only executed after sphinx-build on Unix platforms. On Windows, pdflatex"
1687  " must be executed manually in the directory\n\n\t${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}")
1688  endif ()
1689  endif ()
1691  add_custom_target (
1692  ${TARGET_UID}_${BUILDER}
1693  "${Sphinx_PYTHON_EXECUTABLE}" ${Sphinx_PYTHON_OPTIONS}
1694  "${Sphinx-build_EXECUTABLE}" ${OPTIONS}
1695  -b ${SPHINX_BUILDER}
1696  -c "${SPHINX_CONFIG_DIRECTORY}"
1697  -d "${SPHINX_CONFIG_DIRECTORY}/doctrees"
1698  "${SPHINX_SOURCE_DIRECTORY}"
1699  "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}"
1700  ${SPHINX_POST_COMMAND}
1701  ${OPTDEPENDS}
1702  WORKING_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
1703  COMMENT "Building documentation ${TARGET_UID} (${BUILDER})..."
1704  )
1705  elseif (UNIX)
1706  add_custom_target (
1707  ${TARGET_UID}_${BUILDER}
1708  "${Sphinx-build_EXECUTABLE}" ${OPTIONS}
1709  -b ${SPHINX_BUILDER}
1710  -c "${SPHINX_CONFIG_DIRECTORY}"
1711  -d "${SPHINX_CONFIG_DIRECTORY}/doctrees"
1712  "${SPHINX_SOURCE_DIRECTORY}"
1713  "${SPHINX_OUTPUT_DIRECTORY}/${SPHINX_BUILDER}"
1714  ${SPHINX_POST_COMMAND}
1715  ${OPTDEPENDS}
1716  WORKING_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
1717  COMMENT "Building documentation ${TARGET_UID} (${BUILDER})..."
1718  )
1719  else ()
1720  message (FATAL_ERROR "Python executable required to run Sphinx could not be determined by FindSphinx.cmake!"
1721  " Set the advanced PYTHON_EXECUTABLE variable and try again.")
1722  endif ()
1723  if (SPHINX_DEPENDS)
1724  add_dependencies (${TARGET_UID}_${BUILDER} ${SPHINX_DEPENDS})
1725  endif ()
1726  add_dependencies (${TARGET_UID}_all ${TARGET_UID}_${BUILDER})
1727  # cleanup on "make clean"
1728  set_property (
1729  DIRECTORY
1730  APPEND PROPERTY
1731  ADDITIONAL_MAKE_CLEAN_FILES
1732  "${SPHINX_OUTPUT_DIRECTORY}"
1733  )
1734  endforeach ()
1735  # add general target which depends on default builder only
1736  if (BUILD_DOCUMENTATION AND BASIS_ALL_DOC)
1737  add_custom_target (${TARGET_UID} ALL)
1738  else ()
1739  add_custom_target (${TARGET_UID})
1740  endif ()
1741  add_dependencies (${TARGET_UID} ${TARGET_UID}_${SPHINX_DEFAULT_BUILDER})
1742  # add general "doc" target
1743  if (NOT SPHINX_EXCLUDE_FROM_DOC)
1744  if (NOT TARGET doc)
1745  add_custom_target (doc)
1746  endif ()
1747  add_dependencies (doc ${TARGET_UID}_${SPHINX_DEFAULT_BUILDER})
1748  endif ()
1749  # memorize important target properties
1751  ${TARGET_UID}
1752  PROPERTIES
1753  BASIS_TYPE Sphinx
1754  BUILDERS "${SPHINX_BUILDERS}"
1755  SOURCE_DIRECTORY "${SPHINX_SOURCE_DIRECTORY}"
1756  OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}"
1757  CONFIG_DIRECTORY "${SPHINX_CONFIG_DIRECTORY}"
1758  )
1759  foreach (b IN LISTS SPHINX_BUILDERS)
1760  string (TOUPPER ${b} B)
1761  set_target_properties (${TARGET_UID} PROPERTIES ${B}_INSTALL_DIRECTORY "${SPHINX_${B}_DESTINATION}")
1762  endforeach ()
1763  # cleanup on "make clean"
1764  set_property (
1765  DIRECTORY
1766  APPEND PROPERTY
1767  ADDITIONAL_MAKE_CLEAN_FILES
1768  "${SPHINX_CONFIG_DIRECTORY}/doctrees"
1769  )
1770  # install documentation
1771  install (
1772  CODE
1773  "
1774  set (HTML_DESTINATION \"${SPHINX_HTML_DESTINATION}\")
1775  set (PDF_DESTINATION \"${SPHINX_PDF_DESTINATION}\")
1776  set (LATEX_DESTINATION \"${SPHINX_LATEX_DESTINATION}\")
1777  set (MAN_DESTINATION \"${SPHINX_MAN_DESTINATION}\")
1778  set (TEXINFO_DESTINATION \"${SPHINX_TEXINFO_DESTINATION}\")
1779  set (TEXT_DESTINATION \"${SPHINX_TEXT_DESTINATION}\")
1780 
1781  function (install_sphinx_doc BUILDER)
1782  if (BUILDER MATCHES \"pdf\")
1783  set (SPHINX_BUILDER \"latex\")
1784  else ()
1785  set (SPHINX_BUILDER \"\${BUILDER}\")
1786  endif ()
1787  string (TOUPPER \"\${BUILDER}\" BUILDER_U)
1788  set (CMAKE_INSTALL_PREFIX \"\${\${BUILDER_U}_DESTINATION}\")
1789  if (NOT CMAKE_INSTALL_PREFIX)
1790  return ()
1791  elseif (NOT IS_ABSOLUTE \"\${CMAKE_INSTALL_PREFIX}\")
1792  set (CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}/\${CMAKE_INSTALL_PREFIX}\")
1793  endif ()
1794  set (EXT)
1795  if (BUILDER MATCHES \"pdf\")
1796  set (EXT \".pdf\")
1797  elseif (BUILDER MATCHES \"man\")
1798  set (EXT \".?\")
1799  elseif (BUILDER MATCHES \"texinfo\")
1800  set (EXT \".info\")
1801  endif ()
1802  file (
1803  GLOB_RECURSE
1804  FILES
1805  RELATIVE \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}\"
1806  \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/*\${EXT}\"
1807  )
1808  foreach (F IN LISTS FILES)
1809  if (NOT F MATCHES \"\\\\.buildinfo\")
1810  set (RC 1)
1811  if (NOT BUILDER MATCHES \"texinfo\")
1812  execute_process (
1813  COMMAND \"${CMAKE_COMMAND}\" -E compare_files
1814  \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
1815  \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
1816  RESULT_VARIABLE RC
1817  OUTPUT_QUIET
1818  ERROR_QUIET
1819  )
1820  endif ()
1821  if (RC EQUAL 0)
1822  message (STATUS \"Up-to-date: \${CMAKE_INSTALL_PREFIX}/\${F}\")
1823  else ()
1824  message (STATUS \"Installing: \${CMAKE_INSTALL_PREFIX}/\${F}\")
1825  if (BUILDER MATCHES \"texinfo\")
1826  if (EXISTS \"\${CMAKE_INSTALL_PREFIX}/dir\")
1827  execute_process (
1828  COMMAND install-info
1829  \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
1830  \"\${CMAKE_INSTALL_PREFIX}/dir\"
1831  RESULT_VARIABLE RC
1832  OUTPUT_QUIET
1833  ERROR_QUIET
1834  )
1835  else ()
1836  execute_process (
1837  COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
1838  \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
1839  \"\${CMAKE_INSTALL_PREFIX}/dir\"
1840  RESULT_VARIABLE RC
1841  OUTPUT_QUIET
1842  ERROR_QUIET
1843  )
1844  endif ()
1845  else ()
1846  execute_process (
1847  COMMAND \"${CMAKE_COMMAND}\" -E copy_if_different
1848  \"${SPHINX_OUTPUT_DIRECTORY}/\${SPHINX_BUILDER}/\${F}\"
1849  \"\${CMAKE_INSTALL_PREFIX}/\${F}\"
1850  RESULT_VARIABLE RC
1851  OUTPUT_QUIET
1852  ERROR_QUIET
1853  )
1854  endif ()
1855  if (RC EQUAL 0)
1856  # also remember .info files for deinstallation via install-info --delete
1857  list (APPEND CMAKE_INSTALL_MANIFEST_FILES \"\${CMAKE_INSTALL_PREFIX}/\${F}\")
1858  else ()
1859  message (STATUS \"Failed to install \${CMAKE_INSTALL_PREFIX}/\${F}\")
1860  endif ()
1861  endif ()
1862  endif ()
1863  endforeach ()
1864  endfunction ()
1865 
1866  set (BUILDERS \"${SPHINX_BUILDERS}\")
1867  set (HTML_INSTALLED FALSE)
1868  foreach (BUILDER IN LISTS BUILDERS)
1869  if ((BUILDER MATCHES \"html\" AND NOT HTML_INSTALLED) OR
1870  (BUILDER MATCHES \"texinfo|man\" AND UNIX) OR
1871  NOT BUILDER MATCHES \"html|texinfo|man|latex|linkcheck\")
1872  install_sphinx_doc (\${BUILDER})
1873  if (BUILDER MATCHES \"html\")
1874  set (HTML_INSTALLED TRUE)
1875  endif ()
1876  endif ()
1877  endforeach ()
1878  "
1879  )
1880  # done
1881  message (STATUS "Adding documentation ${TARGET_UID}... - done")
1882 endfunction ()
1883 
1884 # ============================================================================
1885 # change log
1886 # ============================================================================
1887 
1888 # ----------------------------------------------------------------------------
1889 ## @brief Add target for generation of ChangeLog file.
1890 #
1891 # The ChangeLog is either generated from the Subversion or Git log depending
1892 # on which revision control system is used by the project. Moreover, the
1893 # project's source directory must be either a Subversion working copy or
1894 # the root of a Git repository, respectively. In case of Subversion, if the
1895 # command-line tool svn2cl(.sh) is installed, it is used to output a nicer
1896 # formatted change log.
1897 function (basis_add_changelog)
1898  _basis_make_target_uid (TARGET_UID changelog)
1899 
1900  option (BUILD_CHANGELOG "Request build and/or installation of the ChangeLog." OFF)
1901  mark_as_advanced (BUILD_CHANGELOG)
1902  set (CHANGELOG_FILE "${PROJECT_BINARY_DIR}/ChangeLog")
1903 
1904  message (STATUS "Adding ChangeLog...")
1905 
1906  if (NOT PROJECT_IS_MODULE AND BUILD_CHANGELOG)
1907  set (_ALL "ALL")
1908  else ()
1909  set (_ALL)
1910  endif ()
1911 
1912  set (DISABLE_BUILD_CHANGELOG FALSE)
1913 
1914  # --------------------------------------------------------------------------
1915  # generate ChangeLog from Subversion history
1916  if (EXISTS "${PROJECT_SOURCE_DIR}/.svn")
1917  find_package (Subversion QUIET)
1918  if (Subversion_FOUND)
1919 
1920  if (_ALL)
1921  message ("Generation of ChangeLog enabled as part of ALL."
1922  " Be aware that the ChangeLog generation from the Subversion"
1923  " commit history can take several minutes and may require the"
1924  " input of your Subversion repository credentials during the"
1925  " build. If you would like to build the ChangeLog separate"
1926  " from the rest of the software package, disable the option"
1927  " BUILD_CHANGELOG. You can then build the changelog target"
1928  " separate from ALL.")
1929  endif ()
1930 
1931  # using svn2cl command
1932  find_program (
1933  SVN2CL_EXECUTABLE
1934  NAMES svn2cl svn2cl.sh
1935  DOC "The command line tool svn2cl."
1936  )
1937  mark_as_advanced (SVN2CL_EXECUTABLE)
1938  if (SVN2CL_EXECUTABLE)
1939  add_custom_target (
1940  ${TARGET_UID} ${_ALL}
1941  COMMAND "${SVN2CL_EXECUTABLE}"
1942  "--output=${CHANGELOG_FILE}"
1943  "--linelen=79"
1944  "--reparagraph"
1945  "--group-by-day"
1946  "--include-actions"
1947  "--separate-daylogs"
1948  "${PROJECT_SOURCE_DIR}"
1949  COMMAND "${CMAKE_COMMAND}"
1950  "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN2CL
1951  -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
1952  WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
1953  COMMENT "Generating ChangeLog from Subversion log (using svn2cl)..."
1954  )
1955  # otherwise, use svn log output directly
1956  else ()
1957  add_custom_target (
1958  ${TARGET_UID} ${_ALL}
1959  COMMAND "${CMAKE_COMMAND}"
1960  "-DCOMMAND=${Subversion_SVN_EXECUTABLE};log"
1961  "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
1962  "-DOUTPUT_FILE=${CHANGELOG_FILE}"
1964  COMMAND "${CMAKE_COMMAND}"
1965  "-DCHANGELOG_FILE:FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=SVN
1966  -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
1967  COMMENT "Generating ChangeLog from Subversion log..."
1968  VERBATIM
1969  )
1970  endif ()
1971 
1972  else ()
1973  if (BASIS_VERBOSE)
1974  message (STATUS "Project is SVN working copy but Subversion executable was not found."
1975  " Generation of ChangeLog disabled.")
1976  endif ()
1977  set (DISABLE_BUILD_CHANGELOG TRUE)
1978  endif ()
1979 
1980  # --------------------------------------------------------------------------
1981  # generate ChangeLog from Git log
1982  elseif (EXISTS "${PROJECT_SOURCE_DIR}/.git")
1983  find_package (Git QUIET)
1984  if (GIT_FOUND)
1985 
1986  add_custom_target (
1987  ${TARGET_UID} ${_ALL}
1988  COMMAND "${CMAKE_COMMAND}"
1989  "-DCOMMAND=${GIT_EXECUTABLE};log;--date-order;--date=short;--pretty=format:%ad\ \ %an%n%n%w(79,8,10)* %s%n%n%b%n"
1990  "-DWORKING_DIRECTORY=${PROJECT_SOURCE_DIR}"
1991  "-DOUTPUT_FILE=${CHANGELOG_FILE}"
1993  COMMAND "${CMAKE_COMMAND}"
1994  "-DCHANGELOG_FILE=${CHANGELOG_FILE}" -DINPUTFORMAT=GIT
1995  -P "${BASIS_MODULE_PATH}/PostprocessChangeLog.cmake"
1996  COMMENT "Generating ChangeLog from Git log..."
1997  VERBATIM
1998  )
1999 
2000  else ()
2001  if (BASIS_VERBOSE)
2002  message (STATUS "Project is Git repository but Git executable was not found."
2003  " Generation of ChangeLog disabled.")
2004  endif ()
2005  set (DISABLE_BUILD_CHANGELOG TRUE)
2006  endif ()
2007 
2008  # --------------------------------------------------------------------------
2009  # neither SVN nor Git repository
2010  else ()
2011  if (BASIS_VERBOSE)
2012  message (STATUS "Project source directory ${PROJECT_SOURCE_DIR} is neither"
2013  " SVN working copy nor Git repository. Generation of ChangeLog disabled.")
2014  endif ()
2015  set (DISABLE_BUILD_CHANGELOG TRUE)
2016  endif ()
2017 
2018  # --------------------------------------------------------------------------
2019  # disable changelog target
2020  if (DISABLE_BUILD_CHANGELOG)
2021  set (BUILD_CHANGELOG OFF CACHE INTERNAL "" FORCE)
2022  message (STATUS "Adding ChangeLog... - skipped")
2023  return ()
2024  endif ()
2025 
2026  # --------------------------------------------------------------------------
2027  # cleanup on "make clean"
2028  set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CHANGELOG_FILE}")
2029 
2030  # --------------------------------------------------------------------------
2031  # install ChangeLog
2032  get_filename_component (CHANGELOG_NAME "${CHANGELOG_FILE}" NAME)
2033  if (PROJECT_IS_MODULE)
2034  set (CHANGELOG_NAME "${CHANGELOG_NAME}-${PROJECT_NAME}")
2035  endif ()
2036 
2037  install (
2038  FILES "${CHANGELOG_FILE}"
2039  DESTINATION "${TOPLEVEL_INSTALL_DOC_DIR}"
2040  COMPONENT "${BASIS_RUNTIME_COMPONENT}"
2041  RENAME "${CHANGELOG_NAME}"
2042  OPTIONAL
2043  )
2044 
2045  message (STATUS "Adding ChangeLog... - done")
2046 endfunction ()
function basis_install_doc(in SOURCE, in ARGN)
Install documentation file(s).
function basis_get_target_uid(out TARGET_UID, in TARGET_NAME)
Get "global" target name, i.e., actual CMake target name.
function set_target_properties(in ARGN)
Set target property.
cmake BASIS_SPHINX_HTML_THEME
Default Sphinx theme.
function basis_get_relative_path(out REL, in BASE, in PATH)
Get path relative to a given base directory.
function is(in result, in expected, in name)
Test whether a given result is equal to the expected result.
def which(command, path=None, verbose=0, exts=None)
Definition: which.py:257
function basis_get_project_property(out VARIABLE, in ARGN)
Get project-global property value.
cmake PROJECT_INCLUDE_DIRS
Absolute paths to directories of public header files in source tree.
function basis_add_sphinx_doc(in TARGET_NAME, in ARGN)
Add documentation target to be generated by Sphinx (sphinx-build).
cmake SOURCES
Definition: glob.cmake:52
function basis_check_target_name(in TARGET_NAME)
Checks whether a given name is a valid target name.
cmake BINARY_INCLUDE_DIR
Absolute path to output directory for configured public header files.
cmake Sphinx_PYTHON_EXECUTABLE
cmake INSTALL_MAN_DIR
Path of installation directory for man pages relative to CMAKE_INSTALL_PREFIX.
function basis_add_doc(in TARGET_NAME, in ARGN)
Add documentation target.
string COPYRIGHT
Default copyright of executables.
Definition: utilities.sh:91
cmake BUILDERS
cmake NAME
cmake PROJECT_MODULES_ENABLED
option BUILD_DOCUMENTATION
Request build/installation of documentation.
function basis_add_doxygen_doc(in TARGET_NAME, in ARGN)
Add documentation to be generated by Doxygen.
macro basis_get_filename_component()
Alias for the overwritten get_filename_component() function.
cmake BASIS_ALL_DOC
Advanced non-cached variable to request build of documentation targets as part of ALL target...
function basis_join(in VALUES, in DELIMITER, out OUTPUT)
Concatenates all list elements into a single delimited string.
function abspath(in path)
Get absolute path given a relative path.
function basis_make_target_uid(out TARGET_UID, in TARGET_NAME)
Make target UID from given target name.
cmake CONFIG_FILE
Name of the CMake package configuration file.
#define UNIX
Whether the sources are compiled on a Unix-based system.
Definition: config.h:60
cmake COMMAND
cmake FILE
cmake PROJECT_CODE_DIRS
Absolute paths to directories of project sources in source tree.
function basis_list_to_delimited_string(out STR, in DELIM, in ARGN)
Concatenates all list elements into a single delimited string.
function basis_add_changelog()
Add target for generation of ChangeLog file.
cmake BASIS_SCRIPT_EXECUTE_PROCESS
Script used to execute a process in CMake script mode.
option BASIS_VERBOSE
Default Sphinx theme options.
function like(in result, in pattern, in name)
Test whether a given result matches an expected pattern.
cmake BASIS_RUNTIME_COMPONENT
Default component used for executables when no component is specified.
function basis_install_directory(in ARGN)
Install content of source directory excluding typical files.
cmake __BASIS_DOCTOOLS_INCLUDED
Definition: DocTools.cmake:21
cmake INSTALL_TEXINFO_DIR
Path of Texinfo files relative to CMAKE_INSTALL_PREFIX.
macro find_package()
Overloaded find_package() command.
function get_filename_component(inout ARGN)
Fixes CMake&#39;s get_filename_component() command.
cmake BASIS_DIR
function basis_get_target_location(out VAR, in TARGET_NAME, in PART)
Get location of build target output file(s).