Changeset View
Changeset View
Standalone View
Standalone View
cmake/modules/MarbleAddQCH.cmake
- This file was added.
1 | #.rst: | ||||
---|---|---|---|---|---|
2 | # MarbleAddQCH | ||||
3 | # ------------------ | ||||
4 | # | ||||
5 | # This module provides the ``marble_add_qch`` function for generating API | ||||
6 | # documentation files in the QCH format, and the ``marble_install_qch_export`` | ||||
7 | # function for generating and installing exported CMake targets for such | ||||
8 | # generated QCH files to enable builds of other software with generation of | ||||
9 | # QCH files to create links into the given QCH files. | ||||
10 | # | ||||
11 | # :: | ||||
12 | # | ||||
13 | # marble_add_qch(<target_name> | ||||
14 | # NAME <name> | ||||
15 | # VERSION <version> | ||||
16 | # QCH_INSTALL_DESTINATION <qchfile_install_path> | ||||
17 | # TAGFILE_INSTALL_DESTINATION <tagsfile_install_path> | ||||
18 | # [BASE_NAME <basename>] | ||||
19 | # [SOURCE_DIRS <dir> [<dir2> [...]]] | ||||
20 | # [SOURCES <file> [<file2> [...]]] | ||||
21 | # |MD_MAINPAGE <md_file>] | ||||
22 | # [IMAGE_DIRS <idir> [<idir2> [...]]] | ||||
23 | # [EXAMPLE_DIRS <edir> [<edir2> [...]]] | ||||
24 | # [ORG_DOMAIN <domain>] | ||||
25 | # [NAMESPACE <namespace>] | ||||
26 | # [LINK_QCHS <qch> [<qch2> [...]]] | ||||
27 | # [LINK_QCHS_VERSIONED <qchv> [<qchv2> [...]]] | ||||
28 | # [BLANK_MACROS <macro> [<macro2> [...]]] | ||||
29 | # [CONFIG_TEMPLATE <configtemplate_file>] | ||||
30 | # [VERBOSE] | ||||
31 | # ) | ||||
32 | # | ||||
33 | # This macro adds a target called <target_name> for the creation of an API | ||||
34 | # documentation manual in the QCH format from the given sources. | ||||
35 | # It currently uses doxygen, future versions might optionally also allow other | ||||
36 | # tools. | ||||
37 | # Next to the QCH file the target will generate a corresponding doxygen tag | ||||
38 | # file, which enables creating links from other documentation into the | ||||
39 | # generated QCH file. | ||||
40 | # | ||||
41 | # If the required tools are not found, the macro will skip creation of the | ||||
42 | # target and only emit a warning, so the use of the macro can be introduced | ||||
43 | # without requiring anyone to also have the needed tools present at that time. | ||||
44 | # This behaviour might change in future versions to result in a fail instead. | ||||
45 | # It is recommended to make the use of this macro optional, by depending | ||||
46 | # the call to ``marble_add_qch()`` on a CMake option being set, with a name like | ||||
47 | # ``BUILD_QCH`` and being TRUE by default. This will allow the developers to | ||||
48 | # saves resources on normal source development build cycles by setting this | ||||
49 | # option to FALSE. | ||||
50 | # | ||||
51 | # The macro will set the target properties DOXYGEN_TAGFILE, QHP_NAMESPACE, | ||||
52 | # QHP_NAMESPACE_VERSIONED and QHP_VIRTUALFOLDER to the respective values, to | ||||
53 | # allow other code access to them, e.g. the macro marble_install_qch_export(). | ||||
54 | # To enable the use of the target <target_name> as item for LINK_QCHS or | ||||
55 | # LINK_QCHS_VERSIONED in further ``marble_add_qch()`` calls in the current build, | ||||
56 | # additionally a target property DOXYGEN_TAGFILE_BUILD is set, with the path | ||||
57 | # of the created doxygen tag file in the build dir. | ||||
58 | # If existing, ``marble_add_qch()`` will use this property instead of | ||||
59 | # DOXYGEN_TAGFILE for access to the tags file. | ||||
60 | # | ||||
61 | # NAME specifies the name for the generated documentation. | ||||
62 | # | ||||
63 | # VERSION specifies the version of the library for which the documentation is | ||||
64 | # created. | ||||
65 | # | ||||
66 | # BASE_NAME specifies the base name for the generated files. | ||||
67 | # The default basename is ``<name>``. | ||||
68 | # | ||||
69 | # SOURCE_DIRS specifies the dirs (incl. subdirs) with the source files for | ||||
70 | # which the API documentation should be generated. Dirs can be relative to | ||||
71 | # the current source dir. Dependencies to the files in the dirs are not | ||||
72 | # tracked currently, other than with the SOURCES argument. So do not use for | ||||
73 | # sources generated during the build. | ||||
74 | # Needs to be used when SOURCES or CONFIG_TEMPLATE are not used. | ||||
75 | # | ||||
76 | # SOURCES specifies the source files for which the API documentation should be | ||||
77 | # generated. | ||||
78 | # Needs to be used when SOURCE_DIRS or CONFIG_TEMPLATE are not used. | ||||
79 | # | ||||
80 | # MD_MAINPAGE specifies a file in Markdown format that should be used as main | ||||
81 | # page. This page will overrule any ``\mainpage`` command in the included | ||||
82 | # sources. | ||||
83 | # | ||||
84 | # IMAGE_DIRS specifies the dirs which contain images that are included in the | ||||
85 | # documentation. Dirs can be relative to the current source dir. | ||||
86 | # | ||||
87 | # EXAMPLE_DIRS specifies the dirs which contain examples that are included in | ||||
88 | # the documentation. Dirs can be relative to the current source dir. | ||||
89 | # | ||||
90 | # QCH_INSTALL_DESTINATION specifies where the generated QCH file will be | ||||
91 | # installed. | ||||
92 | # | ||||
93 | # TAGFILE_INSTALL_DESTINATION specifies where the generated tag file will be | ||||
94 | # installed. | ||||
95 | # | ||||
96 | # NAMESPACE can be used to set a custom namespace <namespace> of the generated | ||||
97 | # QCH file. The namepspace is used as the unique id by QHelpEngine (cmp. | ||||
98 | # http://doc.qt.io/qt-5/qthelpproject.html#namespace). | ||||
99 | # The default namespace is ``<domain>.<name>``. | ||||
100 | # Needs to be used when ORG_DOMAIN is not used. | ||||
101 | # | ||||
102 | # ORG_DOMAIN can be used to define the organization domain prefix for the | ||||
103 | # default namespace of the generated QCH file. | ||||
104 | # Needs to be used when NAMESPACE is not used. | ||||
105 | # | ||||
106 | # LINK_QCHS specifies a list of other QCH targets which should be used for | ||||
107 | # creating references to API documenation of code in external libraries. | ||||
108 | # For each target <qch> in the list these target properties are expected to be | ||||
109 | # defined: DOXYGEN_TAGFILE, QHP_NAMESPACE and QHP_VIRTUALFOLDER. | ||||
110 | # If any of these is not existing, <qch> will be ignored. | ||||
111 | # Use the macro marble_install_qch_export for exporting a target with these | ||||
112 | # properties with the CMake config of a library. | ||||
113 | # Any target <qch> can also be one created before in the same buildsystem by | ||||
114 | # another call of ``marble_add_qch()``. | ||||
115 | # | ||||
116 | # LINK_QCHS_VERSIONED does basically the same as LINK_QCHS, but binds the links | ||||
117 | # to a certain version. | ||||
118 | # For each <qchv> in the list these target properties are expected to be | ||||
119 | # defined: DOXYGEN_TAGFILE, QHP_NAMESPACE_VERSIONED and QHP_VIRTUALFOLDER. | ||||
120 | # If any of these is not existing, <qchv> will be ignored. | ||||
121 | # Use the macro marble_install_qch_export for exporting a target with these | ||||
122 | # properties with the CMake config of a library. | ||||
123 | # Any <qchv> can also be one created before in the same buildsystem by another | ||||
124 | # call of ``marble_add_qch()``. | ||||
125 | # | ||||
126 | # BLANK_MACROS specifies a list of C/C++ macro names which should be ignored by | ||||
127 | # the API dox generation tool and handled as if they resolve to empty strings. | ||||
128 | # Examples are export macros only defined in generated files, so whose | ||||
129 | # definition might be not available to the tool. | ||||
130 | # | ||||
131 | # CONFIG_TEMPLATE specifies a custom cmake template file for the config file | ||||
132 | # that is created to control the execution of the API dox generation tool. | ||||
133 | # The following CMake variables need to be used: | ||||
134 | # ECM_DOXYGENQCH_PERL_EXECUTABLE, ECM_DOXYGENQCH_QHELPGENERATOR_EXECUTABLE, | ||||
135 | # ECM_DOXYGENQCH_FILEPATH, ECM_DOXYGENQCH_TAGFILE. | ||||
136 | # The following CMake variables can be used: | ||||
137 | # ECM_DOXYGENQCH_PROJECTNAME, ECM_DOXYGENQCH_PROJECTVERSION, | ||||
138 | # ECM_DOXYGENQCH_VIRTUALFOLDER, ECM_DOXYGENQCH_FULLNAMESPACE, | ||||
139 | # ECM_DOXYGENQCH_TAGFILES, | ||||
140 | # ECM_DOXYGENQCH_WARN_LOGFILE, ECM_DOXYGENQCH_QUIET. | ||||
141 | # There is no guarantue that the other CMake variables currently used in the | ||||
142 | # default config file template will also be present with the same semantics | ||||
143 | # in future versions of this macro. | ||||
144 | # | ||||
145 | # VERBOSE tells the API dox generation tool to be more verbose about its | ||||
146 | # activity. | ||||
147 | # | ||||
148 | # Example usage: | ||||
149 | # | ||||
150 | # .. code-block:: cmake | ||||
151 | # | ||||
152 | # marble_add_qch( | ||||
153 | # MyLib_QCH | ||||
154 | # NAME MyLib | ||||
155 | # VERSION "0.42.0" | ||||
156 | # ORG_DOMAIN org.myorg | ||||
157 | # SOURCE_DIRS | ||||
158 | # src | ||||
159 | # LINK_QCHS | ||||
160 | # Qt5Core_QCH | ||||
161 | # Qt5Xml_QCH | ||||
162 | # Qt5Gui_QCH | ||||
163 | # Qt5Widgets_QCH | ||||
164 | # BLANK_MACROS | ||||
165 | # MyLib_EXPORT | ||||
166 | # MyLib_DEPRECATED | ||||
167 | # TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags | ||||
168 | # QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch | ||||
169 | # ) | ||||
170 | # | ||||
171 | # Example usage (with two QCH files, second linking first): | ||||
172 | # | ||||
173 | # .. code-block:: cmake | ||||
174 | # | ||||
175 | # marble_add_qch( | ||||
176 | # MyLib_QCH | ||||
177 | # NAME MyLib | ||||
178 | # VERSION ${MyLib_VERSION} | ||||
179 | # ORG_DOMAIN org.myorg | ||||
180 | # SOURCES ${MyLib_PUBLIC_HEADERS} | ||||
181 | # MD_MAINPAGE src/mylib/README.md | ||||
182 | # LINK_QCHS Qt5Core_QCH | ||||
183 | # TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags | ||||
184 | # QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch | ||||
185 | # ) | ||||
186 | # marble_add_qch( | ||||
187 | # MyOtherLib_QCH | ||||
188 | # NAME MyOtherLib | ||||
189 | # VERSION ${MyOtherLib_VERSION} | ||||
190 | # ORG_DOMAIN org.myorg | ||||
191 | # SOURCES ${MyOtherLib_PUBLIC_HEADERS} | ||||
192 | # MD_MAINPAGE src/myotherlib/README.md | ||||
193 | # LINK_QCHS Qt5Core_QCH MyLib_QCH | ||||
194 | # TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags | ||||
195 | # QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch | ||||
196 | # ) | ||||
197 | # | ||||
198 | # :: | ||||
199 | # | ||||
200 | # marble_install_qch_export( | ||||
201 | # TARGETS [<name> [<name2> [...]]] | ||||
202 | # FILE <file> | ||||
203 | # DESTINATION <dest> | ||||
204 | # [COMPONENT <component>}] | ||||
205 | # ) | ||||
206 | # | ||||
207 | # This macro creates and installs a CMake file <file> which exports the given | ||||
208 | # QCH targets <name> etc., so they can be picked up by CMake-based builds of | ||||
209 | # other software that also generate QCH files (using ``marble_add_qch()``) and | ||||
210 | # which should include links to the QCH files created by the given targets. | ||||
211 | # The installed CMake file <file> is expected to be included by the CMake | ||||
212 | # config file created for the software the related QCH files are documenting. | ||||
213 | # | ||||
214 | # TARGETS specifies the QCH targets which should be exported. If a target does | ||||
215 | # not exist or does not have all needed properties, a warning will be | ||||
216 | # generated and the target skipped. | ||||
217 | # This behaviour might change in future versions to result in a fail instead. | ||||
218 | # | ||||
219 | # FILE specifies the name of the created CMake file, typically with a .cmake | ||||
220 | # extension. | ||||
221 | # | ||||
222 | # DESTINATION specifies the directory on disk to which the file will be | ||||
223 | # installed. It usually is the same as the one where the CMake config files | ||||
224 | # for this software are installed. | ||||
225 | # | ||||
226 | # COMPONENT specifies the the installation component name with which the | ||||
227 | # install rule is associated. | ||||
228 | # | ||||
229 | # Example usage: | ||||
230 | # | ||||
231 | # .. code-block:: cmake | ||||
232 | # | ||||
233 | # marble_install_qch_export( | ||||
234 | # TARGETS MyLib_QCH | ||||
235 | # FILE MyLibQCHTargets.cmake | ||||
236 | # DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/MyLib" | ||||
237 | # COMPONENT Devel | ||||
238 | # ) | ||||
239 | | ||||
240 | #============================================================================= | ||||
241 | # Copyright 2016 Friedrich W. H. Kossebau <kossebau@kde.org> | ||||
242 | # | ||||
243 | # Redistribution and use in source and binary forms, with or without | ||||
244 | # modification, are permitted provided that the following conditions | ||||
245 | # are met: | ||||
246 | # | ||||
247 | # 1. Redistributions of source code must retain the copyright | ||||
248 | # notice, this list of conditions and the following disclaimer. | ||||
249 | # 2. Redistributions in binary form must reproduce the copyright | ||||
250 | # notice, this list of conditions and the following disclaimer in the | ||||
251 | # documentation and/or other materials provided with the distribution. | ||||
252 | # 3. The name of the author may not be used to endorse or promote products | ||||
253 | # derived from this software without specific prior written permission. | ||||
254 | # | ||||
255 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||||
256 | # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
257 | # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
258 | # IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
259 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
260 | # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
261 | # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
262 | # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
263 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
264 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
265 | | ||||
266 | # needed to find helper files | ||||
267 | get_filename_component(_module_dir ${CMAKE_CURRENT_LIST_FILE} PATH) | ||||
268 | | ||||
269 | include(CMakeParseArguments) | ||||
270 | include(MarbleQueryQmake) | ||||
271 | | ||||
272 | function(marble_add_qch target_name) | ||||
273 | # Parse arguments | ||||
274 | set(options VERBOSE) | ||||
275 | set(oneValueArgs NAME BASE_NAME QCH_INSTALL_DESTINATION TAGFILE_INSTALL_DESTINATION VERSION NAMESPACE MD_MAINPAGE ORG_DOMAIN CONFIG_TEMPLATE) | ||||
276 | set(multiValueArgs SOURCE_DIRS SOURCES IMAGE_DIRS EXAMPLE_DIRS BLANK_MACROS LINK_QCHS LINK_QCHS_VERSIONED) | ||||
277 | cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||||
278 | | ||||
279 | # check required args | ||||
280 | foreach(_arg_name NAME QCH_INSTALL_DESTINATION TAGFILE_INSTALL_DESTINATION VERSION) | ||||
281 | if(NOT DEFINED ARGS_${_arg_name}) | ||||
282 | message(FATAL_ERROR "${_arg_name} needs to be defined when calling marble_add_qch") | ||||
283 | endif() | ||||
284 | endforeach() | ||||
285 | if(NOT DEFINED ARGS_SOURCE_DIRS AND NOT DEFINED ARGS_SOURCES AND NOT DEFINED ARGS_CONFIG_TEMPLATE) | ||||
286 | message(FATAL_ERROR "SOURCE_DIRS or SOURCES needs to be defined when calling marble_add_qch") | ||||
287 | endif() | ||||
288 | if(DEFINED ARGS_SOURCE_DIRS AND DEFINED ARGS_SOURCES) | ||||
289 | message(FATAL_ERROR "Either SOURCE_DIRS or SOURCES, not both, needs to be defined when calling marble_add_qch") | ||||
290 | endif() | ||||
291 | if(NOT DEFINED ARGS_ORG_DOMAIN AND NOT DEFINED ARGS_NAMESPACE) | ||||
292 | message(FATAL_ERROR "ORG_DOMAIN or NAMESPACE needs to be defined when calling marble_add_qch") | ||||
293 | endif() | ||||
294 | | ||||
295 | # find required tools | ||||
296 | # TODO: check with doxygen author if perl is really still required, PERL_PATH seems unused in doxygen | ||||
297 | find_package(Perl) | ||||
298 | set_package_properties(Perl PROPERTIES | ||||
299 | PURPOSE "Needed for API dox QCH file generation" | ||||
300 | TYPE OPTIONAL | ||||
301 | ) | ||||
302 | if (NOT DOXYGEN_PATCHED_JSFILESADDED) | ||||
303 | set(REQUIRED_DOXYGEN_VERSION 1.8.13) | ||||
304 | endif() | ||||
305 | find_package(Doxygen ${REQUIRED_DOXYGEN_VERSION}) | ||||
306 | if (NOT DOXYGEN_FOUND AND NOT DOXYGEN_PATCHED_JSFILESADDED) | ||||
307 | set(doxygen_description_addition " (Or older version patched with https://github.com/doxygen/doxygen/commit/bf9415698e53d79b, pass -DDOXYGEN_PATCHED_JSFILESADDED=ON to cmake if patched)") | ||||
308 | endif() | ||||
309 | set_package_properties(Doxygen PROPERTIES | ||||
310 | TYPE OPTIONAL | ||||
311 | PURPOSE "Needed for API dox QCH file generation${doxygen_description_addition}" | ||||
312 | ) | ||||
313 | find_package(QHelpGenerator) | ||||
314 | set_package_properties(QHelpGenerator PROPERTIES | ||||
315 | TYPE OPTIONAL | ||||
316 | PURPOSE "Needed for API dox QCH file generation" | ||||
317 | DESCRIPTION "Part of Qt5 tools" | ||||
318 | ) | ||||
319 | set(_missing_tools) | ||||
320 | if (NOT PERL_FOUND) | ||||
321 | list(APPEND _missing_tools "Perl") | ||||
322 | endif() | ||||
323 | if (NOT DOXYGEN_FOUND) | ||||
324 | list(APPEND _missing_tools "Doxygen") | ||||
325 | endif() | ||||
326 | if (NOT QHelpGenerator_FOUND) | ||||
327 | list(APPEND _missing_tools "qhelpgenerator") | ||||
328 | endif() | ||||
329 | | ||||
330 | if (_missing_tools) | ||||
331 | message(WARNING "API dox QCH file will not be generated, tools missing: ${_missing_tools}!") | ||||
332 | else() | ||||
333 | set(ECM_DOXYGENQCH_QHELPGENERATOR_EXECUTABLE ${QHelpGenerator_EXECUTABLE}) | ||||
334 | # create QCH targets for Qt | ||||
335 | # Ideally one day Qt CMake Config files provide these | ||||
336 | if(NOT TARGET Qt5Core_QCH) | ||||
337 | # get Qt version, if any | ||||
338 | find_package(Qt5Core CONFIG QUIET) | ||||
339 | # lookup tag files | ||||
340 | query_qmake(qt_docs_dir QT_INSTALL_DOCS) | ||||
341 | find_path(_qtcoreTagsPath qtcore/qtcore.tags | ||||
342 | PATHS | ||||
343 | ${qt_docs_dir} | ||||
344 | ) | ||||
345 | | ||||
346 | if(Qt5Core_FOUND AND _qtcoreTagsPath) | ||||
347 | string(REPLACE "." "" _version ${Qt5Core_VERSION}) | ||||
348 | # TODO: properly find each tag file | ||||
349 | # TODO: complete list of Qt modules | ||||
350 | foreach(_module | ||||
351 | Bluetooth Concurrent Core DBus Gui Location Multimedia MultimediaWidgets | ||||
352 | Network Positioning PrintSupport Qml Quick Sensors SerialPort Sql Svg | ||||
353 | WebEngine WebView Widgets Xml XmlPatterns | ||||
354 | ) | ||||
355 | string(TOLOWER ${_module} _lowermodule) | ||||
356 | | ||||
357 | add_custom_target(Qt5${_module}_QCH) | ||||
358 | set_target_properties(Qt5${_module}_QCH PROPERTIES | ||||
359 | DOXYGEN_TAGFILE "${_qtcoreTagsPath}/qt${_lowermodule}/qt${_lowermodule}.tags" | ||||
360 | QHP_NAMESPACE "org.qt-project.qt${_lowermodule}" | ||||
361 | QHP_NAMESPACE_VERSIONED "org.qt-project.qt${_lowermodule}.${_version}" | ||||
362 | QHP_VIRTUALFOLDER "qt${_lowermodule}" | ||||
363 | IMPORTED TRUE | ||||
364 | ) | ||||
365 | endforeach() | ||||
366 | endif() | ||||
367 | endif() | ||||
368 | | ||||
369 | # prepare base dirs, working file names and other vars | ||||
370 | if (DEFINED ARGS_BASE_NAME) | ||||
371 | set(_basename ${ARGS_BASE_NAME}) | ||||
372 | else() | ||||
373 | set(_basename ${ARGS_NAME}) | ||||
374 | endif() | ||||
375 | set(_qch_file_basename "${_basename}.qch") | ||||
376 | set(_tags_file_basename "${_basename}.tags") | ||||
377 | set(_qch_buildpath "${CMAKE_CURRENT_BINARY_DIR}/${_qch_file_basename}") | ||||
378 | set(_tags_buildpath "${CMAKE_CURRENT_BINARY_DIR}/${_tags_file_basename}") | ||||
379 | set(_apidox_builddir "${CMAKE_CURRENT_BINARY_DIR}/${_basename}_ECMDoxygenQCH") | ||||
380 | if (DEFINED ARGS_NAMESPACE) | ||||
381 | set(_namespace "${ARGS_NAMESPACE}") | ||||
382 | else() | ||||
383 | set(_namespace "${ARGS_ORG_DOMAIN}.${ARGS_NAME}") | ||||
384 | endif() | ||||
385 | string(REPLACE "." "_" _dotLessVersion ${ARGS_VERSION}) | ||||
386 | set(_versioned_namespace "${_namespace}.${_dotLessVersion}") | ||||
387 | set(_sources) | ||||
388 | set(_dep_tagfiles) | ||||
389 | set(_dep_qch_targets) | ||||
390 | | ||||
391 | ### Create doxygen config file | ||||
392 | set(_doxygenconfig_file "${CMAKE_CURRENT_BINARY_DIR}/${_basename}_ECMDoxygenQCH.config") | ||||
393 | if (DEFINED ARGS_CONFIG_TEMPLATE) | ||||
394 | set(_doxygenconfig_template_file "${ARGS_CONFIG_TEMPLATE}") | ||||
395 | else() | ||||
396 | set(_doxygenconfig_template_file "${_module_dir}/MarbleDoxygenQCH.config.in") | ||||
397 | endif() | ||||
398 | # Setup variables used in config file template, ECM_DOXYGENQCH_* | ||||
399 | set(ECM_DOXYGENQCH_OUTPUTDIR "\"${_apidox_builddir}\"") | ||||
400 | set(ECM_DOXYGENQCH_TAGFILE "\"${_tags_buildpath}\"") | ||||
401 | set(ECM_DOXYGENQCH_LAYOUTFILE "\"${_module_dir}/MarbleDoxygenQCHLayout.xml\"") | ||||
402 | set(ECM_DOXYGENQCH_IMAGEDIRS) | ||||
403 | foreach(_image_DIR IN LISTS ARGS_IMAGE_DIRS) | ||||
404 | if (NOT IS_ABSOLUTE ${_image_DIR}) | ||||
405 | set(_image_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_image_DIR}") | ||||
406 | endif() | ||||
407 | # concat dirs separated by a break, it is no issue that first has also a leading break | ||||
408 | set(ECM_DOXYGENQCH_IMAGEDIRS "${ECM_DOXYGENQCH_IMAGEDIRS} \\\n\"${_image_DIR}\"") | ||||
409 | endforeach() | ||||
410 | set(ECM_DOXYGENQCH_EXAMPLEDIRS) | ||||
411 | foreach(_example_DIR IN LISTS ARGS_EXAMPLE_DIRS) | ||||
412 | if (NOT IS_ABSOLUTE ${_example_DIR}) | ||||
413 | set(_example_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_example_DIR}") | ||||
414 | endif() | ||||
415 | # concat dirs separated by a break, it is no issue that first has also a leading break | ||||
416 | set(ECM_DOXYGENQCH_EXAMPLEDIRS "${ECM_DOXYGENQCH_EXAMPLEDIRS} \\\n\"${_example_DIR}\"") | ||||
417 | endforeach() | ||||
418 | if (ARGS_MD_MAINPAGE) | ||||
419 | if (NOT IS_ABSOLUTE ${ARGS_MD_MAINPAGE}) | ||||
420 | set(ARGS_MD_MAINPAGE "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_MD_MAINPAGE}") | ||||
421 | endif() | ||||
422 | set(ECM_DOXYGENQCH_MAINPAGE_MDFILE "\"${ARGS_MD_MAINPAGE}\"") | ||||
423 | else() | ||||
424 | set(ECM_DOXYGENQCH_MAINPAGE_MDFILE) | ||||
425 | endif() | ||||
426 | set(ECM_DOXYGENQCH_INPUT) | ||||
427 | if (ARGS_SOURCE_DIRS) | ||||
428 | foreach(_source_DIR IN LISTS ARGS_SOURCE_DIRS) | ||||
429 | if (NOT IS_ABSOLUTE ${_source_DIR}) | ||||
430 | set(_source_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_source_DIR}") | ||||
431 | endif() | ||||
432 | # concat dirs separated by a break, it is no issue that first has also a leading break | ||||
433 | set(ECM_DOXYGENQCH_INPUT "${ECM_DOXYGENQCH_INPUT} \\\n\"${_source_DIR}\"") | ||||
434 | endforeach() | ||||
435 | if (ARGS_MD_MAINPAGE) | ||||
436 | set(ECM_DOXYGENQCH_INPUT "${ECM_DOXYGENQCH_INPUT} \\\n\"${ARGS_MD_MAINPAGE}\"") | ||||
437 | endif() | ||||
438 | set(ECM_DOXYGENQCH_FILE_PATTERNS "*.h *.cpp *.hpp *.hh *.cc *.h++ *.c++ *.hxx *.cxx *.dox *.md") | ||||
439 | else() | ||||
440 | foreach(_source IN LISTS ARGS_SOURCES) | ||||
441 | if (NOT IS_ABSOLUTE ${_source}) | ||||
442 | set(_source "${CMAKE_CURRENT_SOURCE_DIR}/${_source}") | ||||
443 | endif() | ||||
444 | list(APPEND _sources "${_source}") | ||||
445 | endforeach() | ||||
446 | if (ARGS_MD_MAINPAGE) | ||||
447 | list(FIND _sources ${ARGS_MD_MAINPAGE} _mainpage_index) | ||||
448 | if (_mainpage_index STREQUAL -1) | ||||
449 | list(APPEND _sources "${ARGS_MD_MAINPAGE}") | ||||
450 | endif() | ||||
451 | endif() | ||||
452 | foreach(_source IN LISTS _sources) | ||||
453 | # concat sources separated by a break, it is no issue that first has also a leading break | ||||
454 | set(ECM_DOXYGENQCH_INPUT "${ECM_DOXYGENQCH_INPUT} \\\n\"${_source}\"") | ||||
455 | endforeach() | ||||
456 | set(ECM_DOXYGENQCH_FILE_PATTERNS "") | ||||
457 | endif() | ||||
458 | | ||||
459 | set(ECM_DOXYGENQCH_PROJECTNAME ${ARGS_NAME}) | ||||
460 | file(RELATIVE_PATH _builddirrelative_filepath "${_apidox_builddir}/html" ${_qch_buildpath}) | ||||
461 | set(ECM_DOXYGENQCH_FILEPATH "\"${_builddirrelative_filepath}\"") | ||||
462 | set(ECM_DOXYGENQCH_PROJECTVERSION ${ARGS_VERSION}) | ||||
463 | set(ECM_DOXYGENQCH_VIRTUALFOLDER "${ARGS_NAME}") | ||||
464 | set(ECM_DOXYGENQCH_FULLNAMESPACE ${_versioned_namespace}) | ||||
465 | set(ECM_DOXYGENQCH_BLANK_MACROS) | ||||
466 | foreach(_macro IN LISTS ARGS_BLANK_MACROS) | ||||
467 | # concat dirs separated by a break, it is no issue that first has also a leading break | ||||
468 | set(ECM_DOXYGENQCH_BLANK_MACROS "${ECM_DOXYGENQCH_BLANK_MACROS} \\\n${_macro}=\"\"") | ||||
469 | endforeach() | ||||
470 | set(ECM_DOXYGENQCH_TAGFILES) | ||||
471 | foreach(_versioned_postfix "" "_VERSIONED") | ||||
472 | foreach(_link_qch IN LISTS ARGS_LINK_QCHS${_versioned_postfix}) | ||||
473 | set(_target_usable TRUE) | ||||
474 | if (NOT TARGET ${_link_qch}) | ||||
475 | message(STATUS "No such target ${_link_qch} defined when calling marble_add_qch().") | ||||
476 | set(_target_usable FALSE) | ||||
477 | elseif() | ||||
478 | foreach(_propertyname | ||||
479 | DOXYGEN_TAGFILE | ||||
480 | QHP_NAMESPACE${_versioned_postfix} | ||||
481 | QHP_VIRTUALFOLDER | ||||
482 | ) | ||||
483 | get_target_property(_property ${_target} ${_propertyname}) | ||||
484 | if(NOT "${_property}") | ||||
485 | message(STATUS "No property ${_propertyname} set on ${_link_qch} when calling marble_add_qch().") | ||||
486 | set(_target_usable FALSE) | ||||
487 | endif() | ||||
488 | endforeach() | ||||
489 | endif() | ||||
490 | if(_target_usable) | ||||
491 | list(APPEND _dep_qch_targets ${_link_qch}) | ||||
492 | get_target_property(_link_qch_tagfile ${_link_qch} DOXYGEN_TAGFILE) | ||||
493 | get_target_property(_link_qch_tagfile_build ${_link_qch} DOXYGEN_TAGFILE_BUILD) | ||||
494 | get_target_property(_link_qch_namespace ${_link_qch} QHP_NAMESPACE${_versioned_postfix}) | ||||
495 | get_target_property(_link_qch_virtualfolder ${_link_qch} QHP_VIRTUALFOLDER) | ||||
496 | # if same build, then prefer build version over any installed one | ||||
497 | if (_link_qch_tagfile_build) | ||||
498 | set(_link_qch_tagfile ${_link_qch_tagfile_build}) | ||||
499 | list(APPEND _dep_tagfiles "${_link_qch_tagfile}") | ||||
500 | endif() | ||||
501 | set(_tagfile_entry "\"${_link_qch_tagfile}=qthelp://${_link_qch_namespace}/${_link_qch_virtualfolder}/\"") | ||||
502 | # concat dirs separated by a break, it is no issue that first has also a leading break | ||||
503 | set(ECM_DOXYGENQCH_TAGFILES "${ECM_DOXYGENQCH_TAGFILES} \\\n${_tagfile_entry}") | ||||
504 | else() | ||||
505 | message(WARNING "No linking to API dox of ${_link_qch}.") | ||||
506 | endif() | ||||
507 | endforeach() | ||||
508 | endforeach() | ||||
509 | | ||||
510 | set(ECM_DOXYGENQCH_WARN_LOGFILE "\"${_doxygenconfig_file}.log\"") | ||||
511 | if(ARGS_VERBOSE) | ||||
512 | set(ECM_DOXYGENQCH_QUIET "NO") | ||||
513 | else() | ||||
514 | set(ECM_DOXYGENQCH_QUIET "YES") | ||||
515 | endif() | ||||
516 | set(ECM_DOXYGENQCH_PERL_EXECUTABLE "${PERL_EXECUTABLE}") | ||||
517 | | ||||
518 | configure_file( | ||||
519 | "${_doxygenconfig_template_file}" | ||||
520 | "${_doxygenconfig_file}" | ||||
521 | @ONLY | ||||
522 | ) | ||||
523 | | ||||
524 | set(_qch_INSTALLPATH ${ARGS_QCH_INSTALL_DESTINATION}) | ||||
525 | set(_tags_INSTALLPATH ${ARGS_TAGFILE_INSTALL_DESTINATION}) | ||||
526 | file(RELATIVE_PATH _relative_qch_file ${CMAKE_BINARY_DIR} ${_qch_buildpath}) | ||||
527 | file(RELATIVE_PATH _relative_tags_file ${CMAKE_BINARY_DIR} ${_tags_buildpath}) | ||||
528 | add_custom_command( | ||||
529 | OUTPUT ${_qch_buildpath} ${_tags_buildpath} | ||||
530 | COMMENT "Generating ${_relative_qch_file}, ${_relative_tags_file}" | ||||
531 | COMMAND cmake -E remove_directory "${ECM_DOXYGENQCH_OUTPUTDIR}" | ||||
532 | COMMAND cmake -E make_directory "${ECM_DOXYGENQCH_OUTPUTDIR}" | ||||
533 | COMMAND ${DOXYGEN_EXECUTABLE} "${_doxygenconfig_file}" | ||||
534 | DEPENDS ${_doxygenconfig_file} ${_sources} ${_dep_tagfiles} ${_dep_qch_targets} | ||||
535 | ) | ||||
536 | add_custom_target(${target_name} ALL DEPENDS ${_qch_buildpath} ${_tags_buildpath}) | ||||
537 | set_target_properties(${target_name} PROPERTIES | ||||
538 | DOXYGEN_TAGFILE "${_qch_INSTALLPATH}/${_tags_file_basename}" | ||||
539 | DOXYGEN_TAGFILE_BUILD "${_tags_buildpath}" | ||||
540 | QHP_NAMESPACE "${_namespace}" | ||||
541 | QHP_NAMESPACE_VERSIONED "${_versioned_namespace}" | ||||
542 | QHP_VIRTUALFOLDER "${ECM_DOXYGENQCH_VIRTUALFOLDER}" | ||||
543 | ) | ||||
544 | | ||||
545 | install(FILES | ||||
546 | ${_qch_buildpath} | ||||
547 | DESTINATION ${_qch_INSTALLPATH} | ||||
548 | COMPONENT Devel | ||||
549 | ) | ||||
550 | | ||||
551 | install(FILES | ||||
552 | ${_tags_buildpath} | ||||
553 | DESTINATION ${_tags_INSTALLPATH} | ||||
554 | COMPONENT Devel | ||||
555 | ) | ||||
556 | endif() | ||||
557 | | ||||
558 | endfunction() | ||||
559 | | ||||
560 | | ||||
561 | function(marble_install_qch_export) | ||||
562 | set(options ) | ||||
563 | set(oneValueArgs FILE DESTINATION COMPONENT) | ||||
564 | set(multiValueArgs TARGETS) | ||||
565 | | ||||
566 | cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | ||||
567 | | ||||
568 | if(NOT DEFINED ARGS_FILE) | ||||
569 | message(FATAL_ERROR "FILE needs to be defined when calling marble_install_qch_export().") | ||||
570 | endif() | ||||
571 | | ||||
572 | if(NOT DEFINED ARGS_DESTINATION) | ||||
573 | message(FATAL_ERROR "DESTINATION needs to be defined when calling marble_install_qch_export().") | ||||
574 | endif() | ||||
575 | | ||||
576 | # TARGETS may be empty (and ARGS_TARGETS will not be defined then by cmake_parse_arguments) | ||||
577 | | ||||
578 | set(_content | ||||
579 | "# Generated by marble_install_qch_export() | ||||
580 | # Any changes to this file will be overwritten by the next CMake run. | ||||
581 | " | ||||
582 | ) | ||||
583 | | ||||
584 | foreach(_target IN LISTS ARGS_TARGETS) | ||||
585 | set(_target_usable TRUE) | ||||
586 | | ||||
587 | if (NOT TARGET ${_target}) | ||||
588 | message(STATUS "No such target ${_target} when calling marble_install_qch_export().") | ||||
589 | set(_target_usable FALSE) | ||||
590 | else() | ||||
591 | foreach(_propertyname | ||||
592 | DOXYGEN_TAGFILE | ||||
593 | QHP_NAMESPACE | ||||
594 | QHP_NAMESPACE_VERSIONED | ||||
595 | QHP_VIRTUALFOLDER | ||||
596 | ) | ||||
597 | get_target_property(_property ${_target} ${_propertyname}) | ||||
598 | if(NOT _property) | ||||
599 | message(STATUS "No property ${_propertyname} set on ${_target} when calling marble_install_qch_export(). <${_property}>") | ||||
600 | set(_target_usable FALSE) | ||||
601 | endif() | ||||
602 | endforeach() | ||||
603 | endif() | ||||
604 | if(_target_usable) | ||||
605 | get_target_property(_tagfile ${_target} DOXYGEN_TAGFILE) | ||||
606 | get_target_property(_namespace ${_target} QHP_NAMESPACE) | ||||
607 | get_target_property(_namespace_versioned ${_target} QHP_NAMESPACE_VERSIONED) | ||||
608 | get_target_property(_virtualfolder ${_target} QHP_VIRTUALFOLDER) | ||||
609 | set(_content "${_content} | ||||
610 | if (NOT TARGET ${_target}) | ||||
611 | | ||||
612 | add_custom_target(${_target}) | ||||
613 | set_target_properties(${_target} PROPERTIES | ||||
614 | DOXYGEN_TAGFILE \"${_tagfile}\" | ||||
615 | QHP_NAMESPACE \"${_namespace}\" | ||||
616 | QHP_NAMESPACE_VERSIONED \"${_namespace_versioned}\" | ||||
617 | QHP_VIRTUALFOLDER \"${_virtualfolder}\" | ||||
618 | IMPORTED TRUE | ||||
619 | ) | ||||
620 | | ||||
621 | endif() | ||||
622 | " | ||||
623 | ) | ||||
624 | else() | ||||
625 | message(STATUS "No target exported for ${_target}.") | ||||
626 | endif() | ||||
627 | endforeach() | ||||
628 | | ||||
629 | if (NOT IS_ABSOLUTE ${ARGS_FILE}) | ||||
630 | set(ARGS_FILE "${CMAKE_CURRENT_BINARY_DIR}/${ARGS_FILE}") | ||||
631 | endif() | ||||
632 | | ||||
633 | file(GENERATE | ||||
634 | OUTPUT "${ARGS_FILE}" | ||||
635 | CONTENT "${_content}" | ||||
636 | ) | ||||
637 | | ||||
638 | if (DEFINED ARGS_COMPONENT) | ||||
639 | set(_component COMPONENT ${ARGS_COMPONENT}) | ||||
640 | endif() | ||||
641 | install( | ||||
642 | FILES "${ARGS_FILE}" | ||||
643 | DESTINATION "${ARGS_DESTINATION}" | ||||
644 | ${_component} | ||||
645 | ) | ||||
646 | | ||||
647 | endfunction() |