qt5base-lts/cmake/QtQmakeHelpers.cmake
Laszlo Agocs 1dd8b5ceec rhi: Make it a QPA-style private but semi-public API
qrhi.h, qshader.h, qshaderdescription.h (and qshaderbaker.h from
shadertools; done separately) become "RHI APIs", following the concept
of QPA APIs.

Mirror completely what is done for QPA headers, but using the "rhi"
prefix for the headers. This involves updating syncqt to handle the
new category of headers. (a note on the regex: matching everything
starting with "qrhi" is not acceptable due to incorrectly matching
existing and future headers, hence specifying the four header names
explicitly)

There is going to be one difference to QPA: the documentation for
everything RHI is going to be public and part of the regular docs, not
hidden with \internal.

In addition to the header renaming and adding the comments and
documentation notes and warnings, there is one significant change
here: there is no longer a need to do API-specific includes, such as
qrhid3d11[_p].h, qrhivulkan[_p].h, etc. These are simply merged into a
single header that is then included from qrhi.h. This means that users
within Qt, and any future applications can just do #include
<rhi/qrhi.h> (or rhi/qshader.h if the QRhi stuff is not relevant), no
other headers are needed.

There are no changes to functionality in this patch. Only the
documentation is expanded, quite a lot, to eliminate all qdoc warnings
and make the generated API docs complete. An example, with a quite
extensive doc page is added as well.

Task-number: QTBUG-113331
Change-Id: I91c749826348f14320cb335b1c83e9d1ea2b1d8b
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2023-05-21 15:42:58 +02:00

