Warning, /frameworks/extra-cmake-modules/modules/ECMAddQch.cmake is written in an unsupported language. File is not indexed.
0001 # SPDX-FileCopyrightText: 2016-2017 Friedrich W. H. Kossebau <kossebau@kde.org> 0002 # 0003 # SPDX-License-Identifier: BSD-3-Clause 0004 0005 #[=======================================================================[.rst: 0006 ECMAddQch 0007 ------------------ 0008 0009 This module provides the ``ecm_add_qch`` function for generating API 0010 documentation files in the QCH format, and the ``ecm_install_qch_export`` 0011 function for generating and installing exported CMake targets for such 0012 generated QCH files to enable builds of other software with generation of 0013 QCH files to create links into the given QCH files. 0014 0015 :: 0016 0017 ecm_add_qch(<target_name> 0018 NAME <name> 0019 VERSION <version> 0020 QCH_INSTALL_DESTINATION <qchfile_install_path> 0021 TAGFILE_INSTALL_DESTINATION <tagsfile_install_path> 0022 [COMPONENT <component>] 0023 [BASE_NAME <basename>] 0024 [SOURCE_DIRS <dir> [<dir2> [...]]] 0025 [SOURCES <file> [<file2> [...]]] 0026 |MD_MAINPAGE <md_file>] 0027 [INCLUDE_DIRS <incdir> [<incdir2> [...]]] 0028 [IMAGE_DIRS <idir> [<idir2> [...]]] 0029 [EXAMPLE_DIRS <edir> [<edir2> [...]]] 0030 [ORG_DOMAIN <domain>] 0031 [NAMESPACE <namespace>] 0032 [LINK_QCHS <qch> [<qch2> [...]]] 0033 [PREDEFINED_MACROS <macro[=content]> [<macro2[=content]> [...]]] 0034 [BLANK_MACROS <macro> [<macro2> [...]]] 0035 [CONFIG_TEMPLATE <configtemplate_file>] 0036 [VERBOSE] 0037 ) 0038 0039 This macro adds a target called <target_name> for the creation of an API 0040 documentation manual in the QCH format from the given sources. 0041 It currently uses doxygen, future versions might optionally also allow other 0042 tools. 0043 Next to the QCH file the target will generate a corresponding doxygen tag 0044 file, which enables creating links from other documentation into the 0045 generated QCH file. 0046 0047 It is recommended to make the use of this macro optional, by depending 0048 the call to ``ecm_add_qch`` on a CMake option being set, with a name like 0049 ``BUILD_QCH`` and being ``TRUE`` by default. This will allow the developers to 0050 saves resources on normal source development build cycles by setting this 0051 option to FALSE. 0052 0053 The macro will set the target properties ``DOXYGEN_TAGFILE``, ``QHP_NAMESPACE``, 0054 ``QHP_NAMESPACE_VERSIONED``, ``QHP_VIRTUALFOLDER`` and ``LINK_QCHS`` to the respective 0055 values, to allow other code access to them, e.g. the macro 0056 ``ecm_install_qch_export``. 0057 To enable the use of the target <target_name> as item for ``LINK_QCHS`` 0058 in further ``ecm_add_qch`` calls in the current build, 0059 additionally a target property ``DOXYGEN_TAGFILE_BUILD`` is set, with the path 0060 of the created doxygen tag file in the build dir. 0061 If existing, ``ecm_add_qch`` will use this property instead of 0062 ``DOXYGEN_TAGFILE`` for access to the tags file. 0063 0064 ``NAME`` specifies the name for the generated documentation. 0065 0066 ``VERSION`` specifies the version of the library for which the documentation is 0067 created. 0068 0069 ``BASE_NAME`` specifies the base name for the generated files. 0070 The default basename is ``<name>``. 0071 0072 ``SOURCE_DIRS`` specifies the dirs (incl. subdirs) with the source files for 0073 which the API documentation should be generated. Dirs can be relative to 0074 the current source dir. Dependencies to the files in the dirs are not 0075 tracked currently, other than with the ``SOURCES`` argument. So do not use for 0076 sources generated during the build. 0077 Needs to be used when ``SOURCES`` or ``CONFIG_TEMPLATE`` are not used. 0078 0079 ``SOURCES`` specifies the source files for which the API documentation should be 0080 generated. 0081 Needs to be used when ``SOURCE_DIRS`` or ``CONFIG_TEMPLATE`` are not used. 0082 0083 ``MD_MAINPAGE`` specifies a file in Markdown format that should be used as main 0084 page. This page will overrule any ``\mainpage`` command in the included 0085 sources. 0086 0087 ``INCLUDE_DIRS`` specifies the dirs which should be searched for included 0088 headers. Dirs can be relative to the current source dir. Since 5.63. 0089 0090 ``IMAGE_DIRS`` specifies the dirs which contain images that are included in the 0091 documentation. Dirs can be relative to the current source dir. 0092 0093 ``EXAMPLE_DIRS`` specifies the dirs which contain examples that are included in 0094 the documentation. Dirs can be relative to the current source dir. 0095 0096 ``QCH_INSTALL_DESTINATION`` specifies where the generated QCH file will be 0097 installed. 0098 0099 ``TAGFILE_INSTALL_DESTINATION`` specifies where the generated tag file will be 0100 installed. 0101 0102 ``COMPONENT`` specifies the installation component name with which the install 0103 rules for the generated QCH file and tag file are associated. 0104 0105 ``NAMESPACE`` can be used to set a custom namespace <namespace> of the generated 0106 QCH file. The namepspace is used as the unique id by QHelpEngine (cmp. 0107 https://doc.qt.io/qt-5/qthelpproject.html#namespace). 0108 The default namespace is ``<domain>.<name>``. 0109 Needs to be used when ``ORG_DOMAIN`` is not used. 0110 0111 ``ORG_DOMAIN`` can be used to define the organization domain prefix for the 0112 default namespace of the generated QCH file. 0113 Needs to be used when ``NAMESPACE`` is not used. 0114 0115 ``LINK_QCHS`` specifies a list of other QCH targets which should be used for 0116 creating references to API documentation of code in external libraries. 0117 For each target <qch> in the list these target properties are expected to be 0118 defined: ``DOXYGEN_TAGFILE``, ``QHP_NAMESPACE`` and ``QHP_VIRTUALFOLDER``. 0119 If any of these is not existing, <qch> will be ignored. 0120 Use the macro ``ecm_install_qch_export`` for exporting a target with these 0121 properties with the CMake config of a library. 0122 Any target <qch> can also be one created before in the same buildsystem by 0123 another call of ``ecm_add_qch``. 0124 0125 ``PREDEFINED_MACROS`` specifies a list of C/C++ macros which should be handled as 0126 given by the API dox generation tool. 0127 Examples are macros only defined in generated files, so whose 0128 definition might be not available to the tool. 0129 0130 ``BLANK_MACROS`` specifies a list of C/C++ macro names which should be ignored by 0131 the API dox generation tool and handled as if they resolve to empty strings. 0132 Examples are export macros only defined in generated files, so whose 0133 definition might be not available to the tool. 0134 0135 ``CONFIG_TEMPLATE`` specifies a custom cmake template file for the config file 0136 that is created to control the execution of the API dox generation tool. 0137 The following CMake variables need to be used: 0138 - ``ECM_QCH_DOXYGEN_QHELPGENERATOR_EXECUTABLE`` 0139 - ``ECM_QCH_DOXYGEN_FILEPATH, ECM_QCH_DOXYGEN_TAGFILE`` 0140 The following CMake variables can be used: 0141 - ``ECM_QCH_DOXYGEN_PROJECTNAME`` 0142 - ``ECM_QCH_DOXYGEN_PROJECTVERSION`` 0143 - ``ECM_QCH_DOXYGEN_VIRTUALFOLDER`` 0144 - ``ECM_QCH_DOXYGEN_FULLNAMESPACE`` 0145 - ``ECM_QCH_DOXYGEN_TAGFILES`` 0146 - ``ECM_QCH_DOXYGEN_WARN_LOGFILE`` 0147 - ``ECM_QCH_DOXYGEN_QUIET`` 0148 There is no guarantue that the other CMake variables currently used in the 0149 default config file template will also be present with the same semantics 0150 in future versions of this macro. 0151 0152 ``VERBOSE`` tells the API dox generation tool to be more verbose about its 0153 activity. 0154 0155 The default config file for the API dox generation tool, so the one when not 0156 using ``CONFIG_TEMPLATE``, allows code to handle the case of being processed by 0157 the tool by defining the C/C++ preprocessor macro ``K_DOXYGEN`` when run 0158 (since v5.67.0). For backward-compatibility also the definition 0159 ``DOXYGEN_SHOULD_SKIP_THIS`` is set, but its usage is deprecated. 0160 0161 Example usage: 0162 0163 .. code-block:: cmake 0164 0165 ecm_add_qch( 0166 MyLib_QCH 0167 NAME MyLib 0168 VERSION "0.42.0" 0169 ORG_DOMAIN org.myorg 0170 SOURCE_DIRS 0171 src 0172 LINK_QCHS 0173 Qt5Core_QCH 0174 Qt5Xml_QCH 0175 Qt5Gui_QCH 0176 Qt5Widgets_QCH 0177 BLANK_MACROS 0178 MyLib_EXPORT 0179 MyLib_DEPRECATED 0180 TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags 0181 QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch 0182 COMPONENT Devel 0183 ) 0184 0185 Example usage (with two QCH files, second linking first): 0186 0187 .. code-block:: cmake 0188 0189 ecm_add_qch( 0190 MyLib_QCH 0191 NAME MyLib 0192 VERSION ${MyLib_VERSION} 0193 ORG_DOMAIN org.myorg 0194 SOURCES ${MyLib_PUBLIC_HEADERS} 0195 MD_MAINPAGE src/mylib/README.md 0196 LINK_QCHS Qt5Core_QCH 0197 TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags 0198 QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch 0199 COMPONENT Devel 0200 ) 0201 ecm_add_qch( 0202 MyOtherLib_QCH 0203 NAME MyOtherLib 0204 VERSION ${MyOtherLib_VERSION} 0205 ORG_DOMAIN org.myorg 0206 SOURCES ${MyOtherLib_PUBLIC_HEADERS} 0207 MD_MAINPAGE src/myotherlib/README.md 0208 LINK_QCHS Qt5Core_QCH MyLib_QCH 0209 TAGFILE_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/tags 0210 QCH_INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}/share/docs/qch 0211 COMPONENT Devel 0212 ) 0213 0214 :: 0215 0216 ecm_install_qch_export( 0217 TARGETS [<name> [<name2> [...]]] 0218 FILE <file> 0219 DESTINATION <dest> 0220 [COMPONENT <component>] 0221 ) 0222 0223 This macro creates and installs a CMake file <file> which exports the given 0224 QCH targets <name> etc., so they can be picked up by CMake-based builds of 0225 other software that also generate QCH files (using ``ecm_add_qch``) and 0226 which should include links to the QCH files created by the given targets. 0227 The installed CMake file <file> is expected to be included by the CMake 0228 config file created for the software the related QCH files are documenting. 0229 0230 ``TARGETS`` specifies the QCH targets which should be exported. If a target does 0231 not exist or does not have all needed properties, a warning will be 0232 generated and the target skipped. 0233 This behaviour might change in future versions to result in a fail instead. 0234 0235 ``FILE`` specifies the name of the created CMake file, typically with a .cmake 0236 extension. 0237 0238 ``DESTINATION`` specifies the directory on disk to which the file will be 0239 installed. It usually is the same as the one where the CMake config files 0240 for this software are installed. 0241 0242 ``COMPONENT`` specifies the installation component name with which the 0243 install rule is associated. 0244 0245 Example usage: 0246 0247 .. code-block:: cmake 0248 0249 ecm_install_qch_export( 0250 TARGETS MyLib_QCH 0251 FILE MyLibQCHTargets.cmake 0252 DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/MyLib" 0253 COMPONENT Devel 0254 ) 0255 0256 Since 5.36.0. 0257 #]=======================================================================] 0258 0259 include(${CMAKE_CURRENT_LIST_DIR}/../modules/QtVersionOption.cmake) 0260 include(ECMQueryQt) 0261 0262 0263 # Helper method: adding the LINK_QCHS property to a Qt QCH targets, from module base names ("Core" etc.) 0264 # if target does not exist (e.g. because no tagsfile was found), this is a no-op 0265 macro(_ecm_setup_qt_qch_links _module) 0266 set(_target "Qt${QT_MAJOR_VERSION}${_module}_QCH") 0267 if(TARGET ${_target}) 0268 set(_linkqchs) 0269 foreach(_linkqch ${ARGN}) 0270 list(APPEND _linkqchs "Qt${QT_MAJOR_VERSION}${_linkqch}_QCH") 0271 endforeach() 0272 set_property(TARGET ${_target} PROPERTY LINK_QCHS ${_linkqchs}) 0273 endif() 0274 endmacro() 0275 0276 # Helper method: ensure Qt QCH targets are created 0277 function(_ecm_ensure_qt_qch_targets) 0278 # create QCH targets for Qt 0279 # Ideally one day Qt CMake Config files provide these 0280 if(NOT TARGET Qt${QT_MAJOR_VERSION}Core_QCH) 0281 # get Qt version, if any 0282 find_package(Qt${QT_MAJOR_VERSION}Core CONFIG QUIET) 0283 # lookup tag files 0284 ecm_query_qt(qt_docs_dir QT_INSTALL_DOCS TRY) 0285 find_path(_qtcoreTagsPath qtcore/qtcore.tags 0286 PATHS 0287 ${qt_docs_dir} 0288 ) 0289 0290 if(Qt${QT_MAJOR_VERSION}Core_FOUND AND _qtcoreTagsPath) 0291 string(REPLACE "." "" _version ${Qt${QT_MAJOR_VERSION}Core_VERSION}) 0292 # TODO: properly find each tag file 0293 # TODO: complete list of Qt modules 0294 if (QT_MAJOR_VERSION EQUAL "6") 0295 set(_module_list 0296 3D Bluetooth Concurrent Core DBus Gui Location 0297 Network Nfc Pdf Positioning PrintSupport Qml Quick 0298 Sensors SerialBus SerialPort Sql StateMachine Svg 0299 Test TextToSpeech WebChannel WebEngine WebSockets Widgets Xml) 0300 else() 0301 set(_module_list 0302 3D Bluetooth Concurrent Core DBus Gui Location 0303 Network Positioning PrintSupport Qml Quick 0304 Sensors SerialPort Sql Svg 0305 WebChannel WebEngine WebSockets Widgets Xml XmlPatterns) 0306 endif() 0307 foreach(_module ${_module_list}) 0308 string(TOLOWER ${_module} _lowermodule) 0309 0310 set(_tagfile "${_qtcoreTagsPath}/qt${_lowermodule}/qt${_lowermodule}.tags") 0311 if(EXISTS "${_tagfile}") 0312 add_custom_target(Qt${QT_MAJOR_VERSION}${_module}_QCH) 0313 set_target_properties(Qt${QT_MAJOR_VERSION}${_module}_QCH PROPERTIES 0314 DOXYGEN_TAGFILE "${_tagfile}" 0315 QHP_NAMESPACE "org.qt-project.qt${_lowermodule}" 0316 QHP_NAMESPACE_VERSIONED "org.qt-project.qt${_lowermodule}.${_version}" 0317 QHP_VIRTUALFOLDER "qt${_lowermodule}" 0318 IMPORTED TRUE 0319 ) 0320 endif() 0321 endforeach() 0322 _ecm_setup_qt_qch_links(3D Gui Core) 0323 _ecm_setup_qt_qch_links(Bluetooth DBus Core) 0324 _ecm_setup_qt_qch_links(Concurrent Gui Core) 0325 _ecm_setup_qt_qch_links(DBus Core) 0326 _ecm_setup_qt_qch_links(Gui Core) 0327 _ecm_setup_qt_qch_links(Location Positioning Gui Core) 0328 _ecm_setup_qt_qch_links(Network Core) 0329 if (QT_MAJOR_VERSION EQUAL "6") 0330 _ecm_setup_qt_qch_links(Nfc Core) 0331 _ecm_setup_qt_qch_links(Pdf Gui Core) 0332 endif() 0333 _ecm_setup_qt_qch_links(Positioning Core) 0334 _ecm_setup_qt_qch_links(PrintSupport Widgets Gui Core) 0335 _ecm_setup_qt_qch_links(Qml Network Core) 0336 _ecm_setup_qt_qch_links(Quick Qml Network Gui Core) 0337 _ecm_setup_qt_qch_links(Sensors Core) 0338 if (QT_MAJOR_VERSION EQUAL "6") 0339 _ecm_setup_qt_qch_links(SerialBus Core) 0340 endif() 0341 _ecm_setup_qt_qch_links(SerialPort Core) 0342 _ecm_setup_qt_qch_links(Sql Core) 0343 if (QT_MAJOR_VERSION EQUAL "6") 0344 _ecm_setup_qt_qch_links(StateMachine Core) 0345 endif() 0346 _ecm_setup_qt_qch_links(Svg Widgets Gui Core) 0347 _ecm_setup_qt_qch_links(Test Core) 0348 if (QT_MAJOR_VERSION EQUAL "6") 0349 _ecm_setup_qt_qch_links(TextToSpeech Core) 0350 endif() 0351 _ecm_setup_qt_qch_links(WebChannel Qml Core) 0352 _ecm_setup_qt_qch_links(WebEngine Quick Qml Gui Core) 0353 _ecm_setup_qt_qch_links(WebSockets Network Core) 0354 _ecm_setup_qt_qch_links(Widgets Gui Core) 0355 _ecm_setup_qt_qch_links(Xml Core) 0356 if (QT_MAJOR_VERSION EQUAL "5") 0357 _ecm_setup_qt_qch_links(XmlPatterns Network Core) 0358 endif() 0359 endif() 0360 endif() 0361 endfunction() 0362 0363 # Helper method: collect all qch targets from the LINK_QCHS dependency tree and set result to <var> 0364 function(_ecm_collect_linkable_qch_targets name) 0365 set(_candidate_qchs ${ARGN}) 0366 set(_handled_qchs) 0367 set(_good_qchs) 0368 # while unhandled qch targets 0369 while(_candidate_qchs) 0370 # get another unhandled qch target 0371 list(GET _candidate_qchs 0 _qch) 0372 list(REMOVE_AT _candidate_qchs 0) 0373 list(FIND _handled_qchs ${_qch} _index) 0374 # if not already handled 0375 if(_index EQUAL -1) 0376 list(APPEND _handled_qchs ${_qch}) 0377 if(TARGET ${_qch}) 0378 # always look at other linked qch targets, also for incomplete targets 0379 get_property(_link_qchs TARGET ${_qch} PROPERTY LINK_QCHS) 0380 if(_link_qchs) 0381 list(APPEND _candidate_qchs ${_link_qchs}) 0382 endif() 0383 # check if this target has all needed properties 0384 set(_target_usable TRUE) 0385 foreach(_propertyname 0386 DOXYGEN_TAGFILE 0387 QHP_NAMESPACE 0388 QHP_VIRTUALFOLDER 0389 ) 0390 get_target_property(_property ${_qch} ${_propertyname}) 0391 if(NOT _property) 0392 message(STATUS "No property ${_propertyname} set on ${_qch} when calling ecm_add_qch(). <<${_property}>>") 0393 set(_target_usable FALSE) 0394 endif() 0395 endforeach() 0396 get_target_property(_tagfile_build ${_qch} DOXYGEN_TAGFILE_BUILD) 0397 if (NOT _tagfile_build) 0398 get_target_property(_tagfile ${_qch} DOXYGEN_TAGFILE) 0399 if(NOT EXISTS ${_tagfile}) 0400 message(STATUS "No such tag file \"${_tagfile}\" found for ${_qch} when calling ecm_add_qch().") 0401 set(_target_usable FALSE) 0402 endif() 0403 endif() 0404 if(_target_usable) 0405 list(APPEND _good_qchs ${_qch}) 0406 else() 0407 message(WARNING "No linking to API dox of ${_qch}.") 0408 endif() 0409 else() 0410 message(STATUS "No such target ${_qch} defined when calling ecm_add_qch(), ignored.") 0411 endif() 0412 endif() 0413 endwhile() 0414 set(${name} ${_good_qchs} PARENT_SCOPE) 0415 endfunction() 0416 0417 0418 function(ecm_add_qch target_name) 0419 # Parse arguments 0420 set(options VERBOSE) 0421 set(oneValueArgs NAME BASE_NAME QCH_INSTALL_DESTINATION TAGFILE_INSTALL_DESTINATION COMPONENT VERSION NAMESPACE MD_MAINPAGE ORG_DOMAIN CONFIG_TEMPLATE) 0422 set(multiValueArgs SOURCE_DIRS SOURCES INCLUDE_DIRS IMAGE_DIRS EXAMPLE_DIRS PREDEFINED_MACROS BLANK_MACROS LINK_QCHS) 0423 cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 0424 0425 # check required args 0426 foreach(_arg_name NAME QCH_INSTALL_DESTINATION TAGFILE_INSTALL_DESTINATION VERSION) 0427 if(NOT DEFINED ARGS_${_arg_name}) 0428 message(FATAL_ERROR "${_arg_name} needs to be defined when calling ecm_add_qch") 0429 endif() 0430 endforeach() 0431 if(NOT DEFINED ARGS_SOURCE_DIRS AND NOT DEFINED ARGS_SOURCES AND NOT DEFINED ARGS_CONFIG_TEMPLATE) 0432 message(FATAL_ERROR "SOURCE_DIRS or SOURCES needs to be defined when calling ecm_add_qch") 0433 endif() 0434 if(DEFINED ARGS_SOURCE_DIRS AND DEFINED ARGS_SOURCES) 0435 message(FATAL_ERROR "Either SOURCE_DIRS or SOURCES, not both, needs to be defined when calling ecm_add_qch") 0436 endif() 0437 if(NOT DEFINED ARGS_ORG_DOMAIN AND NOT DEFINED ARGS_NAMESPACE) 0438 message(FATAL_ERROR "ORG_DOMAIN or NAMESPACE needs to be defined when calling ecm_add_qch") 0439 endif() 0440 0441 # find required tools 0442 if (NOT DOXYGEN_PATCHED_JSFILESADDED) 0443 set(REQUIRED_DOXYGEN_VERSION 1.8.13) 0444 endif() 0445 find_package(Doxygen ${REQUIRED_DOXYGEN_VERSION} REQUIRED) 0446 if (NOT DOXYGEN_FOUND AND NOT DOXYGEN_PATCHED_JSFILESADDED) 0447 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)") 0448 endif() 0449 set_package_properties(Doxygen PROPERTIES 0450 TYPE REQUIRED 0451 PURPOSE "Needed for API dox QCH file generation${doxygen_description_addition}" 0452 ) 0453 0454 if (QT_MAJOR_VERSION EQUAL "5") 0455 find_package(QHelpGenerator REQUIRED) 0456 set_package_properties(QHelpGenerator PROPERTIES 0457 TYPE REQUIRED 0458 PURPOSE "Needed for API dox QCH file generation" 0459 DESCRIPTION "Part of Qt5 tools" 0460 ) 0461 else() 0462 find_package(Qt6 COMPONENTS ToolsTools CONFIG REQUIRED) 0463 set_package_properties(Qt6ToolsTools PROPERTIES 0464 TYPE REQUIRED 0465 PURPOSE "Needed for API dox QCH file generation" 0466 DESCRIPTION "qhelpgenerator from Qt6 tools" 0467 ) 0468 if(TARGET Qt6::qhelpgenerator) 0469 get_target_property(QHelpGenerator_EXECUTABLE Qt6::qhelpgenerator LOCATION) 0470 endif() 0471 endif() 0472 0473 set(_missing_tools) 0474 if (NOT DOXYGEN_FOUND) 0475 list(APPEND _missing_tools "Doxygen") 0476 endif() 0477 if (NOT QHelpGenerator_FOUND AND NOT TARGET Qt6::qhelpgenerator) 0478 list(APPEND _missing_tools "qhelpgenerator") 0479 endif() 0480 0481 if (_missing_tools) 0482 message(WARNING "API dox QCH file will not be generated, tools missing: ${_missing_tools}!") 0483 else() 0484 _ecm_ensure_qt_qch_targets() 0485 0486 # prepare base dirs, working file names and other vars 0487 if (DEFINED ARGS_BASE_NAME) 0488 set(_basename ${ARGS_BASE_NAME}) 0489 else() 0490 set(_basename ${ARGS_NAME}) 0491 endif() 0492 set(_qch_file_basename "${_basename}.qch") 0493 set(_tags_file_basename "${_basename}.tags") 0494 set(_qch_buildpath "${CMAKE_CURRENT_BINARY_DIR}/${_qch_file_basename}") 0495 set(_tags_buildpath "${CMAKE_CURRENT_BINARY_DIR}/${_tags_file_basename}") 0496 set(_apidox_builddir "${CMAKE_CURRENT_BINARY_DIR}/${_basename}_ECMQchDoxygen") 0497 if (DEFINED ARGS_NAMESPACE) 0498 set(_namespace "${ARGS_NAMESPACE}") 0499 else() 0500 set(_namespace "${ARGS_ORG_DOMAIN}.${ARGS_NAME}") 0501 endif() 0502 string(REPLACE "." "_" _dotLessVersion ${ARGS_VERSION}) 0503 set(_versioned_namespace "${_namespace}.${_dotLessVersion}") 0504 set(_sources) 0505 set(_dep_tagfiles) 0506 set(_dep_qch_targets) 0507 0508 ### Create doxygen config file 0509 set(_doxygenconfig_file "${CMAKE_CURRENT_BINARY_DIR}/${_basename}_ECMQchDoxygen.config") 0510 if (DEFINED ARGS_CONFIG_TEMPLATE) 0511 set(_doxygenconfig_template_file "${ARGS_CONFIG_TEMPLATE}") 0512 else() 0513 set(_doxygenconfig_template_file "${ECM_MODULE_DIR}/ECMQchDoxygen.config.in") 0514 endif() 0515 set(_doxygen_layout_file "${ECM_MODULE_DIR}/ECMQchDoxygenLayout.xml") 0516 # Setup variables used in config file template, ECM_QCH_DOXYGEN_* 0517 set(ECM_QCH_DOXYGEN_OUTPUTDIR "\"${_apidox_builddir}\"") 0518 set(ECM_QCH_DOXYGEN_TAGFILE "\"${_tags_buildpath}\"") 0519 set(ECM_QCH_DOXYGEN_LAYOUTFILE "\"${_doxygen_layout_file}\"") 0520 set(ECM_QCH_DOXYGEN_INCLUDE_PATH) 0521 foreach(_include_DIR IN LISTS ARGS_INCLUDE_DIRS) 0522 if (NOT IS_ABSOLUTE ${_include_DIR}) 0523 set(_include_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_include_DIR}") 0524 endif() 0525 # concat dirs separated by a break, it is no issue that first has also a leading break 0526 set(ECM_QCH_DOXYGEN_INCLUDE_PATH "${ECM_QCH_DOXYGEN_INCLUDE_PATH} \\\n\"${_include_DIR}\"") 0527 endforeach() 0528 set(ECM_QCH_DOXYGEN_IMAGEDIRS) 0529 foreach(_image_DIR IN LISTS ARGS_IMAGE_DIRS) 0530 if (NOT IS_ABSOLUTE ${_image_DIR}) 0531 set(_image_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_image_DIR}") 0532 endif() 0533 # concat dirs separated by a break, it is no issue that first has also a leading break 0534 set(ECM_QCH_DOXYGEN_IMAGEDIRS "${ECM_QCH_DOXYGEN_IMAGEDIRS} \\\n\"${_image_DIR}\"") 0535 endforeach() 0536 set(ECM_QCH_DOXYGEN_EXAMPLEDIRS) 0537 foreach(_example_DIR IN LISTS ARGS_EXAMPLE_DIRS) 0538 if (NOT IS_ABSOLUTE ${_example_DIR}) 0539 set(_example_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_example_DIR}") 0540 endif() 0541 # concat dirs separated by a break, it is no issue that first has also a leading break 0542 set(ECM_QCH_DOXYGEN_EXAMPLEDIRS "${ECM_QCH_DOXYGEN_EXAMPLEDIRS} \\\n\"${_example_DIR}\"") 0543 endforeach() 0544 if (ARGS_MD_MAINPAGE) 0545 if (NOT IS_ABSOLUTE ${ARGS_MD_MAINPAGE}) 0546 set(ARGS_MD_MAINPAGE "${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_MD_MAINPAGE}") 0547 endif() 0548 set(ECM_QCH_DOXYGEN_MAINPAGE_MDFILE "\"${ARGS_MD_MAINPAGE}\"") 0549 else() 0550 set(ECM_QCH_DOXYGEN_MAINPAGE_MDFILE) 0551 endif() 0552 set(ECM_QCH_DOXYGEN_INPUT) 0553 if (ARGS_SOURCE_DIRS) 0554 foreach(_source_DIR IN LISTS ARGS_SOURCE_DIRS) 0555 if (NOT IS_ABSOLUTE ${_source_DIR}) 0556 set(_source_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${_source_DIR}") 0557 endif() 0558 # concat dirs separated by a break, it is no issue that first has also a leading break 0559 set(ECM_QCH_DOXYGEN_INPUT "${ECM_QCH_DOXYGEN_INPUT} \\\n\"${_source_DIR}\"") 0560 endforeach() 0561 if (ARGS_MD_MAINPAGE) 0562 set(ECM_QCH_DOXYGEN_INPUT "${ECM_QCH_DOXYGEN_INPUT} \\\n\"${ARGS_MD_MAINPAGE}\"") 0563 endif() 0564 set(ECM_QCH_DOXYGEN_FILE_PATTERNS "*.h *.cpp *.hpp *.hh *.cc *.h++ *.c++ *.hxx *.cxx *.dox *.md") 0565 else() 0566 foreach(_source IN LISTS ARGS_SOURCES) 0567 if (NOT IS_ABSOLUTE ${_source}) 0568 set(_source "${CMAKE_CURRENT_SOURCE_DIR}/${_source}") 0569 endif() 0570 list(APPEND _sources "${_source}") 0571 endforeach() 0572 if (ARGS_MD_MAINPAGE) 0573 list(FIND _sources ${ARGS_MD_MAINPAGE} _mainpage_index) 0574 if (_mainpage_index STREQUAL -1) 0575 list(APPEND _sources "${ARGS_MD_MAINPAGE}") 0576 endif() 0577 endif() 0578 foreach(_source IN LISTS _sources) 0579 # concat sources separated by a break, it is no issue that first has also a leading break 0580 set(ECM_QCH_DOXYGEN_INPUT "${ECM_QCH_DOXYGEN_INPUT} \\\n\"${_source}\"") 0581 endforeach() 0582 set(ECM_QCH_DOXYGEN_FILE_PATTERNS "") 0583 endif() 0584 0585 set(ECM_QCH_DOXYGEN_PROJECTNAME ${ARGS_NAME}) 0586 file(RELATIVE_PATH _builddirrelative_filepath "${_apidox_builddir}/html" ${_qch_buildpath}) 0587 set(ECM_QCH_DOXYGEN_FILEPATH "\"${_builddirrelative_filepath}\"") 0588 set(ECM_QCH_DOXYGEN_PROJECTVERSION ${ARGS_VERSION}) 0589 string(TOLOWER ${ARGS_NAME} ECM_QCH_DOXYGEN_VIRTUALFOLDER) 0590 set(ECM_QCH_DOXYGEN_FULLNAMESPACE ${_versioned_namespace}) 0591 set(ECM_QCH_DOXYGEN_PREDEFINED_MACROS) 0592 foreach(_macro IN LISTS ARGS_PREDEFINED_MACROS) 0593 # concat dirs separated by a break, it is no issue that first has also a leading break 0594 # wrap each macro in quotes, to handle potential blanks and commas 0595 string(REPLACE "\"" "\\\"" _macro "${_macro}") 0596 set(ECM_QCH_DOXYGEN_PREDEFINED_MACROS "${ECM_QCH_DOXYGEN_PREDEFINED_MACROS} \\\n\"${_macro}\"") 0597 endforeach() 0598 set(ECM_QCH_DOXYGEN_BLANK_MACROS) 0599 foreach(_macro IN LISTS ARGS_BLANK_MACROS) 0600 # concat dirs separated by a break, it is no issue that first has also a leading break 0601 # wrap each macro in quotes, to handle potential blanks and commas 0602 string(REPLACE "\"" "\\\"" _macro "${_macro}") 0603 set(ECM_QCH_DOXYGEN_BLANK_MACROS "${ECM_QCH_DOXYGEN_BLANK_MACROS} \\\n\"${_macro}=\"") 0604 endforeach() 0605 0606 # create list of tag files for linking other QCH files 0607 set(ECM_QCH_DOXYGEN_TAGFILES) 0608 _ecm_collect_linkable_qch_targets(_link_qchs ${ARGS_LINK_QCHS}) 0609 foreach(_link_qch IN LISTS _link_qchs) 0610 list(APPEND _dep_qch_targets ${_link_qch}) 0611 get_target_property(_link_qch_tagfile ${_link_qch} DOXYGEN_TAGFILE) 0612 get_target_property(_link_qch_tagfile_build ${_link_qch} DOXYGEN_TAGFILE_BUILD) 0613 get_target_property(_link_qch_namespace ${_link_qch} QHP_NAMESPACE) 0614 get_target_property(_link_qch_virtualfolder ${_link_qch} QHP_VIRTUALFOLDER) 0615 # if same build, then prefer build version over any installed one 0616 if (_link_qch_tagfile_build) 0617 set(_link_qch_tagfile ${_link_qch_tagfile_build}) 0618 list(APPEND _dep_tagfiles "${_link_qch_tagfile}") 0619 endif() 0620 get_property(_linkqchs TARGET ${_link_qch} PROPERTY LINK_QCHS) 0621 set(_tagfile_entry "\"${_link_qch_tagfile}=qthelp://${_link_qch_namespace}/${_link_qch_virtualfolder}/\"") 0622 # concat dirs separated by a break, it is no issue that first has also a leading break 0623 set(ECM_QCH_DOXYGEN_TAGFILES "${ECM_QCH_DOXYGEN_TAGFILES} \\\n${_tagfile_entry}") 0624 endforeach() 0625 0626 set(ECM_QCH_DOXYGEN_WARN_LOGFILE "\"${_doxygenconfig_file}.log\"") 0627 if(ARGS_VERBOSE) 0628 set(ECM_QCH_DOXYGEN_QUIET "NO") 0629 else() 0630 set(ECM_QCH_DOXYGEN_QUIET "YES") 0631 endif() 0632 set(ECM_QCH_DOXYGEN_QHELPGENERATOR_EXECUTABLE ${QHelpGenerator_EXECUTABLE}) 0633 0634 # finally create doxygen config file 0635 configure_file( 0636 "${_doxygenconfig_template_file}" 0637 "${_doxygenconfig_file}" 0638 @ONLY 0639 ) 0640 # Doxygen warns verbosely about outdated config entries. 0641 # To spare custom code here to generate configuration with no out-dated entries, 0642 # instead make use of the doxygen feature to update configuration files. 0643 execute_process( 0644 COMMAND ${DOXYGEN_EXECUTABLE} -u "${_doxygenconfig_file}" 0645 ERROR_VARIABLE _doxygen_update_error 0646 RESULT_VARIABLE _doxygen_update_result 0647 ) 0648 if(NOT ${_doxygen_update_result} STREQUAL "0") 0649 message(WARNING "Updating the doxygen config file failed: ${_doxygen_update_error}") 0650 endif() 0651 0652 # setup make target 0653 set(_qch_INSTALLPATH ${ARGS_QCH_INSTALL_DESTINATION}) 0654 set(_tags_INSTALLPATH ${ARGS_TAGFILE_INSTALL_DESTINATION}) 0655 file(RELATIVE_PATH _relative_qch_file ${CMAKE_BINARY_DIR} ${_qch_buildpath}) 0656 file(RELATIVE_PATH _relative_tags_file ${CMAKE_BINARY_DIR} ${_tags_buildpath}) 0657 add_custom_command( 0658 OUTPUT ${_qch_buildpath} ${_tags_buildpath} 0659 COMMENT "Generating ${_relative_qch_file}, ${_relative_tags_file}" 0660 COMMAND cmake -E remove_directory "${ECM_QCH_DOXYGEN_OUTPUTDIR}" 0661 COMMAND cmake -E make_directory "${ECM_QCH_DOXYGEN_OUTPUTDIR}" 0662 COMMAND ${DOXYGEN_EXECUTABLE} "${_doxygenconfig_file}" 0663 DEPENDS 0664 ${_doxygenconfig_file} 0665 ${_doxygen_layout_file} 0666 ${_sources} 0667 ${_dep_tagfiles} 0668 ${_dep_qch_targets} 0669 ) 0670 add_custom_target(${target_name} ALL DEPENDS ${_qch_buildpath} ${_tags_buildpath}) 0671 set_target_properties(${target_name} PROPERTIES 0672 DOXYGEN_TAGFILE "${_qch_INSTALLPATH}/${_tags_file_basename}" 0673 DOXYGEN_TAGFILE_NAME "${_tags_file_basename}" 0674 DOXYGEN_TAGFILE_INSTALLDIR "${_qch_INSTALLPATH}" 0675 DOXYGEN_TAGFILE_BUILD "${_tags_buildpath}" 0676 QHP_NAMESPACE "${_namespace}" 0677 QHP_NAMESPACE_VERSIONED "${_versioned_namespace}" 0678 QHP_VIRTUALFOLDER "${ECM_QCH_DOXYGEN_VIRTUALFOLDER}" 0679 ) 0680 # list as value does not work with set_target_properties 0681 set_property(TARGET ${target_name} PROPERTY LINK_QCHS "${ARGS_LINK_QCHS}") 0682 0683 if (DEFINED ARGS_COMPONENT) 0684 set(_component COMPONENT ${ARGS_COMPONENT}) 0685 else() 0686 set(_component) 0687 endif() 0688 0689 # setup installation 0690 install(FILES 0691 ${_qch_buildpath} 0692 DESTINATION ${_qch_INSTALLPATH} 0693 ${_component} 0694 ) 0695 0696 install(FILES 0697 ${_tags_buildpath} 0698 DESTINATION ${_tags_INSTALLPATH} 0699 ${_component} 0700 ) 0701 endif() 0702 0703 endfunction() 0704 0705 0706 function(ecm_install_qch_export) 0707 set(options ) 0708 set(oneValueArgs FILE DESTINATION COMPONENT) 0709 set(multiValueArgs TARGETS) 0710 0711 cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) 0712 0713 if(NOT DEFINED ARGS_FILE) 0714 message(FATAL_ERROR "FILE needs to be defined when calling ecm_install_qch_export().") 0715 endif() 0716 0717 if(NOT DEFINED ARGS_DESTINATION) 0718 message(FATAL_ERROR "DESTINATION needs to be defined when calling ecm_install_qch_export().") 0719 endif() 0720 0721 # TARGETS may be empty (and ARGS_TARGETS will not be defined then by cmake_parse_arguments) 0722 0723 set(_content 0724 "# This file was generated by ecm_install_qch_export(). DO NOT EDIT! 0725 " 0726 ) 0727 0728 foreach(_target IN LISTS ARGS_TARGETS) 0729 set(_target_usable TRUE) 0730 0731 if (NOT TARGET ${_target}) 0732 message(STATUS "No such target ${_target} when calling ecm_install_qch_export().") 0733 set(_target_usable FALSE) 0734 else() 0735 foreach(_propertyname 0736 DOXYGEN_TAGFILE_NAME 0737 DOXYGEN_TAGFILE_INSTALLDIR 0738 QHP_NAMESPACE 0739 QHP_NAMESPACE_VERSIONED 0740 QHP_VIRTUALFOLDER 0741 ) 0742 get_target_property(_property ${_target} ${_propertyname}) 0743 if(NOT _property) 0744 message(STATUS "No property ${_propertyname} set on ${_target} when calling ecm_install_qch_export(). <${_property}>") 0745 set(_target_usable FALSE) 0746 endif() 0747 endforeach() 0748 endif() 0749 if(_target_usable) 0750 get_target_property(_tagfile_name ${_target} DOXYGEN_TAGFILE_NAME) 0751 get_target_property(_tagfile_installdir ${_target} DOXYGEN_TAGFILE_INSTALLDIR) 0752 if (NOT IS_ABSOLUTE ${_tagfile_installdir}) 0753 set(_tagfile_installdir "${CMAKE_INSTALL_PREFIX}/${_tagfile_installdir}") 0754 endif() 0755 get_target_property(_namespace ${_target} QHP_NAMESPACE) 0756 get_target_property(_namespace_versioned ${_target} QHP_NAMESPACE_VERSIONED) 0757 get_target_property(_virtualfolder ${_target} QHP_VIRTUALFOLDER) 0758 get_property(_linkqchs TARGET ${_target} PROPERTY LINK_QCHS) 0759 set(_content "${_content} 0760 if (NOT TARGET ${_target}) 0761 0762 add_custom_target(${_target}) 0763 set_target_properties(${_target} PROPERTIES 0764 DOXYGEN_TAGFILE \"${_tagfile_installdir}/${_tagfile_name}\" 0765 QHP_NAMESPACE \"${_namespace}\" 0766 QHP_NAMESPACE_VERSIONED \"${_namespace_versioned}\" 0767 QHP_VIRTUALFOLDER \"${_virtualfolder}\" 0768 IMPORTED TRUE 0769 ) 0770 set_property(TARGET ${_target} PROPERTY LINK_QCHS ${_linkqchs}) 0771 0772 endif() 0773 " 0774 ) 0775 else() 0776 message(STATUS "No target exported for ${_target}.") 0777 endif() 0778 endforeach() 0779 0780 if (NOT IS_ABSOLUTE ${ARGS_FILE}) 0781 set(ARGS_FILE "${CMAKE_CURRENT_BINARY_DIR}/${ARGS_FILE}") 0782 endif() 0783 0784 file(GENERATE 0785 OUTPUT "${ARGS_FILE}" 0786 CONTENT "${_content}" 0787 ) 0788 0789 if (DEFINED ARGS_COMPONENT) 0790 set(_component COMPONENT ${ARGS_COMPONENT}) 0791 else() 0792 set(_component) 0793 endif() 0794 install( 0795 FILES "${ARGS_FILE}" 0796 DESTINATION "${ARGS_DESTINATION}" 0797 ${_component} 0798 ) 0799 0800 endfunction()