1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4#[=======================================================================[.rst:
5FindDoxygen
6-----------
7
8Doxygen is a documentation generation tool (see http://www.doxygen.org).
9This module looks for Doxygen and some optional tools it supports:
10
11``dot``
12  `Graphviz <http://graphviz.org>`_ ``dot`` utility used to render various
13  graphs.
14``mscgen``
15  `Message Chart Generator <http://www.mcternan.me.uk/mscgen/>`_ utility used
16  by Doxygen's ``\msc`` and ``\mscfile`` commands.
17``dia``
18  `Dia <https://wiki.gnome.org/Apps/Dia>`_ the diagram editor used by Doxygen's
19  ``\diafile`` command.
20
21.. versionadded:: 3.9
22  These tools are available as components in the :command:`find_package` command.
23  For example:
24
25.. code-block:: cmake
26
27  # Require dot, treat the other components as optional
28  find_package(Doxygen
29               REQUIRED dot
30               OPTIONAL_COMPONENTS mscgen dia)
31
32The following variables are defined by this module:
33
34.. variable:: DOXYGEN_FOUND
35
36  True if the ``doxygen`` executable was found.
37
38.. variable:: DOXYGEN_VERSION
39
40  The version reported by ``doxygen --version``.
41
42.. versionadded:: 3.9
43  The module defines ``IMPORTED`` targets for Doxygen and each component found.
44  These can be used as part of custom commands, etc. and should be preferred over
45  old-style (and now deprecated) variables like ``DOXYGEN_EXECUTABLE``. The
46  following import targets are defined if their corresponding executable could be
47  found (the component import targets will only be defined if that component was
48  requested):
49
50::
51
52  Doxygen::doxygen
53  Doxygen::dot
54  Doxygen::mscgen
55  Doxygen::dia
56
57
58Functions
59^^^^^^^^^
60
61.. command:: doxygen_add_docs
62
63  .. versionadded:: 3.9
64
65  This function is intended as a convenience for adding a target for generating
66  documentation with Doxygen. It aims to provide sensible defaults so that
67  projects can generally just provide the input files and directories and that
68  will be sufficient to give sensible results. The function supports the
69  ability to customize the Doxygen configuration used to build the
70  documentation.
71
72  ::
73
74    doxygen_add_docs(targetName
75        [filesOrDirs...]
76        [ALL]
77        [USE_STAMP_FILE]
78        [WORKING_DIRECTORY dir]
79        [COMMENT comment])
80
81  The function constructs a ``Doxyfile`` and defines a custom target that runs
82  Doxygen on that generated file. The listed files and directories are used as
83  the ``INPUT`` of the generated ``Doxyfile`` and they can contain wildcards.
84  Any files that are listed explicitly will also be added as ``SOURCES`` of the
85  custom target so they will show up in an IDE project's source list.
86
87  So that relative input paths work as expected, by default the working
88  directory of the Doxygen command will be the current source directory (i.e.
89  :variable:`CMAKE_CURRENT_SOURCE_DIR`). This can be overridden with the
90  ``WORKING_DIRECTORY`` option to change the directory used as the relative
91  base point. Note also that Doxygen's default behavior is to strip the working
92  directory from relative paths in the generated documentation (see the
93  ``STRIP_FROM_PATH`` `Doxygen config option
94  <http://www.doxygen.org/manual/config.html>`_ for details).
95
96  If provided, the optional ``comment`` will be passed as the ``COMMENT`` for
97  the :command:`add_custom_target` command used to create the custom target
98  internally.
99
100  .. versionadded:: 3.12
101    If ``ALL`` is set, the target will be added to the default build target.
102
103  .. versionadded:: 3.16
104    If ``USE_STAMP_FILE`` is set, the custom command defined by this function will
105    create a stamp file with the name ``<targetName>.stamp`` in the current
106    binary directory whenever doxygen is re-run.  With this option present, all
107    items in ``<filesOrDirs>`` must be files (i.e. no directories, symlinks or
108    wildcards) and each of the files must exist at the time
109    ``doxygen_add_docs()`` is called.  An error will be raised if any of the
110    items listed is missing or is not a file when ``USE_STAMP_FILE`` is given.
111    A dependency will be created on each of the files so that doxygen will only
112    be re-run if one of the files is updated.  Without the ``USE_STAMP_FILE``
113    option, doxygen will always be re-run if the ``<targetName>`` target is built
114    regardless of whether anything listed in ``<filesOrDirs>`` has changed.
115
116  The contents of the generated ``Doxyfile`` can be customized by setting CMake
117  variables before calling ``doxygen_add_docs()``. Any variable with a name of
118  the form ``DOXYGEN_<tag>`` will have its value substituted for the
119  corresponding ``<tag>`` configuration option in the ``Doxyfile``. See the
120  `Doxygen documentation <http://www.doxygen.org/manual/config.html>`_ for the
121  full list of supported configuration options.
122
123  Some of Doxygen's defaults are overridden to provide more appropriate
124  behavior for a CMake project. Each of the following will be explicitly set
125  unless the variable already has a value before ``doxygen_add_docs()`` is
126  called (with some exceptions noted):
127
128  .. variable:: DOXYGEN_HAVE_DOT
129
130    Set to ``YES`` if the ``dot`` component was requested and it was found,
131    ``NO`` otherwise. Any existing value of ``DOXYGEN_HAVE_DOT`` is ignored.
132
133  .. variable:: DOXYGEN_DOT_MULTI_TARGETS
134
135    Set to ``YES`` by this module (note that this requires a ``dot`` version
136    newer than 1.8.10). This option is only meaningful if ``DOXYGEN_HAVE_DOT``
137    is also set to ``YES``.
138
139  .. variable:: DOXYGEN_GENERATE_LATEX
140
141    Set to ``NO`` by this module.
142
143  .. variable:: DOXYGEN_WARN_FORMAT
144
145    For Visual Studio based generators, this is set to the form recognized by
146    the Visual Studio IDE: ``$file($line) : $text``. For all other generators,
147    Doxygen's default value is not overridden.
148
149  .. variable:: DOXYGEN_PROJECT_NAME
150
151    Populated with the name of the current project (i.e.
152    :variable:`PROJECT_NAME`).
153
154  .. variable:: DOXYGEN_PROJECT_NUMBER
155
156    Populated with the version of the current project (i.e.
157    :variable:`PROJECT_VERSION`).
158
159  .. variable:: DOXYGEN_PROJECT_BRIEF
160
161    Populated with the description of the current project (i.e.
162    :variable:`PROJECT_DESCRIPTION`).
163
164  .. variable:: DOXYGEN_INPUT
165
166    Projects should not set this variable. It will be populated with the set of
167    files and directories passed to ``doxygen_add_docs()``, thereby providing
168    consistent behavior with the other built-in commands like
169    :command:`add_executable`, :command:`add_library` and
170    :command:`add_custom_target`. If a variable named ``DOXYGEN_INPUT`` is set
171    by the project, it will be ignored and a warning will be issued.
172
173  .. variable:: DOXYGEN_RECURSIVE
174
175    Set to ``YES`` by this module.
176
177  .. variable:: DOXYGEN_EXCLUDE_PATTERNS
178
179    If the set of inputs includes directories, this variable will specify
180    patterns used to exclude files from them. The following patterns are added
181    by ``doxygen_add_docs()`` to ensure CMake-specific files and directories
182    are not included in the input. If the project sets
183    ``DOXYGEN_EXCLUDE_PATTERNS``, those contents are merged with these
184    additional patterns rather than replacing them:
185
186    ::
187
188      */.git/*
189      */.svn/*
190      */.hg/*
191      */CMakeFiles/*
192      */_CPack_Packages/*
193      DartConfiguration.tcl
194      CMakeLists.txt
195      CMakeCache.txt
196
197  .. variable:: DOXYGEN_OUTPUT_DIRECTORY
198
199    Set to :variable:`CMAKE_CURRENT_BINARY_DIR` by this module. Note that if
200    the project provides its own value for this and it is a relative path, it
201    will be converted to an absolute path relative to the current binary
202    directory. This is necessary because doxygen will normally be run from a
203    directory within the source tree so that relative source paths work as
204    expected. If this directory does not exist, it will be recursively created
205    prior to executing the doxygen commands.
206
207To change any of these defaults or override any other Doxygen config option,
208set relevant variables before calling ``doxygen_add_docs()``. For example:
209
210  .. code-block:: cmake
211
212    set(DOXYGEN_GENERATE_HTML NO)
213    set(DOXYGEN_GENERATE_MAN YES)
214
215    doxygen_add_docs(
216        doxygen
217        ${PROJECT_SOURCE_DIR}
218        COMMENT "Generate man pages"
219    )
220
221A number of Doxygen config options accept lists of values, but Doxygen requires
222them to be separated by whitespace. CMake variables hold lists as a string with
223items separated by semi-colons, so a conversion needs to be performed. The
224``doxygen_add_docs()`` command specifically checks the following Doxygen config
225options and will convert their associated CMake variable's contents into the
226required form if set. CMake variables are named ``DOXYGEN_<name>`` for the
227Doxygen settings specified here.
228
229::
230
231  ABBREVIATE_BRIEF
232  ALIASES
233  CITE_BIB_FILES
234  DIAFILE_DIRS
235  DOTFILE_DIRS
236  DOT_FONTPATH
237  ENABLED_SECTIONS
238  EXAMPLE_PATH
239  EXAMPLE_PATTERNS
240  EXCLUDE
241  EXCLUDE_PATTERNS
242  EXCLUDE_SYMBOLS
243  EXPAND_AS_DEFINED
244  EXTENSION_MAPPING
245  EXTRA_PACKAGES
246  EXTRA_SEARCH_MAPPINGS
247  FILE_PATTERNS
248  FILTER_PATTERNS
249  FILTER_SOURCE_PATTERNS
250  HTML_EXTRA_FILES
251  HTML_EXTRA_STYLESHEET
252  IGNORE_PREFIX
253  IMAGE_PATH
254  INCLUDE_FILE_PATTERNS
255  INCLUDE_PATH
256  INPUT
257  LATEX_EXTRA_FILES
258  LATEX_EXTRA_STYLESHEET
259  MATHJAX_EXTENSIONS
260  MSCFILE_DIRS
261  PLANTUML_INCLUDE_PATH
262  PREDEFINED
263  QHP_CUST_FILTER_ATTRS
264  QHP_SECT_FILTER_ATTRS
265  STRIP_FROM_INC_PATH
266  STRIP_FROM_PATH
267  TAGFILES
268  TCL_SUBST
269
270The following single value Doxygen options will be quoted automatically
271if they contain at least one space:
272
273::
274
275  CHM_FILE
276  DIA_PATH
277  DOCBOOK_OUTPUT
278  DOCSET_FEEDNAME
279  DOCSET_PUBLISHER_NAME
280  DOT_FONTNAME
281  DOT_PATH
282  EXTERNAL_SEARCH_ID
283  FILE_VERSION_FILTER
284  GENERATE_TAGFILE
285  HHC_LOCATION
286  HTML_FOOTER
287  HTML_HEADER
288  HTML_OUTPUT
289  HTML_STYLESHEET
290  INPUT_FILTER
291  LATEX_FOOTER
292  LATEX_HEADER
293  LATEX_OUTPUT
294  LAYOUT_FILE
295  MAN_OUTPUT
296  MAN_SUBDIR
297  MATHJAX_CODEFILE
298  MSCGEN_PATH
299  OUTPUT_DIRECTORY
300  PERL_PATH
301  PLANTUML_JAR_PATH
302  PROJECT_BRIEF
303  PROJECT_LOGO
304  PROJECT_NAME
305  QCH_FILE
306  QHG_LOCATION
307  QHP_CUST_FILTER_NAME
308  QHP_VIRTUAL_FOLDER
309  RTF_EXTENSIONS_FILE
310  RTF_OUTPUT
311  RTF_STYLESHEET_FILE
312  SEARCHDATA_FILE
313  USE_MDFILE_AS_MAINPAGE
314  WARN_FORMAT
315  WARN_LOGFILE
316  XML_OUTPUT
317
318.. versionadded:: 3.11
319  There are situations where it may be undesirable for a particular config option
320  to be automatically quoted by ``doxygen_add_docs()``, such as ``ALIASES`` which
321  may need to include its own embedded quoting.  The ``DOXYGEN_VERBATIM_VARS``
322  variable can be used to specify a list of Doxygen variables (including the
323  leading ``DOXYGEN_`` prefix) which should not be quoted.  The project is then
324  responsible for ensuring that those variables' values make sense when placed
325  directly in the Doxygen input file.  In the case of list variables, list items
326  are still separated by spaces, it is only the automatic quoting that is
327  skipped.  For example, the following allows ``doxygen_add_docs()`` to apply
328  quoting to ``DOXYGEN_PROJECT_BRIEF``, but not each item in the
329  ``DOXYGEN_ALIASES`` list (:ref:`bracket syntax <Bracket Argument>` can also
330  be used to make working with embedded quotes easier):
331
332.. code-block:: cmake
333
334  set(DOXYGEN_PROJECT_BRIEF "String with spaces")
335  set(DOXYGEN_ALIASES
336      [[somealias="@some_command param"]]
337      "anotherAlias=@foobar"
338  )
339  set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES)
340
341The resultant ``Doxyfile`` will contain the following lines:
342
343.. code-block:: text
344
345  PROJECT_BRIEF = "String with spaces"
346  ALIASES       = somealias="@some_command param" anotherAlias=@foobar
347
348
349Deprecated Result Variables
350^^^^^^^^^^^^^^^^^^^^^^^^^^^
351
352.. deprecated:: 3.9
353
354For compatibility with previous versions of CMake, the following variables
355are also defined but they are deprecated and should no longer be used:
356
357.. variable:: DOXYGEN_EXECUTABLE
358
359  The path to the ``doxygen`` command. If projects need to refer to the
360  ``doxygen`` executable directly, they should use the ``Doxygen::doxygen``
361  import target instead.
362
363.. variable:: DOXYGEN_DOT_FOUND
364
365  True if the ``dot`` executable was found.
366
367.. variable:: DOXYGEN_DOT_EXECUTABLE
368
369  The path to the ``dot`` command. If projects need to refer to the ``dot``
370  executable directly, they should use the ``Doxygen::dot`` import target
371  instead.
372
373.. variable:: DOXYGEN_DOT_PATH
374
375  The path to the directory containing the ``dot`` executable as reported in
376  ``DOXYGEN_DOT_EXECUTABLE``. The path may have forward slashes even on Windows
377  and is not suitable for direct substitution into a ``Doxyfile.in`` template.
378  If you need this value, get the :prop_tgt:`IMPORTED_LOCATION` property of the
379  ``Doxygen::dot`` target and use :command:`get_filename_component` to extract
380  the directory part of that path. You may also want to consider using
381  :command:`file(TO_NATIVE_PATH)` to prepare the path for a Doxygen
382  configuration file.
383
384
385Deprecated Hint Variables
386^^^^^^^^^^^^^^^^^^^^^^^^^
387
388.. deprecated:: 3.9
389
390.. variable:: DOXYGEN_SKIP_DOT
391
392  This variable has no effect for the component form of ``find_package``.
393  In backward compatibility mode (i.e. without components list) it prevents
394  the finder module from searching for Graphviz's ``dot`` utility.
395
396#]=======================================================================]
397
398cmake_policy(PUSH)
399cmake_policy(SET CMP0054 NEW) # quoted if arguments
400cmake_policy(SET CMP0057 NEW) # if IN_LIST
401
402# For backwards compatibility support
403if(Doxygen_FIND_QUIETLY)
404    set(DOXYGEN_FIND_QUIETLY TRUE)
405endif()
406
407# ===== Rationale for OS X AppBundle mods below =====
408#  With the OS X GUI version, Doxygen likes to be installed to /Applications
409#  and it contains the doxygen executable in the bundle. In the versions I've
410#  seen, it is located in Resources, but in general, more often binaries are
411#  located in MacOS.
412#
413#  NOTE: The official Doxygen.app distributed for OS X uses non-standard
414#  conventions. Instead of the command-line "doxygen" tool being placed in
415#  Doxygen.app/Contents/MacOS, "Doxywizard" is placed there instead and
416#  "doxygen" is placed in Contents/Resources.  This is most likely done
417#  so that something happens when people double-click on the Doxygen.app
418#  package. Unfortunately, CMake gets confused by this as when it sees the
419#  bundle it uses "Doxywizard" as the executable to use instead of
420#  "doxygen". Therefore to work-around this issue we temporarily disable
421#  the app-bundle feature, just for this CMake module:
422#
423if(APPLE)
424    # Save the old setting
425    set(TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE})
426    # Disable the App-bundle detection feature
427    set(CMAKE_FIND_APPBUNDLE "NEVER")
428endif()
429# FYI:
430# In older versions of OS X Doxygen, dot was included with the Doxygen bundle,
431# but newer versions require you to download Graphviz.app which contains "dot"
432# or use something like homebrew.
433# ============== End OSX stuff ================
434
435#
436# Find Doxygen...
437#
438macro(_Doxygen_find_doxygen)
439    find_program(
440        DOXYGEN_EXECUTABLE
441        NAMES doxygen
442        PATHS
443            "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\doxygen_is1;Inno Setup: App Path]/bin"
444            /Applications/Doxygen.app/Contents/Resources
445            /Applications/Doxygen.app/Contents/MacOS
446            /Applications/Utilities/Doxygen.app/Contents/Resources
447            /Applications/Utilities/Doxygen.app/Contents/MacOS
448        DOC "Doxygen documentation generation tool (http://www.doxygen.org)"
449    )
450    mark_as_advanced(DOXYGEN_EXECUTABLE)
451
452    if(DOXYGEN_EXECUTABLE)
453        execute_process(
454            COMMAND "${DOXYGEN_EXECUTABLE}" --version
455            OUTPUT_VARIABLE DOXYGEN_VERSION
456            OUTPUT_STRIP_TRAILING_WHITESPACE
457            RESULT_VARIABLE _Doxygen_version_result
458        )
459        if(_Doxygen_version_result)
460            message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}")
461        endif()
462
463        # Create an imported target for Doxygen
464        if(NOT TARGET Doxygen::doxygen)
465            add_executable(Doxygen::doxygen IMPORTED GLOBAL)
466            set_target_properties(Doxygen::doxygen PROPERTIES
467                IMPORTED_LOCATION "${DOXYGEN_EXECUTABLE}"
468            )
469        endif()
470    endif()
471endmacro()
472
473#
474# Find Diagram Editor...
475#
476macro(_Doxygen_find_dia)
477    set(_x86 "(x86)")
478    find_program(
479        DOXYGEN_DIA_EXECUTABLE
480        NAMES dia
481        PATHS
482            "$ENV{ProgramFiles}/Dia"
483            "$ENV{ProgramFiles${_x86}}/Dia"
484        DOC "Diagram Editor tool for use with Doxygen"
485    )
486    mark_as_advanced(DOXYGEN_DIA_EXECUTABLE)
487
488    if(DOXYGEN_DIA_EXECUTABLE)
489        # The Doxyfile wants the path to the utility, not the entire path
490        # including file name
491        get_filename_component(DOXYGEN_DIA_PATH
492                              "${DOXYGEN_DIA_EXECUTABLE}"
493                              DIRECTORY)
494        if(WIN32)
495            file(TO_NATIVE_PATH "${DOXYGEN_DIA_PATH}" DOXYGEN_DIA_PATH)
496        endif()
497
498        # Create an imported target for component
499        if(NOT TARGET Doxygen::dia)
500            add_executable(Doxygen::dia IMPORTED GLOBAL)
501            set_target_properties(Doxygen::dia PROPERTIES
502                IMPORTED_LOCATION "${DOXYGEN_DIA_EXECUTABLE}"
503            )
504        endif()
505    endif()
506
507    unset(_x86)
508endmacro()
509
510#
511# Find Graphviz Dot...
512#
513macro(_Doxygen_find_dot)
514    if(WIN32)
515        set(_x86 "(x86)")
516        file(
517            GLOB _Doxygen_GRAPHVIZ_BIN_DIRS
518            "$ENV{ProgramFiles}/Graphviz*/bin"
519            "$ENV{ProgramFiles${_x86}}/Graphviz*/bin"
520        )
521        unset(_x86)
522    else()
523        set(_Doxygen_GRAPHVIZ_BIN_DIRS "")
524    endif()
525
526    find_program(
527        DOXYGEN_DOT_EXECUTABLE
528        NAMES dot
529        PATHS
530            ${_Doxygen_GRAPHVIZ_BIN_DIRS}
531            "$ENV{ProgramFiles}/ATT/Graphviz/bin"
532            "C:/Program Files/ATT/Graphviz/bin"
533            [HKEY_LOCAL_MACHINE\\SOFTWARE\\ATT\\Graphviz;InstallPath]/bin
534            /Applications/Graphviz.app/Contents/MacOS
535            /Applications/Utilities/Graphviz.app/Contents/MacOS
536            /Applications/Doxygen.app/Contents/Resources
537            /Applications/Doxygen.app/Contents/MacOS
538            /Applications/Utilities/Doxygen.app/Contents/Resources
539            /Applications/Utilities/Doxygen.app/Contents/MacOS
540        DOC "Dot tool for use with Doxygen"
541    )
542    mark_as_advanced(DOXYGEN_DOT_EXECUTABLE)
543
544    if(DOXYGEN_DOT_EXECUTABLE)
545        # The Doxyfile wants the path to the utility, not the entire path
546        # including file name
547        get_filename_component(DOXYGEN_DOT_PATH
548                               "${DOXYGEN_DOT_EXECUTABLE}"
549                               DIRECTORY)
550        if(WIN32)
551            file(TO_NATIVE_PATH "${DOXYGEN_DOT_PATH}" DOXYGEN_DOT_PATH)
552        endif()
553
554        # Create an imported target for component
555        if(NOT TARGET Doxygen::dot)
556            add_executable(Doxygen::dot IMPORTED GLOBAL)
557            set_target_properties(Doxygen::dot PROPERTIES
558                IMPORTED_LOCATION "${DOXYGEN_DOT_EXECUTABLE}"
559            )
560        endif()
561    endif()
562
563    unset(_Doxygen_GRAPHVIZ_BIN_DIRS)
564endmacro()
565
566#
567# Find Message Sequence Chart...
568#
569macro(_Doxygen_find_mscgen)
570    set(_x86 "(x86)")
571    find_program(
572        DOXYGEN_MSCGEN_EXECUTABLE
573        NAMES mscgen
574        PATHS
575            "$ENV{ProgramFiles}/Mscgen"
576            "$ENV{ProgramFiles${_x86}}/Mscgen"
577        DOC "Message sequence chart tool for use with Doxygen"
578    )
579    mark_as_advanced(DOXYGEN_MSCGEN_EXECUTABLE)
580
581    if(DOXYGEN_MSCGEN_EXECUTABLE)
582        # The Doxyfile wants the path to the utility, not the entire path
583        # including file name
584        get_filename_component(DOXYGEN_MSCGEN_PATH
585                               "${DOXYGEN_MSCGEN_EXECUTABLE}"
586                               DIRECTORY)
587        if(WIN32)
588            file(TO_NATIVE_PATH "${DOXYGEN_MSCGEN_PATH}" DOXYGEN_MSCGEN_PATH)
589        endif()
590
591        # Create an imported target for component
592        if(NOT TARGET Doxygen::mscgen)
593            add_executable(Doxygen::mscgen IMPORTED GLOBAL)
594            set_target_properties(Doxygen::mscgen PROPERTIES
595                IMPORTED_LOCATION "${DOXYGEN_MSCGEN_EXECUTABLE}"
596            )
597        endif()
598    endif()
599
600    unset(_x86)
601endmacro()
602
603# Make sure `doxygen` is one of the components to find
604set(_Doxygen_keep_backward_compat FALSE)
605if(NOT Doxygen_FIND_COMPONENTS)
606    # Search at least for `doxygen` executable
607    set(Doxygen_FIND_COMPONENTS doxygen)
608    # Preserve backward compatibility:
609    # search for `dot` also if `DOXYGEN_SKIP_DOT` is not explicitly disable this.
610    if(NOT DOXYGEN_SKIP_DOT)
611        list(APPEND Doxygen_FIND_COMPONENTS dot)
612    endif()
613    set(_Doxygen_keep_backward_compat TRUE)
614elseif(NOT doxygen IN_LIST Doxygen_FIND_COMPONENTS)
615    list(INSERT Doxygen_FIND_COMPONENTS 0 doxygen)
616endif()
617
618#
619# Find all requested components of Doxygen...
620#
621foreach(_comp IN LISTS Doxygen_FIND_COMPONENTS)
622    if(_comp STREQUAL "doxygen")
623        _Doxygen_find_doxygen()
624    elseif(_comp STREQUAL "dia")
625        _Doxygen_find_dia()
626    elseif(_comp STREQUAL "dot")
627        _Doxygen_find_dot()
628    elseif(_comp STREQUAL "mscgen")
629        _Doxygen_find_mscgen()
630    else()
631        message(WARNING "${_comp} is not a valid Doxygen component")
632        set(Doxygen_${_comp}_FOUND FALSE)
633        continue()
634    endif()
635
636    if(TARGET Doxygen::${_comp})
637        set(Doxygen_${_comp}_FOUND TRUE)
638    else()
639        set(Doxygen_${_comp}_FOUND FALSE)
640    endif()
641endforeach()
642unset(_comp)
643
644# Verify find results
645include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
646find_package_handle_standard_args(
647    Doxygen
648    REQUIRED_VARS DOXYGEN_EXECUTABLE
649    VERSION_VAR DOXYGEN_VERSION
650    HANDLE_COMPONENTS
651)
652
653#
654# Backwards compatibility...
655#
656if(APPLE)
657    # Restore the old app-bundle setting
658    set(CMAKE_FIND_APPBUNDLE ${TEMP_DOXYGEN_SAVE_CMAKE_FIND_APPBUNDLE})
659endif()
660
661# Maintain the _FOUND variables as "YES" or "NO" for backwards
662# compatibility. This allows people to substitute them directly into
663# Doxyfile with configure_file().
664if(DOXYGEN_FOUND)
665    set(DOXYGEN_FOUND "YES")
666else()
667    set(DOXYGEN_FOUND "NO")
668endif()
669if(_Doxygen_keep_backward_compat)
670    if(Doxygen_dot_FOUND)
671        set(DOXYGEN_DOT_FOUND "YES")
672    else()
673        set(DOXYGEN_DOT_FOUND "NO")
674    endif()
675
676    # For backwards compatibility support for even older CMake versions
677    set(DOXYGEN ${DOXYGEN_EXECUTABLE})
678    set(DOT ${DOXYGEN_DOT_EXECUTABLE})
679
680    # No need to keep any backward compatibility for `DOXYGEN_MSCGEN_XXX`
681    # and `DOXYGEN_DIA_XXX` since they were not supported before component
682    # support was added
683endif()
684unset(_Doxygen_keep_backward_compat)
685
686#
687# Allow full control of Doxygen from CMakeLists.txt
688#
689
690# Prepare a template Doxyfile and Doxygen's default values CMake file
691if(TARGET Doxygen::doxygen)
692    # If doxygen was found, use it to generate a minimal default Doxyfile.
693    # We will delete this file after we have finished using it below to
694    # generate the other files that doxygen_add_docs() will use.
695    set(_Doxygen_tpl "${CMAKE_BINARY_DIR}/CMakeDoxyfile.tpl")
696    execute_process(
697        COMMAND "${DOXYGEN_EXECUTABLE}" -s -g "${_Doxygen_tpl}"
698        OUTPUT_QUIET
699        RESULT_VARIABLE _Doxygen_tpl_result
700    )
701    if(_Doxygen_tpl_result)
702        message(FATAL_ERROR
703                "Unable to generate Doxyfile template: ${_Doxygen_tpl_result}")
704    elseif(NOT EXISTS "${_Doxygen_tpl}")
705        message(FATAL_ERROR
706                "Doxygen has failed to generate a Doxyfile template")
707    endif()
708
709    # Write a do-not-edit header to files we are going to generate...
710    set(_Doxygen_dne_header
711[[
712#
713# DO NOT EDIT! THIS FILE WAS GENERATED BY CMAKE!
714#
715
716]]
717    )
718    # We only need one copy of these across the whole build, since their
719    # content is only dependent on the version of Doxygen being used. Therefore
720    # we always put them at the top of the build tree so that they are in a
721    # predictable location.
722    set(_doxyfile_in       "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in")
723    set(_doxyfile_defaults "${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake")
724
725    set(_doxyfile_in_contents "")
726    set(_doxyfile_defaults_contents "")
727
728    # Get strings containing a configuration key from the template Doxyfile
729    # we obtained from this version of Doxygen. Because some options are split
730    # across multiple lines by ending lines with backslashes, we cannot just
731    # use file(STRINGS...) with a REGEX. Instead, read lines without a REGEX
732    # so that file(STRINGS...) handles the trailing backslash as a line
733    # continuation. It stores multi-lines as lists, so we then have to replace
734    # the ";" list separator with backslashed newlines again so that we get the
735    # original content stored back as the value part.
736    file(STRINGS "${_Doxygen_tpl}" _file_lines)
737    unset(_Doxygen_tpl_params)
738    foreach(_line IN LISTS _file_lines)
739        if(_line MATCHES "([A-Z][A-Z0-9_]+)( *=)(.*)")
740            set(_key "${CMAKE_MATCH_1}")
741            set(_eql "${CMAKE_MATCH_2}")
742            set(_value "${CMAKE_MATCH_3}")
743            string(REPLACE "\\" "\\\\" _value "${_value}")
744            string(REPLACE ";" "\\\n" _value "${_value}")
745            list(APPEND _Doxygen_tpl_params "${_key}${_eql}${_value}")
746        endif()
747    endforeach()
748
749    # Build up a Doxyfile that provides @configVar@ substitutions for each
750    # Doxygen config option as well as a separate CMake script which provides
751    # the default value for each of those options if the project doesn't supply
752    # them. Each config option will support substitution of a CMake variable
753    # of the same name except with DOXYGEN_ prepended.
754    foreach(_Doxygen_param IN LISTS _Doxygen_tpl_params)
755        if(_Doxygen_param MATCHES "([A-Z][A-Z0-9_]+)( *)=( (.*))?")
756            # Ok, this is a config key with a value
757            if(CMAKE_MATCH_COUNT EQUAL 4)
758                string(APPEND _doxyfile_in_contents
759                       "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n")
760                # Remove the backslashes we had to preserve to handle newlines
761                string(REPLACE "\\\n" "\n" _value "${CMAKE_MATCH_4}")
762                string(APPEND _doxyfile_defaults_contents
763"if(NOT DEFINED DOXYGEN_${CMAKE_MATCH_1})
764    set(DOXYGEN_${CMAKE_MATCH_1} ${_value})
765endif()
766")
767            # Ok, this is a config key with empty default value
768            elseif(CMAKE_MATCH_COUNT EQUAL 2)
769                string(APPEND _doxyfile_in_contents
770                       "${CMAKE_MATCH_1}${CMAKE_MATCH_2}= @DOXYGEN_${CMAKE_MATCH_1}@\n")
771            else()
772                message(AUTHOR_WARNING
773"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}")
774            endif()
775        else()
776            message(AUTHOR_WARNING
777"Unexpected line format! Code review required!\nFault line: ${_Doxygen_param}")
778        endif()
779    endforeach()
780    file(WRITE "${_doxyfile_defaults}" "${_Doxygen_dne_header}"
781                                       "${_doxyfile_defaults_contents}")
782    file(WRITE "${_doxyfile_in}"       "${_Doxygen_dne_header}"
783                                       "${_doxyfile_in_contents}")
784
785    # Ok, dumped defaults are not needed anymore...
786    file(REMOVE "${_Doxygen_tpl}")
787
788    unset(_Doxygen_param)
789    unset(_Doxygen_tpl_params)
790    unset(_Doxygen_dne_header)
791    unset(_Doxygen_tpl)
792
793endif()
794
795function(doxygen_quote_value VARIABLE)
796    # Quote a value of the given variable if:
797    # - VARIABLE parameter was really given
798    # - the variable it names is defined and is not present in the list
799    #   specified by DOXYGEN_VERBATIM_VARS (if set)
800    # - the value of the named variable isn't already quoted
801    # - the value has spaces
802    if(VARIABLE AND DEFINED ${VARIABLE} AND
803       NOT ${VARIABLE} MATCHES "^\".* .*\"$" AND ${VARIABLE} MATCHES " " AND
804       NOT (DEFINED DOXYGEN_VERBATIM_VARS AND
805            "${VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS))
806        set(${VARIABLE} "\"${${VARIABLE}}\"" PARENT_SCOPE)
807    endif()
808endfunction()
809
810function(doxygen_list_to_quoted_strings LIST_VARIABLE)
811    if(LIST_VARIABLE AND DEFINED ${LIST_VARIABLE})
812        unset(_inputs)
813        unset(_sep)
814        unset(_verbatim)
815        # Have to test if list items should be treated as verbatim here
816        # because we lose the variable name when we pass just one list item
817        # to doxygen_quote_value() below
818        if(DEFINED DOXYGEN_VERBATIM_VARS AND
819           "${LIST_VARIABLE}" IN_LIST DOXYGEN_VERBATIM_VARS)
820            set(_verbatim True)
821        endif()
822        foreach(_in IN LISTS ${LIST_VARIABLE})
823            if(NOT _verbatim)
824                doxygen_quote_value(_in)
825            endif()
826            string(APPEND _inputs "${_sep}${_in}")
827            set(_sep " ")
828        endforeach()
829        set(${LIST_VARIABLE} "${_inputs}" PARENT_SCOPE)
830    endif()
831endfunction()
832
833function(doxygen_add_docs targetName)
834    set(_options ALL USE_STAMP_FILE)
835    set(_one_value_args WORKING_DIRECTORY COMMENT)
836    set(_multi_value_args)
837    cmake_parse_arguments(_args
838                          "${_options}"
839                          "${_one_value_args}"
840                          "${_multi_value_args}"
841                          ${ARGN})
842
843    if(NOT _args_COMMENT)
844        set(_args_COMMENT "Generate API documentation for ${targetName}")
845    endif()
846
847    if(NOT _args_WORKING_DIRECTORY)
848        set(_args_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
849    endif()
850
851    if(DEFINED DOXYGEN_INPUT)
852        message(WARNING
853"DOXYGEN_INPUT is set but it will be ignored. Pass the files and directories \
854directly to the doxygen_add_docs() command instead.")
855    endif()
856    set(DOXYGEN_INPUT ${_args_UNPARSED_ARGUMENTS})
857
858    if(NOT TARGET Doxygen::doxygen)
859        message(FATAL_ERROR "Doxygen was not found, needed by \
860doxygen_add_docs() for target ${targetName}")
861    endif()
862
863    # If not already defined, set some relevant defaults based on the
864    # assumption that the documentation is for the whole project. Details
865    # specified in the project() command will be used to populate a number of
866    # these defaults.
867
868    if(NOT DEFINED DOXYGEN_PROJECT_NAME)
869        # The PROJECT_NAME tag is a single word (or a sequence of words
870        # surrounded by double-quotes, unless you are using Doxywizard) that
871        # should identify the project for which the documentation is generated.
872        # This name is used in the title of most generated pages and in a few
873        # other places. The default value is: My Project.
874        set(DOXYGEN_PROJECT_NAME ${PROJECT_NAME})
875    endif()
876
877    if(NOT DEFINED DOXYGEN_PROJECT_NUMBER)
878        # The PROJECT_NUMBER tag can be used to enter a project or revision
879        # number. This could be handy for archiving the generated documentation
880        # or if some version control system is used.
881        set(DOXYGEN_PROJECT_NUMBER ${PROJECT_VERSION})
882    endif()
883
884    if(NOT DEFINED DOXYGEN_PROJECT_BRIEF)
885        # Using the PROJECT_BRIEF tag one can provide an optional one line
886        # description for a project that appears at the top of each page and
887        # should give viewer a quick idea about the purpose of the project.
888        # Keep the description short.
889        set(DOXYGEN_PROJECT_BRIEF "${PROJECT_DESCRIPTION}")
890    endif()
891
892    if(NOT DEFINED DOXYGEN_RECURSIVE)
893        # The RECURSIVE tag can be used to specify whether or not
894        # subdirectories should be searched for input files as well. CMake
895        # projects generally evolve to span multiple directories, so it makes
896        # more sense for this to be on by default. Doxygen's default value
897        # has this setting turned off, so we override it.
898        set(DOXYGEN_RECURSIVE YES)
899    endif()
900
901    if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY)
902        # The OUTPUT_DIRECTORY tag is used to specify the (relative or
903        # absolute) path into which the generated documentation will be
904        # written. If a relative path is used, Doxygen will interpret it as
905        # being relative to the location where doxygen was started, but we need
906        # to run Doxygen in the source tree so that relative input paths work
907        # intuitively. Therefore, we ensure that the output directory is always
908        # an absolute path and if the project provided a relative path, we
909        # treat it as relative to the current BINARY directory so that output
910        # is not generated inside the source tree.
911        set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
912    elseif(NOT IS_ABSOLUTE "${DOXYGEN_OUTPUT_DIRECTORY}")
913        get_filename_component(DOXYGEN_OUTPUT_DIRECTORY
914                               "${DOXYGEN_OUTPUT_DIRECTORY}"
915                               ABSOLUTE
916                               BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
917    endif()
918
919    if(NOT DEFINED DOXYGEN_HAVE_DOT)
920        # If you set the HAVE_DOT tag to YES then doxygen will assume the dot
921        # tool is available from the path. This tool is part of Graphviz (see:
922        # http://www.graphviz.org/), a graph visualization toolkit from AT&T
923        # and Lucent Bell Labs. The other options in this section have no
924        # effect if this option is set to NO.
925        # Doxygen's default value is: NO.
926        if(Doxygen_dot_FOUND)
927          set(DOXYGEN_HAVE_DOT "YES")
928        else()
929          set(DOXYGEN_HAVE_DOT "NO")
930        endif()
931    endif()
932
933    if(NOT DEFINED DOXYGEN_DOT_MULTI_TARGETS)
934        # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate
935        # multiple output files in one run (i.e. multiple -o and -T options on
936        # the command line). This makes dot run faster, but since only newer
937        # versions of dot (>1.8.10) support this, Doxygen disables this feature
938        # by default.
939        # This tag requires that the tag HAVE_DOT is set to YES.
940        set(DOXYGEN_DOT_MULTI_TARGETS YES)
941    endif()
942
943    if(NOT DEFINED DOXYGEN_GENERATE_LATEX)
944        # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX
945        # output. We only want the HTML output enabled by default, so we turn
946        # this off if the project hasn't specified it.
947        set(DOXYGEN_GENERATE_LATEX NO)
948    endif()
949
950    if(NOT DEFINED DOXYGEN_WARN_FORMAT)
951        if(CMAKE_VS_MSBUILD_COMMAND OR CMAKE_VS_DEVENV_COMMAND)
952            # The WARN_FORMAT tag determines the format of the warning messages
953            # that doxygen can produce. The string should contain the $file,
954            # $line and $text tags, which will be replaced by the file and line
955            # number from which the warning originated and the warning text.
956            # Optionally, the format may contain $version, which will be
957            # replaced by the version of the file (if it could be obtained via
958            # FILE_VERSION_FILTER).
959            # Doxygen's default value is: $file:$line: $text
960            set(DOXYGEN_WARN_FORMAT "$file($line) : $text ")
961        endif()
962    endif()
963
964    if(DEFINED DOXYGEN_WARN_LOGFILE AND NOT IS_ABSOLUTE "${DOXYGEN_WARN_LOGFILE}")
965        # The WARN_LOGFILE tag can be used to specify a file to which warning and error
966        # messages should be written. If left blank the output is written to standard
967        # error (stderr).
968        get_filename_component(DOXYGEN_WARN_LOGFILE
969                               "${DOXYGEN_WARN_LOGFILE}"
970                               ABSOLUTE
971                               BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
972    endif()
973
974    # Any files from the INPUT that match any of the EXCLUDE_PATTERNS will be
975    # excluded from the set of input files. We provide some additional patterns
976    # to prevent commonly unwanted things from CMake builds being pulled in.
977    #
978    # Note that the wildcards are matched against the file with absolute path,
979    # so to exclude all test directories for example use the pattern */test/*
980    list(
981        APPEND
982        DOXYGEN_EXCLUDE_PATTERNS
983        "*/.git/*"
984        "*/.svn/*"
985        "*/.hg/*"
986        "*/CMakeFiles/*"
987        "*/_CPack_Packages/*"
988        "DartConfiguration.tcl"
989        "CMakeLists.txt"
990        "CMakeCache.txt"
991    )
992
993    # Now bring in Doxgen's defaults for those things the project has not
994    # already set and we have not provided above
995    include("${CMAKE_BINARY_DIR}/CMakeDoxygenDefaults.cmake" OPTIONAL)
996
997    # Cleanup built HTMLs on "make clean"
998    # TODO Any other dirs?
999    if(DOXYGEN_GENERATE_HTML)
1000        if(IS_ABSOLUTE "${DOXYGEN_HTML_OUTPUT}")
1001            set(_args_clean_html_dir "${DOXYGEN_HTML_OUTPUT}")
1002        else()
1003            set(_args_clean_html_dir
1004                "${DOXYGEN_OUTPUT_DIRECTORY}/${DOXYGEN_HTML_OUTPUT}")
1005        endif()
1006        set_property(DIRECTORY APPEND PROPERTY
1007            ADDITIONAL_CLEAN_FILES "${_args_clean_html_dir}")
1008    endif()
1009
1010    # Build up a list of files we can identify from the inputs so we can list
1011    # them as DEPENDS and SOURCES in the custom command/target (the latter
1012    # makes them display in IDEs). This must be done before we transform the
1013    # various DOXYGEN_... variables below because we need to process
1014    # DOXYGEN_INPUT as a list first.
1015    unset(_sources)
1016    foreach(_item IN LISTS DOXYGEN_INPUT)
1017        get_filename_component(_abs_item "${_item}" ABSOLUTE
1018                               BASE_DIR "${_args_WORKING_DIRECTORY}")
1019        get_source_file_property(_isGenerated "${_abs_item}" GENERATED)
1020        if(_isGenerated OR
1021           (EXISTS "${_abs_item}" AND
1022            NOT IS_DIRECTORY "${_abs_item}" AND
1023            NOT IS_SYMLINK "${_abs_item}"))
1024            list(APPEND _sources "${_abs_item}")
1025        elseif(_args_USE_STAMP_FILE)
1026            message(FATAL_ERROR "Source does not exist or is not a file:\n"
1027                "    ${_abs_item}\n"
1028                "Only existing files may be specified when the "
1029                "USE_STAMP_FILE option is given.")
1030        endif()
1031    endforeach()
1032
1033    # Transform known list type options into space separated strings.
1034    set(_doxygen_list_options
1035        ABBREVIATE_BRIEF
1036        ALIASES
1037        CITE_BIB_FILES
1038        DIAFILE_DIRS
1039        DOTFILE_DIRS
1040        DOT_FONTPATH
1041        ENABLED_SECTIONS
1042        EXAMPLE_PATH
1043        EXAMPLE_PATTERNS
1044        EXCLUDE
1045        EXCLUDE_PATTERNS
1046        EXCLUDE_SYMBOLS
1047        EXPAND_AS_DEFINED
1048        EXTENSION_MAPPING
1049        EXTRA_PACKAGES
1050        EXTRA_SEARCH_MAPPINGS
1051        FILE_PATTERNS
1052        FILTER_PATTERNS
1053        FILTER_SOURCE_PATTERNS
1054        HTML_EXTRA_FILES
1055        HTML_EXTRA_STYLESHEET
1056        IGNORE_PREFIX
1057        IMAGE_PATH
1058        INCLUDE_FILE_PATTERNS
1059        INCLUDE_PATH
1060        INPUT
1061        LATEX_EXTRA_FILES
1062        LATEX_EXTRA_STYLESHEET
1063        MATHJAX_EXTENSIONS
1064        MSCFILE_DIRS
1065        PLANTUML_INCLUDE_PATH
1066        PREDEFINED
1067        QHP_CUST_FILTER_ATTRS
1068        QHP_SECT_FILTER_ATTRS
1069        STRIP_FROM_INC_PATH
1070        STRIP_FROM_PATH
1071        TAGFILES
1072        TCL_SUBST
1073    )
1074    foreach(_item IN LISTS _doxygen_list_options)
1075        doxygen_list_to_quoted_strings(DOXYGEN_${_item})
1076    endforeach()
1077
1078    # Transform known single value variables which may contain spaces, such as
1079    # paths or description strings.
1080    set(_doxygen_quoted_options
1081        CHM_FILE
1082        DIA_PATH
1083        DOCBOOK_OUTPUT
1084        DOCSET_FEEDNAME
1085        DOCSET_PUBLISHER_NAME
1086        DOT_FONTNAME
1087        DOT_PATH
1088        EXTERNAL_SEARCH_ID
1089        FILE_VERSION_FILTER
1090        GENERATE_TAGFILE
1091        HHC_LOCATION
1092        HTML_FOOTER
1093        HTML_HEADER
1094        HTML_OUTPUT
1095        HTML_STYLESHEET
1096        INPUT_FILTER
1097        LATEX_FOOTER
1098        LATEX_HEADER
1099        LATEX_OUTPUT
1100        LAYOUT_FILE
1101        MAN_OUTPUT
1102        MAN_SUBDIR
1103        MATHJAX_CODEFILE
1104        MSCGEN_PATH
1105        OUTPUT_DIRECTORY
1106        PERL_PATH
1107        PLANTUML_JAR_PATH
1108        PROJECT_BRIEF
1109        PROJECT_LOGO
1110        PROJECT_NAME
1111        QCH_FILE
1112        QHG_LOCATION
1113        QHP_CUST_FILTER_NAME
1114        QHP_VIRTUAL_FOLDER
1115        RTF_EXTENSIONS_FILE
1116        RTF_OUTPUT
1117        RTF_STYLESHEET_FILE
1118        SEARCHDATA_FILE
1119        USE_MDFILE_AS_MAINPAGE
1120        WARN_FORMAT
1121        WARN_LOGFILE
1122        XML_OUTPUT
1123    )
1124
1125    # Store the unmodified value of DOXYGEN_OUTPUT_DIRECTORY prior to invoking
1126    # doxygen_quote_value() below. This will mutate the string specifically for
1127    # consumption by Doxygen's config file, which we do not want when we use it
1128    # later in the custom target's commands.
1129    set( _original_doxygen_output_dir ${DOXYGEN_OUTPUT_DIRECTORY} )
1130
1131    foreach(_item IN LISTS _doxygen_quoted_options)
1132        doxygen_quote_value(DOXYGEN_${_item})
1133    endforeach()
1134
1135    # Prepare doxygen configuration file
1136    set(_doxyfile_template "${CMAKE_BINARY_DIR}/CMakeDoxyfile.in")
1137    set(_target_doxyfile "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile.${targetName}")
1138    configure_file("${_doxyfile_template}" "${_target_doxyfile}")
1139
1140    unset(_all)
1141    if(${_args_ALL})
1142        set(_all ALL)
1143    endif()
1144
1145    # Only create the stamp file if asked to. If we don't create it,
1146    # the target will always be considered out-of-date.
1147    if(_args_USE_STAMP_FILE)
1148        set(__stamp_file "${CMAKE_CURRENT_BINARY_DIR}/${targetName}.stamp")
1149        add_custom_command(
1150            VERBATIM
1151            OUTPUT ${__stamp_file}
1152            COMMAND ${CMAKE_COMMAND} -E make_directory ${_original_doxygen_output_dir}
1153            COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}"
1154            COMMAND ${CMAKE_COMMAND} -E touch ${__stamp_file}
1155            WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}"
1156            DEPENDS "${_target_doxyfile}" ${_sources}
1157            COMMENT "${_args_COMMENT}"
1158        )
1159        add_custom_target(${targetName} ${_all}
1160            DEPENDS ${__stamp_file}
1161            SOURCES ${_sources}
1162        )
1163        unset(__stamp_file)
1164    else()
1165        add_custom_target( ${targetName} ${_all} VERBATIM
1166            COMMAND ${CMAKE_COMMAND} -E make_directory ${_original_doxygen_output_dir}
1167            COMMAND "${DOXYGEN_EXECUTABLE}" "${_target_doxyfile}"
1168            WORKING_DIRECTORY "${_args_WORKING_DIRECTORY}"
1169            DEPENDS "${_target_doxyfile}" ${_sources}
1170            COMMENT "${_args_COMMENT}"
1171            SOURCES ${_sources}
1172        )
1173    endif()
1174
1175endfunction()
1176
1177cmake_policy(POP)
1178