251 lines
9.8 KiB
CMake

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Create a QMake list (values space-separated) containing paths.
# Entries that contain whitespace characters are quoted.
function(qt_to_qmake_path_list out_var)
set(quoted_paths "")
foreach(path ${ARGN})
if(path MATCHES "[ \t]")
list(APPEND quoted_paths "\"${path}\"")
else()
list(APPEND quoted_paths "${path}")
endif()
endforeach()
list(JOIN quoted_paths " " result)
set("${out_var}" "${result}" PARENT_SCOPE)
endfunction()
function(qt_generate_qconfig_cpp in_file out_file)
set(QT_CONFIG_STRS "")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_DOCDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_INCLUDEDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_LIBDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_LIBEXECDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_BINDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_PLUGINSDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_QMLDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_ARCHDATADIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_DATADIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_TRANSLATIONSDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_EXAMPLESDIR})qconfig\",\n")
string(APPEND QT_CONFIG_STRS " R\"qconfig(${INSTALL_TESTSDIR})qconfig\"")
# Settings path / sysconf dir.
set(QT_SYS_CONF_DIR "${INSTALL_SYSCONFDIR}")
# Compute and set relocation prefixes.
if(WIN32)
set(lib_location_absolute_path
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
else()
set(lib_location_absolute_path
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
endif()
file(RELATIVE_PATH from_lib_location_to_prefix
"${lib_location_absolute_path}" "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
set(QT_CONFIGURE_LIBLOCATION_TO_PREFIX_PATH "${from_lib_location_to_prefix}")
# Ensure Windows drive letter is prepended to the install prefix hardcoded
# into qconfig.cpp, otherwise qmake can't find Qt modules in a static Qt
# build if there's no qt.conf. Mostly relevant for CI.
# Given input like
# \work/qt/install
# or
# \work\qt\install
# Expected output is something like
# C:/work/qt/install
# so it includes a drive letter and forward slashes.
if(QT_FEATURE_relocatable)
# A relocatable Qt does not need a hardcoded prefix path.
# This makes reproducible builds a closer reality, because we don't embed a CI path
# into the binaries.
set(QT_CONFIGURE_PREFIX_PATH_STR "")
else()
set(QT_CONFIGURE_PREFIX_PATH_STR "${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}")
if(CMAKE_HOST_WIN32)
get_filename_component(
QT_CONFIGURE_PREFIX_PATH_STR
"${QT_CONFIGURE_PREFIX_PATH_STR}" REALPATH)
endif()
endif()
configure_file(${in_file} ${out_file} @ONLY)
endfunction()
# In the cross-compiling case, creates a wrapper around the host Qt's
# qmake and qtpaths executables. Also creates a qmake configuration file that sets
# up the host qmake's properties for cross-compiling with this Qt
# build.
function(qt_generate_qmake_and_qtpaths_wrapper_for_target)
if(NOT CMAKE_CROSSCOMPILING)
return()
endif()
# Call the configuration file something else but qt.conf to avoid
# being picked up by the qmake executable that's created if
# QT_FORCE_BUILD_TOOLS is enabled.
qt_path_join(qt_conf_path "${INSTALL_BINDIR}" "target_qt.conf")
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(ext_prefix "${QT_STAGING_PREFIX}")
set(host_prefix "${QT_HOST_PATH}")
file(RELATIVE_PATH host_prefix_relative_to_conf_file "${ext_prefix}/${INSTALL_BINDIR}"
"${host_prefix}")
file(RELATIVE_PATH ext_prefix_relative_to_conf_file "${ext_prefix}/${INSTALL_BINDIR}"
"${ext_prefix}")
file(RELATIVE_PATH ext_datadir_relative_to_host_prefix "${host_prefix}"
"${ext_prefix}/${INSTALL_MKSPECSDIR}/..")
set(content "")
# On Android CMAKE_SYSROOT is set, but from qmake's point of view it should not be set, because
# then qmake generates incorrect Qt module include flags (among other things). Do the same for
# darwin uikit cross-compilation.
set(sysroot "")
if(CMAKE_SYSROOT AND NOT ANDROID AND NOT UIKIT)
set(sysroot "${CMAKE_SYSROOT}")
endif()
# Detect if automatic sysrootification should happen. All of the following must be true:
# sysroot is set (CMAKE_SYSRROT)
# prefix is set (CMAKE_INSTALL_PREFIX)
# extprefix is explicitly NOT set (CMAKE_STAGING_PREFIX, not QT_STAGING_PREFIX because that
# always ends up having a value)
if(NOT CMAKE_STAGING_PREFIX AND sysroot)
set(sysrootify_prefix true)
else()
set(sysrootify_prefix false)
if(NOT ext_prefix STREQUAL prefix)
string(APPEND content "[DevicePaths]
Prefix=${prefix}
")
endif()
endif()
string(APPEND content
"[Paths]
Prefix=${ext_prefix_relative_to_conf_file}
Documentation=${INSTALL_DOCDIR}
Headers=${INSTALL_INCLUDEDIR}
Libraries=${INSTALL_LIBDIR}
LibraryExecutables=${INSTALL_LIBEXECDIR}
Binaries=${INSTALL_BINDIR}
Plugins=${INSTALL_PLUGINSDIR}
QmlImports=${INSTALL_QMLDIR}
ArchData=${INSTALL_ARCHDATADIR}
Data=${INSTALL_DATADIR}
Translations=${INSTALL_TRANSLATIONSDIR}
Examples=${INSTALL_EXAMPLESDIR}
Tests=${INSTALL_TESTSDIR}
Settings=${INSTALL_SYSCONFDIR}
HostPrefix=${host_prefix_relative_to_conf_file}
HostBinaries=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}
HostLibraries=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBDIR}
HostLibraryExecutables=${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_LIBEXECDIR}
HostData=${ext_datadir_relative_to_host_prefix}
Sysroot=${sysroot}
SysrootifyPrefix=${sysrootify_prefix}
TargetSpec=${QT_QMAKE_TARGET_MKSPEC}
HostSpec=${QT_QMAKE_HOST_MKSPEC}
")
file(GENERATE OUTPUT "${qt_conf_path}" CONTENT "${content}")
qt_install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${qt_conf_path}"
DESTINATION "${INSTALL_BINDIR}")
if(QT_GENERATE_WRAPPER_SCRIPTS_FOR_ALL_HOSTS)
set(hosts "unix" "non-unix")
elseif(CMAKE_HOST_UNIX)
set(hosts "unix")
else()
set(hosts "non-unix")
endif()
set(wrapper_prefix)
if(QT_FORCE_BUILD_TOOLS)
# Avoid collisions with the cross-compiled qmake/qtpaths binaries.
set(wrapper_prefix "host-")
endif()
set(host_qt_bindir "${host_prefix}/${QT${PROJECT_VERSION_MAJOR}_HOST_INFO_BINDIR}")
file(TO_NATIVE_PATH "${host_qt_bindir}" host_qt_bindir)
if(QT_CREATE_VERSIONED_HARD_LINK AND QT_WILL_INSTALL)
set(tool_version "${PROJECT_VERSION_MAJOR}")
endif()
foreach(host_type ${hosts})
foreach(tool_name qmake qtpaths)
set(wrapper_extension)
set(newline_style LF)
if(host_type STREQUAL "non-unix")
set(wrapper_extension ".bat")
set(newline_style CRLF)
endif()
set(wrapper_in_file
"${CMAKE_CURRENT_SOURCE_DIR}/bin/qmake-and-qtpaths-wrapper${wrapper_extension}.in")
set(wrapper "preliminary/${wrapper_prefix}${tool_name}${wrapper_extension}")
configure_file("${wrapper_in_file}" "${wrapper}" @ONLY NEWLINE_STYLE ${newline_style})
qt_copy_or_install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${wrapper}"
DESTINATION "${INSTALL_BINDIR}")
# Configuring a new wrapper file, this type setting the tool_version
if(QT_CREATE_VERSIONED_HARD_LINK AND QT_WILL_INSTALL)
set(versioned_wrapper "preliminary/${wrapper_prefix}${tool_name}${tool_version}${wrapper_extension}")
configure_file("${wrapper_in_file}" "${versioned_wrapper}" @ONLY NEWLINE_STYLE ${newline_style})
qt_copy_or_install(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/${versioned_wrapper}"
DESTINATION "${INSTALL_BINDIR}")
endif()
endforeach()
endforeach()
endfunction()
# Transforms a CMake Qt module name to a qmake Qt module name.
# Example: Qt6FooPrivate becomes foo_private
function(qt_get_qmake_module_name result module)
string(REGEX REPLACE "^Qt6" "" module "${module}")
string(REGEX REPLACE "Private$" "_private" module "${module}")
string(REGEX REPLACE "Qpa$" "_qpa_lib_private" module "${module}")
string(REGEX REPLACE "Rhi$" "_rhi_lib_private" module "${module}")
string(TOLOWER "${module}" module)
set(${result} ${module} PARENT_SCOPE)
endfunction()
function(qt_cmake_build_type_to_qmake_build_config out_var build_type)
if(build_type STREQUAL "Debug")
set(cfg debug)
else()
set(cfg release)
endif()
set(${out_var} ${cfg} PARENT_SCOPE)
endfunction()
function(qt_guess_qmake_build_config out_var)
if(QT_GENERATOR_IS_MULTI_CONFIG)
unset(cfg)
foreach(config_type ${CMAKE_CONFIGURATION_TYPES})
qt_cmake_build_type_to_qmake_build_config(tmp ${config_type})
list(APPEND cfg ${tmp})
endforeach()
if(cfg)
list(REMOVE_DUPLICATES cfg)
else()
set(cfg debug)
endif()
else()
qt_cmake_build_type_to_qmake_build_config(cfg ${CMAKE_BUILD_TYPE})
endif()
set(${out_var} ${cfg} PARENT_SCOPE)
endfunction()
macro(qt_add_qmake_lib_dependency lib dep)
string(REPLACE "-" "_" dep ${dep})
string(TOUPPER "${dep}" ucdep)
list(APPEND QT_QMAKE_LIB_DEPS_${lib} ${ucdep})
endmacro()