summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Komissarov <abbapoh@gmail.com>2021-09-04 14:22:12 +0300
committerIvan Komissarov <ABBAPOH@gmail.com>2021-09-07 10:40:40 +0000
commit1acd941b42e6f99b55312bef93cfd448945409cb (patch)
tree6d7bc055a0433d64f4be5d26b28bd85e72be12b5
parent117393c7adf0dbbdefba0a274073831da96ba5dc (diff)
downloadqbs-1acd941b42e6f99b55312bef93cfd448945409cb.tar.gz
cmake: Build docs without Qbs
Fixes: QBS-1671 Change-Id: I3f0522d6990caa661997dd773d9b3af662bd2ed8 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
-rw-r--r--CMakeLists.txt10
-rw-r--r--cmake/QbsBuildConfig.cmake2
-rw-r--r--cmake/QbsDocumentation.cmake285
-rw-r--r--doc/CMakeLists.txt84
4 files changed, 296 insertions, 85 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d32301116..4129bc911 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(FeatureSummary)
include(QbsBuildConfig)
+include(QbsDocumentation)
file(STRINGS VERSION QBS_VERSION)
project(Qbs VERSION ${QBS_VERSION})
@@ -57,6 +58,15 @@ else()
endif()
endif()
+if (QBS_INSTALL_HTML_DOCS OR QBS_INSTALL_QCH_DOCS)
+ find_package(Python3 COMPONENTS Interpreter)
+ if (Qt6_FOUND)
+ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Tools REQUIRED)
+ else()
+ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Help REQUIRED)
+ endif()
+endif()
+
add_subdirectory(src)
add_subdirectory(doc)
add_subdirectory(share)
diff --git a/cmake/QbsBuildConfig.cmake b/cmake/QbsBuildConfig.cmake
index 08e36bc67..28827268d 100644
--- a/cmake/QbsBuildConfig.cmake
+++ b/cmake/QbsBuildConfig.cmake
@@ -3,8 +3,6 @@ option(WITH_UNIT_TESTS "Build Unit Tests" OFF)
option(INSTALL_PUBLIC_HEADERS "Whether to install public headers" ON)
option(QBS_ENABLE_RPATH "Whether to enable RPATH" ON)
option(QBS_USE_BUNDLED_QT_SCRIPT "Whether to use bundled QtScript module" OFF)
-option(QBS_INSTALL_HTML_DOCS "Whether to install HTML Documentation" OFF)
-option(QBS_INSTALL_QCH_DOCS "Whether to install QCH Documentation" OFF)
set(QBS_APP_INSTALL_DIR "bin" CACHE STRING "Relative install location for Qbs binaries.")
# default paths
diff --git a/cmake/QbsDocumentation.cmake b/cmake/QbsDocumentation.cmake
new file mode 100644
index 000000000..dad04d312
--- /dev/null
+++ b/cmake/QbsDocumentation.cmake
@@ -0,0 +1,285 @@
+# Options:
+option(QBS_INSTALL_HTML_DOCS "Whether to install Qbs HTML Documentation" OFF)
+option(QBS_INSTALL_QCH_DOCS "Whether to install Qbs QCH Documentation" OFF)
+
+# Get information on directories from qmake
+# as this is not yet exported by cmake.
+# Used for QT_INSTALL_DOCS
+function(qt_query_qmake)
+ if (NOT TARGET Qt${QT_VERSION_MAJOR}::qmake)
+ message(FATAL_ERROR "Qmake was not found. Add find_package(Qt5 COMPONENTS Core) to CMake to enable.")
+ endif()
+ # dummy check for if we already queried qmake
+ if (QT_INSTALL_BINS)
+ return()
+ endif()
+
+ get_target_property(_qmake_binary Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
+ execute_process(COMMAND "${_qmake_binary}" "-query"
+ TIMEOUT 10
+ RESULT_VARIABLE _qmake_result
+ OUTPUT_VARIABLE _qmake_stdout
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if (NOT "${_qmake_result}" STREQUAL "0")
+ message(FATAL_ERROR "Qmake did not execute successfully: ${_qmake_result}.")
+ endif()
+
+ # split into lines:
+ string(REPLACE "\n" ";" _lines "${_qmake_stdout}")
+
+ foreach(_line ${_lines})
+ # split line into key/value pairs
+ string(REPLACE ":" ";" _parts "${_line}")
+ list(GET _parts 0 _key)
+ list(REMOVE_AT _parts 0)
+ string(REPLACE ";" ":" _value "${_parts}")
+
+ set("${_key}" "${_value}" CACHE PATH "qmake import of ${_key}" FORCE)
+ endforeach()
+endfunction()
+
+# Find programs:
+function(_qbs_doc_find_program result_var)
+ if (NOT TARGET Qt${QT_VERSION_MAJOR}::qmake)
+ message(FATAL_ERROR "QDoc is only available in Qt projects")
+ endif()
+
+ get_target_property(_qmake_binary Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
+ get_filename_component(_qmake_dir "${_qmake_binary}" DIRECTORY)
+ find_program("_prg_${result_var}" ${ARGN} HINTS "${_qmake_dir}")
+ if ("_prg_${result_var}" STREQUAL "_prg_${result_var}-NOTFOUND")
+ set("_prg_${result_var}" "${result_var}-NOTFOUND")
+ message(WARNING "Could not find binary for ${result_var}")
+ endif()
+
+ set(${result_var} "${_prg_${result_var}}" PARENT_SCOPE)
+endfunction()
+
+function(_qbs_setup_doc_targets)
+ # Set up important targets:
+ if (NOT TARGET qbs_html_docs)
+ add_custom_target(qbs_html_docs COMMENT "Build HTML documentation")
+ endif()
+ if (NOT TARGET qbs_qch_docs)
+ add_custom_target(qbs_qch_docs COMMENT "Build QCH documentation")
+ endif()
+ if (NOT TARGET BuildQbsDocumentation)
+ add_custom_target(
+ BuildQbsDocumentation ALL COMMENT "Build Qbs documentation")
+ add_dependencies(BuildQbsDocumentation qbs_html_docs qbs_qch_docs)
+ endif()
+endfunction()
+
+function(_find_python_module module)
+ string(TOUPPER ${module} module_upper)
+ if (NOT PY_${module_upper})
+ if (ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED")
+ set(${module}_FIND_REQUIRED TRUE)
+ endif()
+ # A module's location is usually a directory, but for binary modules
+ # it's a .so file.
+ execute_process(COMMAND "${Python3_EXECUTABLE}" "-c"
+ "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
+ RESULT_VARIABLE _${module}_status
+ OUTPUT_VARIABLE _${module}_location
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if (NOT _${module}_status)
+ set(PY_${module_upper} ${_${module}_location} CACHE STRING
+ "Location of Python module ${module}")
+ endif()
+ endif()
+ find_package_handle_standard_args(PY_${module} DEFAULT_MSG PY_${module_upper})
+endfunction()
+
+function(_qbs_setup_qdoc_targets _qdocconf_file _retval)
+ cmake_parse_arguments(_arg "" "HTML_DIR;INSTALL_DIR;POSTFIX"
+ "INDEXES;INCLUDE_DIRECTORIES;FRAMEWORK_PATHS;ENVIRONMENT_EXPORTS" ${ARGN})
+
+ foreach(_index ${_arg_INDEXES})
+ list(APPEND _qdoc_index_args "-indexdir;${_index}")
+ endforeach()
+
+ set(_env "")
+ foreach(_export ${_arg_ENVIRONMENT_EXPORTS})
+ if (NOT DEFINED "${_export}")
+ message(FATAL_ERROR "${_export} is not known when trying to export it to qdoc.")
+ endif()
+ list(APPEND _env "${_export}=${${_export}}")
+ endforeach()
+
+ set(_full_qdoc_command "${_qdoc}")
+ if (_env)
+ set(_full_qdoc_command "${CMAKE_COMMAND}" "-E" "env" ${_env} "${_qdoc}")
+ endif()
+
+ if (_arg_HTML_DIR STREQUAL "")
+ set(_arg_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc")
+ endif()
+
+ get_filename_component(_target "${_qdocconf_file}" NAME_WE)
+
+ # message(${_target})
+ # set(_html_outputdir "${_arg_HTML_DIR}/${_target}${_arg_POSTFIX}")
+ set(_html_outputdir "${_arg_HTML_DIR}")
+ file(MAKE_DIRECTORY "${_html_outputdir}")
+
+ set(_qdoc_include_args "")
+ if (_arg_INCLUDE_DIRECTORIES OR _arg_FRAMEWORK_PATHS)
+ # pass include directories to qdoc via hidden @ option, since we need to generate a file
+ # to be able to resolve the generators inside the include paths
+ set(_qdoc_includes "${CMAKE_CURRENT_BINARY_DIR}/cmake/qdoc_${_target}.inc")
+ set(_qdoc_include_args "@${_qdoc_includes}")
+ set(_includes "")
+ if (_arg_INCLUDE_DIRECTORIES)
+ set(_includes "-I$<JOIN:${_arg_INCLUDE_DIRECTORIES},\n-I>\n")
+ endif()
+ set(_frameworks "")
+ if (_arg_FRAMEWORK_PATHS)
+ set(_frameworks "-F$<JOIN:${_arg_FRAMEWORK_PATHS},\n-F>\n")
+ endif()
+ file(GENERATE
+ OUTPUT "${_qdoc_includes}"
+ CONTENT "${_includes}${_frameworks}"
+ )
+ endif()
+
+ set(_html_target "html_docs_${_target}")
+ add_custom_target("${_html_target}"
+ ${_full_qdoc_command} -outputdir "${_html_outputdir}" "${_qdocconf_file}"
+ ${_qdoc_index_args} ${_qdoc_include_args}
+ COMMENT "Build HTML documentation from ${_qdocconf_file}"
+ DEPENDS "${_qdocconf_file}"
+ SOURCES "${_qdocconf_file}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ VERBATIM
+ )
+
+ if (NOT Python3_Interpreter_FOUND)
+ message(WARNING "Cannot find python3 binary. Qbs documentation will not be built.")
+ endif()
+ _find_python_module(lxml)
+ _find_python_module(bs4)
+ if (NOT PY_LXML OR NOT PY_BS4)
+ message(FATAL_ERROR "Cannot import lxml and bs4 python modules. Qbs documentation will not be built.")
+ endif()
+
+ set(_fixed_html_target "fixed_html_docs_${_target}")
+ set(_fix_qml_imports_script ${Qbs_SOURCE_DIR}/doc/fix-qmlimports.py)
+ add_custom_target("${_fixed_html_target}"
+ ${Python3_EXECUTABLE} "${_fix_qml_imports_script}" ${_html_outputdir}
+ DEPENDS "${_html_target}"
+ SOURCES "${_fix_qml_imports_script}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ VERBATIM
+ )
+ add_dependencies(qbs_html_docs "${_fixed_html_target}")
+
+ set("${_retval}" "${_html_outputdir}" PARENT_SCOPE)
+endfunction()
+
+function(_qbs_setup_qhelpgenerator_targets _qdocconf_file _html_outputdir)
+ cmake_parse_arguments(_arg "" "QCH_DIR;INSTALL_DIR" "" ${ARGN})
+ if (_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "qdoc_build_qdocconf_file has unknown arguments: ${_arg_UNPARSED_ARGUMENTS}.")
+ endif()
+
+ if (NOT _arg_QCH_DIR)
+ set(_arg_QCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc")
+ endif()
+
+ if (NOT TARGET Qt${QT_VERSION_MAJOR}::qhelpgenerator)
+ message(WARNING "qhelpgenerator missing: No QCH documentation targets were generated. Add find_package(Qt5 COMPONENTS Help) to CMake to enable.")
+ return()
+ endif()
+
+ get_filename_component(_target "${_qdocconf_file}" NAME_WE)
+
+ set(_qch_outputdir "${_arg_QCH_DIR}")
+ file(MAKE_DIRECTORY "${_qch_outputdir}")
+
+ set(_qch_target "qch_docs_${_target}")
+ set(_html_target "html_docs_${_target}")
+ add_custom_target("${_qch_target}"
+ Qt${QT_VERSION_MAJOR}::qhelpgenerator "${_html_outputdir}/${_target}.qhp" -o "${_qch_outputdir}/${_target}.qch"
+ COMMENT "Build QCH documentation from ${_qdocconf_file}"
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
+ VERBATIM
+ )
+ add_dependencies("${_qch_target}" "${_html_target}")
+ add_dependencies(qbs_qch_docs "${_qch_target}")
+
+ install(FILES "${_qch_outputdir}/${_target}.qch" DESTINATION "${_arg_INSTALL_DIR}"
+ COMPONENT qbs_qch_docs)
+endfunction()
+
+# Helper functions:
+function(_qbs_qdoc_build_qdocconf_file _qdocconf_file)
+ _qbs_setup_doc_targets()
+
+ _qbs_doc_find_program(_qdoc NAMES qdoc qdoc-qt5)
+ if (_qdoc STREQUAL "_prg__qdoc-NOTFOUND")
+ message(WARNING "No qdoc binary found: No documentation targets were generated")
+ return()
+ endif()
+
+ cmake_parse_arguments(_arg "QCH" "HTML_DIR;QCH_DIR;INSTALL_DIR;POSTFIX"
+ "INDEXES;INCLUDE_DIRECTORIES;FRAMEWORK_PATHS;ENVIRONMENT_EXPORTS" ${ARGN})
+ if (_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "qdoc_build_qdocconf_file has unknown arguments: ${_arg_UNPARSED_ARGUMENTS}.")
+ endif()
+
+ if (NOT _arg_INSTALL_DIR)
+ message(FATAL_ERROR "No INSTALL_DIR set when calling qdoc_build_qdocconf_file")
+ endif()
+
+ _qbs_setup_qdoc_targets("${_qdocconf_file}" _html_outputdir
+ HTML_DIR "${_arg_HTML_DIR}" INSTALL_DIR "${_arg_INSTALL_DIR}"
+ INDEXES ${_arg_INDEXES} ENVIRONMENT_EXPORTS ${_arg_ENVIRONMENT_EXPORTS}
+ POSTFIX "${_arg_POSTFIX}"
+ INCLUDE_DIRECTORIES ${_arg_INCLUDE_DIRECTORIES}
+ FRAMEWORK_PATHS ${_arg_FRAMEWORK_PATHS}
+ )
+
+ if (_arg_QCH)
+ _qbs_setup_qhelpgenerator_targets("${_qdocconf_file}" "${_html_outputdir}"
+ QCH_DIR "${_arg_QCH_DIR}" INSTALL_DIR "${_arg_INSTALL_DIR}")
+ endif()
+
+endfunction()
+
+function(add_qbs_documentation qdocconf_file)
+ cmake_parse_arguments(_arg "" ""
+ "INCLUDE_DIRECTORIES;FRAMEWORK_PATHS" ${ARGN})
+ if (_arg_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "add_qbs_documentation has unknown arguments: ${_arg_UNPARSED_ARGUMENTS}.")
+ endif()
+
+ ### Skip docs setup if that is not needed!
+ if (NOT QBS_INSTALL_HTML_DOCS AND NOT QBS_INSTALL_QCH_DOCS)
+ return()
+ endif()
+
+ qt_query_qmake()
+ set(SRCDIR "${Qbs_SOURCE_DIR}/doc")
+
+ set(_qch_params)
+ if (QBS_INSTALL_QCH_DOCS)
+ set(_qch_params QCH QCH_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+ set(_qdoc_params HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")
+ list(APPEND _qdoc_params INSTALL_DIR "${QBS_DOC_INSTALL_DIR}")
+
+ # Set up environment for qdoc:
+ string(REPLACE "." "" QBS_VERSION_TAG "${QBS_VERSION}")
+
+ list(APPEND _qdoc_params ENVIRONMENT_EXPORTS
+ SRCDIR QBS_VERSION QBS_VERSION_TAG
+ QT_INSTALL_DOCS
+ )
+
+ _qbs_qdoc_build_qdocconf_file(${qdocconf_file} ${_qch_params} ${_qdoc_params}
+ INCLUDE_DIRECTORIES ${_arg_INCLUDE_DIRECTORIES}
+ FRAMEWORK_PATHS ${_arg_FRAMEWORK_PATHS}
+ )
+endfunction()
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 96cdab897..57dcbe33e 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,83 +1 @@
-if (QBS_INSTALL_HTML_DOCS OR QBS_INSTALL_QCH_DOCS)
-
- find_package(Python3 COMPONENTS Interpreter)
-
- function(find_python_module module)
- string(TOUPPER ${module} module_upper)
- if (NOT PY_${module_upper})
- if (ARGC GREATER 1 AND ARGV1 STREQUAL "REQUIRED")
- set(${module}_FIND_REQUIRED TRUE)
- endif()
- # A module's location is usually a directory, but for binary modules
- # it's a .so file.
- execute_process(COMMAND "${Python3_EXECUTABLE}" "-c"
- "import re, ${module}; print(re.compile('/__init__.py.*').sub('',${module}.__file__))"
- RESULT_VARIABLE _${module}_status
- OUTPUT_VARIABLE _${module}_location
- ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT _${module}_status)
- set(PY_${module_upper} ${_${module}_location} CACHE STRING
- "Location of Python module ${module}")
- endif()
- endif()
- find_package_handle_standard_args(PY_${module} DEFAULT_MSG PY_${module_upper})
- endfunction()
-
- if (Python3_Interpreter_FOUND)
- find_python_module(lxml)
- find_python_module(bs4)
- if (PY_LXML AND PY_BS4)
-
- get_target_property(_QBS_OUTPUT_DIR qbs RUNTIME_OUTPUT_DIRECTORY)
-
- if (QBS_INSTALL_HTML_DOCS)
- set(_INSTALL_HTML_DOCS true)
- else()
- set(_INSTALL_HTML_DOCS false)
- endif()
-
- if (QBS_INSTALL_QCH_DOCS)
- set(_INSTALL_QCH_DOCS true)
- else()
- set(_INSTALL_QCH_DOCS false)
- endif()
-
- get_target_property(_QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION)
- get_update_path_command(UPDATE_PATH_COMMAND)
- add_custom_target(
- BuildQbsDocumentation ALL
- COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs
- resolve
- --settings-dir ${PROJECT_BINARY_DIR}/settings
- -f ${PROJECT_SOURCE_DIR}/qbs.qbs
- -d ${PROJECT_BINARY_DIR}/
- config:doc-build
- qbs.installPrefix:undefined
- qbs.buildVariant:release
- project.withCode:false
- project.withDocumentation:true
- profile:none
- "products.qbs documentation.pythonPath:${Python3_EXECUTABLE}"
- modules.qbsbuildconfig.installHtml:${_INSTALL_HTML_DOCS}
- modules.qbsbuildconfig.installQch:${_INSTALL_QCH_DOCS}
- moduleProviders.Qt.qmakeFilePaths:${_QT_QMAKE_EXECUTABLE}
- COMMAND ${CMAKE_COMMAND} -E env "${UPDATE_PATH_COMMAND}" ${_QBS_OUTPUT_DIR}/qbs
- build
- --settings-dir ${PROJECT_BINARY_DIR}/settings
- -f ${PROJECT_SOURCE_DIR}/qbs.qbs
- -d ${PROJECT_BINARY_DIR}/
- config:doc-build
- -p "qbs documentation"
- DEPENDS qbs copy-runtime-files-qbs qbs_processlauncher
- )
- install(
- DIRECTORY ${PROJECT_BINARY_DIR}/doc-build/install-root/share/doc/qbs/html/
- DESTINATION "${QBS_DOC_INSTALL_DIR}"
- )
- else()
- message(WARNING "Cannot import lxml and bs4 python modules. Qbs documentation will not be built.")
- endif()
- else()
- message(WARNING "Cannot find python3 binary. Qbs documentation will not be built.")
- endif()
-endif()
+add_qbs_documentation("qbs.qdocconf")