Merge remote-tracking branch 'origin/wip/cmake' into dev

This pulls the CMake port, which not only adds CMake files but also
modifies existing code. A brief summary of "seemingly unrelated" changes:

    * configure.json was re-formatted to not use multi-line strings. That
      is an extension of the Qt JSON parser but not JSON compliant, which
      is needed for the configure.json-to-cmake conversion script (python).
    * Some moc inclusions were added due to CMake's slightly different way
      of handling moc. With the changes the files build with qmake and cmake.
    * Since CMake just grep's for the Q_OBJECT macro to determine whether to
      call moc (instead of doing pre-processing like qmake), the existing use
      of "Q_OBJECT" in our documentation was changed to \Q_OBJECT, which cmake
      doesn't see and which is now a qdoc macro.
    * QTestLib's qFindTestData was extended to also search in the source
      directory known at build time.

What this change also brings is a new way of building modules in Coin by using
YAML configuration files that describe the steps of building and testing in Coin
specific terms. The platform configuration files in qt5 are instructed to use the
old Coin built-in way of testing ("UseLegacyInstructions" feature) but for any
configurations that do not have this, these yaml files in the coin/ sub-directory
are used and shared across repositories.

Change-Id: I1d832c3400e8d6945ad787024ba60e7440225c08
This commit is contained in:
Alexandru Croitor 2020-01-31 11:43:22 +01:00 committed by Simon Hausmann
commit 4e7af2061e
1825 changed files with 72464 additions and 1100 deletions

16
.gitignore vendored
View File

@ -36,6 +36,8 @@
qt*-config.h
qt*-config_p.h
qt*-config.pri
*.pyc
.mypy_cache
/include/
@ -56,11 +58,12 @@ qt*-config.pri
/src/angle/src/QtANGLE/libANGLE/
/src/angle/src/libGLESv2/libANGLE/
/examples/*/*/*
!/examples/*/*/*[.]*
!/examples/*/*/README
!/examples/*/doc/*
!/examples/*/doc/*/*
# FIXME: Ignore these again?
# /examples/*/*/*
# !/examples/*/*/*[.]*
# !/examples/*/*/README
# !/examples/*/doc/*
# !/examples/*/doc/*/*
/translations/*.qm
/translations/*_en.ts
@ -321,3 +324,6 @@ wrapper.bat
# Generated by qt.prf
*_plugin_import.cpp
# Typical cmake build directories
/build*

101
CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
cmake_minimum_required(VERSION 3.15.0)
# Run auto detection routines
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtAutoDetect.cmake)
project(QtBase
VERSION 6.0.0
DESCRIPTION "Qt Base Libraries"
HOMEPAGE_URL "https://qt.io/"
LANGUAGES CXX C ASM
)
if(NOT QT_BUILD_STANDALONE_TESTS)
## Add some paths to check for cmake modules:
list(PREPEND CMAKE_MODULE_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdparty/extra-cmake-modules/find-modules"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/3rdparty/kwin"
)
## Find the build internals package.
set(QT_BUILD_INTERNALS_SKIP_CMAKE_MODULE_PATH_ADDITION TRUE)
list(PREPEND CMAKE_PREFIX_PATH
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
)
find_package(QtBuildInternals CMAKE_FIND_ROOT_PATH_BOTH)
unset(QT_BUILD_INTERNALS_SKIP_CMAKE_MODULE_PATH_ADDITION)
else()
# When building standalone tests, an istalled BuildInternals package already exists.
find_package(Qt6 REQUIRED COMPONENTS BuildInternals CMAKE_FIND_ROOT_PATH_BOTH)
endif()
qt_build_repo_begin()
if(NOT QT_BUILD_STANDALONE_TESTS)
## Should this Qt be static or dynamically linked?
option(BUILD_SHARED_LIBS "Build Qt statically or dynamically" ON)
set(QT_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
## Should this Qt be built with Werror?
option(WARNINGS_ARE_ERRORS "Build Qt with warnings as errors" ${FEATURE_developer_build})
## Should Qt be built using PCH?
option(BUILD_WITH_PCH "Build Qt using precompiled headers?" ON)
## QtBase specific configure tests:
include(QtBaseConfigureTests)
## Build System tests:
include(QtBaseCMakeTesting)
## Targets for global features, etc.:
include(QtBaseGlobalTargets)
## Set language standards after QtBaseGlobalTargets, because that's when the relevant
## feature variables are available.
qt_set_language_standards()
#include CoreMacros() for qt6_generate_meta_types()
include(src/corelib/Qt6CoreMacros.cmake)
## Setup documentation
add_subdirectory(doc)
## Visit all the directories:
add_subdirectory(src)
endif()
if(BUILD_TESTING)
add_subdirectory(tests)
if(QT_NO_MAKE_TESTS)
set_property(DIRECTORY tests PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()
endif()
if(NOT QT_BUILD_STANDALONE_TESTS)
if(QT_WILL_BUILD_TOOLS)
add_subdirectory(qmake)
endif()
# As long as we use the mkspecs (for qplatformdefs.h), we need to always
# install it, especially when cross-compiling.
set(mkspecs_install_dir "${INSTALL_MKSPECSDIR}")
qt_path_join(mkspecs_install_dir ${QT_INSTALL_DIR} ${mkspecs_install_dir})
file(GLOB mkspecs_subdirs
LIST_DIRECTORIES TRUE
"${PROJECT_SOURCE_DIR}/mkspecs/*")
foreach(directory IN LISTS mkspecs_subdirs)
qt_copy_or_install(DIRECTORY "${directory}"
DESTINATION ${mkspecs_install_dir})
endforeach()
endif()
qt_build_repo_end()
if(NOT QT_BUILD_STANDALONE_TESTS AND BUILD_EXAMPLES)
add_subdirectory(examples)
if(QT_NO_MAKE_EXAMPLES)
set_property(DIRECTORY examples PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()
endif()

1
bin/qt-cmake.bat.in Normal file
View File

@ -0,0 +1 @@
"@CMAKE_COMMAND@" -DCMAKE_TOOLCHAIN_FILE="@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake" @__qt_cmake_extra@ %*

3
bin/qt-cmake.in Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
exec @CMAKE_COMMAND@ -DCMAKE_TOOLCHAIN_FILE=@__GlobalConfig_install_dir_absolute@/qt.toolchain.cmake @__qt_cmake_extra@ "$@"

View File

@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1 @@
include(${CMAKE_CURRENT_LIST_DIR}/../modules/ECMFindModuleHelpers.cmake)

View File

@ -0,0 +1,172 @@
#.rst:
# FindEGL
# -------
#
# Try to find EGL.
#
# This will define the following variables:
#
# ``EGL_FOUND``
# True if (the requested version of) EGL is available
# ``EGL_VERSION``
# The version of EGL; note that this is the API version defined in the
# headers, rather than the version of the implementation (eg: Mesa)
# ``EGL_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``EGL::EGL``
# target
# ``EGL_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``EGL_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``EGL_FOUND`` is TRUE, it will also define the following imported target:
#
# ``EGL::EGL``
# The EGL library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake)
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
ecm_find_package_version_check(EGL)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_EGL QUIET egl)
set(EGL_DEFINITIONS ${PKG_EGL_CFLAGS_OTHER})
find_path(EGL_INCLUDE_DIR
NAMES
EGL/egl.h
HINTS
${PKG_EGL_INCLUDE_DIRS}
)
find_library(EGL_LIBRARY
NAMES
EGL
HINTS
${PKG_EGL_LIBRARY_DIRS}
)
# NB: We do *not* use the version information from pkg-config, as that
# is the implementation version (eg: the Mesa version)
if(EGL_INCLUDE_DIR)
# egl.h has defines of the form EGL_VERSION_x_y for each supported
# version; so the header for EGL 1.1 will define EGL_VERSION_1_0 and
# EGL_VERSION_1_1. Finding the highest supported version involves
# finding all these defines and selecting the highest numbered.
file(READ "${EGL_INCLUDE_DIR}/EGL/egl.h" _EGL_header_contents)
string(REGEX MATCHALL
"[ \t]EGL_VERSION_[0-9_]+"
_EGL_version_lines
"${_EGL_header_contents}"
)
unset(_EGL_header_contents)
foreach(_EGL_version_line ${_EGL_version_lines})
string(REGEX REPLACE
"[ \t]EGL_VERSION_([0-9_]+)"
"\\1"
_version_candidate
"${_EGL_version_line}"
)
string(REPLACE "_" "." _version_candidate "${_version_candidate}")
if(NOT DEFINED EGL_VERSION OR EGL_VERSION VERSION_LESS _version_candidate)
set(EGL_VERSION "${_version_candidate}")
endif()
endforeach()
unset(_EGL_version_lines)
endif()
cmake_push_check_state(RESET)
list(APPEND CMAKE_REQUIRED_LIBRARIES "${EGL_LIBRARY}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${EGL_INCLUDE_DIR}")
check_cxx_source_compiles("
#include <EGL/egl.h>
int main(int argc, char *argv[]) {
EGLint x = 0; EGLDisplay dpy = 0; EGLContext ctx = 0;
eglDestroyContext(dpy, ctx);
}" HAVE_EGL)
cmake_pop_check_state()
set(required_vars EGL_INCLUDE_DIR HAVE_EGL)
if(NOT EMSCRIPTEN)
list(APPEND required_vars EGL_LIBRARY)
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(EGL
FOUND_VAR
EGL_FOUND
REQUIRED_VARS
${required_vars}
VERSION_VAR
EGL_VERSION
)
if(EGL_FOUND AND NOT TARGET EGL::EGL)
if (EMSCRIPTEN)
add_library(EGL::EGL INTERFACE IMPORTED)
# Nothing further to be done, system include paths have headers and linkage is implicit.
else()
add_library(EGL::EGL UNKNOWN IMPORTED)
set_target_properties(EGL::EGL PROPERTIES
IMPORTED_LOCATION "${EGL_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${EGL_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${EGL_INCLUDE_DIR}"
)
endif()
endif()
mark_as_advanced(EGL_LIBRARY EGL_INCLUDE_DIR HAVE_EGL)
# compatibility variables
set(EGL_LIBRARIES ${EGL_LIBRARY})
set(EGL_INCLUDE_DIRS ${EGL_INCLUDE_DIR})
set(EGL_VERSION_STRING ${EGL_VERSION})
include(FeatureSummary)
set_package_properties(EGL PROPERTIES
URL "https://www.khronos.org/egl/"
DESCRIPTION "A platform-agnostic mechanism for creating rendering surfaces for use with other graphics libraries, such as OpenGL|ES and OpenVG."
)

View File

@ -0,0 +1,101 @@
#.rst:
# FindGLIB2
# ---------
#
# Try to locate the GLib2 library.
# If found, this will define the following variables:
#
# ``GLIB2_FOUND``
# True if the GLib2 library is available
# ``GLIB2_INCLUDE_DIRS``
# The GLib2 include directories
# ``GLIB2_LIBRARIES``
# The GLib2 libraries for linking
# ``GLIB2_INCLUDE_DIR``
# Deprecated, use ``GLIB2_INCLUDE_DIRS``
# ``GLIB2_LIBRARY``
# Deprecated, use ``GLIB2_LIBRARIES``
#
# If ``GLIB2_FOUND`` is TRUE, it will also define the following
# imported target:
#
# ``GLIB2::GLIB2``
# The GLIB2 library
#
# Since 5.41.0.
#=============================================================================
# Copyright (c) 2008 Laurent Montel, <montel@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
find_package(PkgConfig)
pkg_check_modules(PC_GLIB2 QUIET glib-2.0)
find_path(GLIB2_INCLUDE_DIRS
NAMES glib.h
HINTS ${PC_GLIB2_INCLUDEDIR}
PATH_SUFFIXES glib-2.0)
find_library(GLIB2_LIBRARIES
NAMES glib-2.0
HINTS ${PC_GLIB2_LIBDIR}
)
# search the glibconfig.h include dir under the same root where the library is found
get_filename_component(glib2LibDir "${GLIB2_LIBRARIES}" PATH)
find_path(GLIB2_INTERNAL_INCLUDE_DIR glibconfig.h
PATH_SUFFIXES glib-2.0/include
HINTS ${PC_GLIB2_INCLUDEDIR} "${glib2LibDir}" ${CMAKE_SYSTEM_LIBRARY_PATH})
# not sure if this include dir is optional or required
# for now it is optional
if(GLIB2_INTERNAL_INCLUDE_DIR)
list(APPEND GLIB2_INCLUDE_DIRS "${GLIB2_INTERNAL_INCLUDE_DIR}")
endif()
# Deprecated synonyms
set(GLIB2_INCLUDE_DIR "${GLIB2_INCLUDE_DIRS}")
set(GLIB2_LIBRARY "${GLIB2_LIBRARIES}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLIB2 DEFAULT_MSG GLIB2_LIBRARIES GLIB2_INCLUDE_DIRS)
if(GLIB2_FOUND AND NOT TARGET GLIB2::GLIB2)
add_library(GLIB2::GLIB2 UNKNOWN IMPORTED)
set_target_properties(GLIB2::GLIB2 PROPERTIES
IMPORTED_LOCATION "${GLIB2_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${GLIB2_INCLUDE_DIRS}")
endif()
mark_as_advanced(GLIB2_INCLUDE_DIRS GLIB2_INCLUDE_DIR
GLIB2_LIBRARIES GLIB2_LIBRARY)
include(FeatureSummary)
set_package_properties(GLIB2 PROPERTIES
URL "https://wiki.gnome.org/Projects/GLib"
DESCRIPTION "Event loop and utility library")

View File

@ -0,0 +1,143 @@
#.rst:
# FindWayland
# -----------
#
# Try to find Wayland.
#
# This is a component-based find module, which makes use of the COMPONENTS
# and OPTIONAL_COMPONENTS arguments to find_module. The following components
# are available::
#
# Client Server Cursor Egl
#
# If no components are specified, this module will act as though all components
# were passed to OPTIONAL_COMPONENTS.
#
# This module will define the following variables, independently of the
# components searched for or found:
#
# ``Wayland_FOUND``
# TRUE if (the requested version of) Wayland is available
# ``Wayland_VERSION``
# Found Wayland version
# ``Wayland_TARGETS``
# A list of all targets imported by this module (note that there may be more
# than the components that were requested)
# ``Wayland_LIBRARIES``
# This can be passed to target_link_libraries() instead of the imported
# targets
# ``Wayland_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the targets are
# not used for linking
# ``Wayland_DEFINITIONS``
# This should be passed to target_compile_options() if the targets are not
# used for linking
#
# For each searched-for components, ``Wayland_<component>_FOUND`` will be set to
# TRUE if the corresponding Wayland library was found, and FALSE otherwise. If
# ``Wayland_<component>_FOUND`` is TRUE, the imported target
# ``Wayland::<component>`` will be defined. This module will also attempt to
# determine ``Wayland_*_VERSION`` variables for each imported target, although
# ``Wayland_VERSION`` should normally be sufficient.
#
# In general we recommend using the imported targets, as they are easier to use
# and provide more control. Bear in mind, however, that if any target is in the
# link interface of an exported library, it must be made available by the
# package config file.
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake)
ecm_find_package_version_check(Wayland)
set(Wayland_known_components
Client
Server
Cursor
Egl
)
foreach(_comp ${Wayland_known_components})
string(TOLOWER "${_comp}" _lc_comp)
set(Wayland_${_comp}_component_deps)
set(Wayland_${_comp}_pkg_config "wayland-${_lc_comp}")
set(Wayland_${_comp}_lib "wayland-${_lc_comp}")
set(Wayland_${_comp}_header "wayland-${_lc_comp}.h")
endforeach()
set(Wayland_Egl_component_deps Client)
ecm_find_package_parse_components(Wayland
RESULT_VAR Wayland_components
KNOWN_COMPONENTS ${Wayland_known_components}
)
ecm_find_package_handle_library_components(Wayland
COMPONENTS ${Wayland_components}
)
# If pkg-config didn't provide us with version information,
# try to extract it from wayland-version.h
# (Note that the version from wayland-egl.pc will probably be
# the Mesa version, rather than the Wayland version, but that
# version will be ignored as we always find wayland-client.pc
# first).
if(NOT Wayland_VERSION)
find_file(Wayland_VERSION_HEADER
NAMES wayland-version.h
HINTS ${Wayland_INCLUDE_DIRS}
)
mark_as_advanced(Wayland_VERSION_HEADER)
if(Wayland_VERSION_HEADER)
file(READ ${Wayland_VERSION_HEADER} _wayland_version_header_contents)
string(REGEX REPLACE
"^.*[ \t]+WAYLAND_VERSION[ \t]+\"([0-9.]*)\".*$"
"\\1"
Wayland_VERSION
"${_wayland_version_header_contents}"
)
unset(_wayland_version_header_contents)
endif()
endif()
find_package_handle_standard_args(Wayland
FOUND_VAR
Wayland_FOUND
REQUIRED_VARS
Wayland_LIBRARIES
VERSION_VAR
Wayland_VERSION
HANDLE_COMPONENTS
)
include(FeatureSummary)
set_package_properties(Wayland PROPERTIES
URL "http://wayland.freedesktop.org"
DESCRIPTION "C library implementation of the Wayland protocol: a protocol for a compositor to talk to its clients"
)

View File

@ -0,0 +1,167 @@
#.rst:
# FindWaylandScanner
# ------------------
#
# Try to find wayland-scanner.
#
# If the wayland-scanner executable is not in your PATH, you can provide
# an alternative name or full path location with the ``WaylandScanner_EXECUTABLE``
# variable.
#
# This will define the following variables:
#
# ``WaylandScanner_FOUND``
# True if wayland-scanner is available.
#
# ``WaylandScanner_EXECUTABLE``
# The wayland-scanner executable.
#
# If ``WaylandScanner_FOUND`` is TRUE, it will also define the following imported
# target:
#
# ``Wayland::Scanner``
# The wayland-scanner executable.
#
# This module provides the following functions to generate C protocol
# implementations:
#
# - ``ecm_add_wayland_client_protocol``
# - ``ecm_add_wayland_server_protocol``
#
# ::
#
# ecm_add_wayland_client_protocol(<source_files_var>
# PROTOCOL <xmlfile>
# BASENAME <basename>)
#
# Generate Wayland client protocol files from ``<xmlfile>`` XML
# definition for the ``<basename>`` interface and append those files
# to ``<source_files_var>``.
#
# ::
#
# ecm_add_wayland_server_protocol(<source_files_var>
# PROTOCOL <xmlfile>
# BASENAME <basename>)
#
# Generate Wayland server protocol files from ``<xmlfile>`` XML
# definition for the ``<basename>`` interface and append those files
# to ``<source_files_var>``.
#
# Since 1.4.0.
#=============================================================================
# Copyright 2012-2014 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake)
ecm_find_package_version_check(WaylandScanner)
# Find wayland-scanner
find_program(WaylandScanner_EXECUTABLE NAMES wayland-scanner)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WaylandScanner
FOUND_VAR
WaylandScanner_FOUND
REQUIRED_VARS
WaylandScanner_EXECUTABLE
)
mark_as_advanced(WaylandScanner_EXECUTABLE)
if(NOT TARGET Wayland::Scanner AND WaylandScanner_FOUND)
add_executable(Wayland::Scanner IMPORTED)
set_target_properties(Wayland::Scanner PROPERTIES
IMPORTED_LOCATION "${WaylandScanner_EXECUTABLE}"
)
endif()
include(FeatureSummary)
set_package_properties(WaylandScanner PROPERTIES
URL "https://wayland.freedesktop.org/"
DESCRIPTION "Executable that converts XML protocol files to C code"
)
include(CMakeParseArguments)
function(ecm_add_wayland_client_protocol out_var)
# Parse arguments
set(oneValueArgs PROTOCOL BASENAME)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN})
if(ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to ecm_add_wayland_client_protocol(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
endif()
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
set(_client_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-client-protocol.h")
set(_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-protocol.c")
set_source_files_properties(${_client_header} GENERATED)
set_source_files_properties(${_code} GENERATED)
set_property(SOURCE ${_client_header} PROPERTY SKIP_AUTOMOC ON)
add_custom_command(OUTPUT "${_client_header}"
COMMAND ${WaylandScanner_EXECUTABLE} client-header ${_infile} ${_client_header}
DEPENDS ${_infile} VERBATIM)
add_custom_command(OUTPUT "${_code}"
COMMAND ${WaylandScanner_EXECUTABLE} code ${_infile} ${_code}
DEPENDS ${_infile} ${_client_header} VERBATIM)
list(APPEND ${out_var} "${_client_header}" "${_code}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
endfunction()
function(ecm_add_wayland_server_protocol out_var)
# Parse arguments
set(oneValueArgs PROTOCOL BASENAME)
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "" ${ARGN})
if(ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unknown keywords given to ecm_add_wayland_server_protocol(): \"${ARGS_UNPARSED_ARGUMENTS}\"")
endif()
ecm_add_wayland_client_protocol(${out_var}
PROTOCOL ${ARGS_PROTOCOL}
BASENAME ${ARGS_BASENAME})
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-server-protocol.h")
set_property(SOURCE ${_server_header} PROPERTY SKIP_AUTOMOC ON)
set_source_files_properties(${_server_header} GENERATED)
add_custom_command(OUTPUT "${_server_header}"
COMMAND ${WaylandScanner_EXECUTABLE} server-header ${_infile} ${_server_header}
DEPENDS ${_infile} VERBATIM)
list(APPEND ${out_var} "${_server_header}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,118 @@
#.rst:
# FindX11_XCB
# -----------
#
# Try to find the X11 XCB compatibility library.
#
# This will define the following variables:
#
# ``X11_XCB_FOUND``
# True if (the requested version of) libX11-xcb is available
# ``X11_XCB_VERSION``
# The version of libX11-xcb (this is not guaranteed to be set even when
# X11_XCB_FOUND is true)
# ``X11_XCB_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``EGL::EGL``
# target
# ``X11_XCB_INCLUDE_DIR``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``X11_XCB_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``X11_XCB_FOUND`` is TRUE, it will also define the following imported
# target:
#
# ``X11::XCB``
# The X11 XCB compatibility library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2011 Fredrik Höglund <fredrik@kde.org>
# Copyright 2008 Helio Chissini de Castro <helio@kde.org>
# Copyright 2007 Matthias Kretz <kretz@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake)
ecm_find_package_version_check(X11_XCB)
# use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_X11_XCB QUIET x11-xcb)
set(X11_XCB_DEFINITIONS ${PKG_X11_XCB_CFLAGS_OTHER})
set(X11_XCB_VERSION ${PKG_X11_XCB_VERSION})
find_path(X11_XCB_INCLUDE_DIR
NAMES X11/Xlib-xcb.h
HINTS ${PKG_X11_XCB_INCLUDE_DIRS}
)
find_library(X11_XCB_LIBRARY
NAMES X11-xcb
HINTS ${PKG_X11_XCB_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(X11_XCB
FOUND_VAR
X11_XCB_FOUND
REQUIRED_VARS
X11_XCB_LIBRARY
X11_XCB_INCLUDE_DIR
VERSION_VAR
X11_XCB_VERSION
)
if(X11_XCB_FOUND AND NOT TARGET X11::XCB)
add_library(X11::XCB UNKNOWN IMPORTED)
set_target_properties(X11::XCB PROPERTIES
IMPORTED_LOCATION "${X11_XCB_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${X11_XCB_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${X11_XCB_INCLUDE_DIR}"
)
endif()
mark_as_advanced(X11_XCB_INCLUDE_DIR X11_XCB_LIBRARY)
# compatibility variables
set(X11_XCB_LIBRARIES ${X11_XCB_LIBRARY})
set(X11_XCB_INCLUDE_DIRS ${X11_XCB_INCLUDE_DIR})
set(X11_XCB_VERSION_STRING ${X11_XCB_VERSION})
include(FeatureSummary)
set_package_properties(X11_XCB PROPERTIES
URL "http://xorg.freedesktop.org/"
DESCRIPTION "A compatibility library for code that translates Xlib API calls into XCB calls"
)

View File

@ -0,0 +1,201 @@
#.rst:
# FindXCB
# -------
#
# Try to find XCB.
#
# This is a component-based find module, which makes use of the COMPONENTS and
# OPTIONAL_COMPONENTS arguments to find_module. The following components are
# available::
#
# XCB
# ATOM AUX COMPOSITE CURSOR DAMAGE
# DPMS DRI2 DRI3 EVENT EWMH
# GLX ICCCM IMAGE KEYSYMS PRESENT
# RANDR RECORD RENDER RENDERUTIL RES
# SCREENSAVER SHAPE SHM SYNC UTIL
# XEVIE XF86DRI XFIXES XINERAMA XINPUT
# XKB XPRINT XTEST XV XVMC
#
# If no components are specified, this module will act as though all components
# except XINPUT (which is considered unstable) were passed to
# OPTIONAL_COMPONENTS.
#
# This module will define the following variables, independently of the
# components searched for or found:
#
# ``XCB_FOUND``
# True if (the requestion version of) xcb is available
# ``XCB_VERSION``
# Found xcb version
# ``XCB_TARGETS``
# A list of all targets imported by this module (note that there may be more
# than the components that were requested)
# ``XCB_LIBRARIES``
# This can be passed to target_link_libraries() instead of the imported
# targets
# ``XCB_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the targets are
# not used for linking
# ``XCB_DEFINITIONS``
# This should be passed to target_compile_options() if the targets are not
# used for linking
#
# For each searched-for components, ``XCB_<component>_FOUND`` will be set to
# true if the corresponding xcb library was found, and false otherwise. If
# ``XCB_<component>_FOUND`` is true, the imported target ``XCB::<component>``
# will be defined. This module will also attempt to determine
# ``XCB_*_VERSION`` variables for each imported target, although
# ``XCB_VERSION`` should normally be sufficient.
#
# In general we recommend using the imported targets, as they are easier to use
# and provide more control. Bear in mind, however, that if any target is in the
# link interface of an exported library, it must be made available by the
# package config file.
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2011 Fredrik Höglund <fredrik@kde.org>
# Copyright 2013 Martin Gräßlin <mgraesslin@kde.org>
# Copyright 2014-2015 Alex Merry <alex.merry@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
include(${CMAKE_CURRENT_LIST_DIR}/ECMFindModuleHelpersStub.cmake)
ecm_find_package_version_check(XCB)
# Note that this list needs to be ordered such that any component
# appears after its dependencies
set(XCB_known_components
XCB
RENDER
SHAPE
XFIXES
SHM
ATOM
AUX
COMPOSITE
CURSOR
DAMAGE
DPMS
DRI2
DRI3
EVENT
EWMH
GLX
ICCCM
IMAGE
KEYSYMS
PRESENT
RANDR
RECORD
RENDERUTIL
RES
SCREENSAVER
SYNC
UTIL
XEVIE
XF86DRI
XINERAMA
XINPUT
XKB
XPRINT
XTEST
XV
XVMC
)
# XINPUT is unstable; do not include it by default
set(XCB_default_components ${XCB_known_components})
list(REMOVE_ITEM XCB_default_components "XINPUT")
# default component info: xcb components have fairly predictable
# header files, library names and pkg-config names
foreach(_comp ${XCB_known_components})
string(TOLOWER "${_comp}" _lc_comp)
set(XCB_${_comp}_component_deps XCB)
set(XCB_${_comp}_pkg_config "xcb-${_lc_comp}")
set(XCB_${_comp}_lib "xcb-${_lc_comp}")
set(XCB_${_comp}_header "xcb/${_lc_comp}.h")
endforeach()
# exceptions
set(XCB_XCB_component_deps)
set(XCB_COMPOSITE_component_deps XCB XFIXES)
set(XCB_DAMAGE_component_deps XCB XFIXES)
set(XCB_IMAGE_component_deps XCB SHM)
set(XCB_RENDERUTIL_component_deps XCB RENDER)
set(XCB_XFIXES_component_deps XCB RENDER SHAPE)
set(XCB_XVMC_component_deps XCB XV)
set(XCB_XV_component_deps XCB SHM)
set(XCB_XCB_pkg_config "xcb")
set(XCB_XCB_lib "xcb")
set(XCB_ATOM_header "xcb/xcb_atom.h")
set(XCB_ATOM_lib "xcb-util")
set(XCB_AUX_header "xcb/xcb_aux.h")
set(XCB_AUX_lib "xcb-util")
set(XCB_CURSOR_header "xcb/xcb_cursor.h")
set(XCB_EVENT_header "xcb/xcb_event.h")
set(XCB_EVENT_lib "xcb-util")
set(XCB_EWMH_header "xcb/xcb_ewmh.h")
set(XCB_ICCCM_header "xcb/xcb_icccm.h")
set(XCB_IMAGE_header "xcb/xcb_image.h")
set(XCB_KEYSYMS_header "xcb/xcb_keysyms.h")
set(XCB_PIXEL_header "xcb/xcb_pixel.h")
set(XCB_RENDERUTIL_header "xcb/xcb_renderutil.h")
set(XCB_RENDERUTIL_lib "xcb-render-util")
set(XCB_UTIL_header "xcb/xcb_util.h")
ecm_find_package_parse_components(XCB
RESULT_VAR XCB_components
KNOWN_COMPONENTS ${XCB_known_components}
DEFAULT_COMPONENTS ${XCB_default_components}
)
list(FIND XCB_components "XINPUT" _XCB_XINPUT_index)
if (NOT _XCB_XINPUT_index EQUAL -1)
message(AUTHOR_WARNING "XINPUT from XCB was requested: this is EXPERIMENTAL and is likely to unavailable on many systems!")
endif()
ecm_find_package_handle_library_components(XCB
COMPONENTS ${XCB_components}
)
find_package_handle_standard_args(XCB
FOUND_VAR
XCB_FOUND
REQUIRED_VARS
XCB_LIBRARIES
VERSION_VAR
XCB_VERSION
HANDLE_COMPONENTS
)
include(FeatureSummary)
set_package_properties(XCB PROPERTIES
URL "http://xcb.freedesktop.org"
DESCRIPTION "X protocol C-language Binding"
)

View File

@ -0,0 +1,173 @@
#.rst:
# ECMEnableSanitizers
# -------------------
#
# Enable compiler sanitizer flags.
#
# The following sanitizers are supported:
#
# - Address Sanitizer
# - Memory Sanitizer
# - Thread Sanitizer
# - Leak Sanitizer
# - Undefined Behaviour Sanitizer
#
# All of them are implemented in Clang, depending on your version, and
# there is an work in progress in GCC, where some of them are currently
# implemented.
#
# This module will check your current compiler version to see if it
# supports the sanitizers that you want to enable
#
# Usage
# =====
#
# Simply add::
#
# include(ECMEnableSanitizers)
#
# to your ``CMakeLists.txt``. Note that this module is included in
# KDECompilerSettings, so projects using that module do not need to also
# include this one.
#
# The sanitizers are not enabled by default. Instead, you must set
# ``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the
# command line) to a semicolon-separated list of sanitizers you wish to enable.
# The options are:
#
# - address
# - memory
# - thread
# - leak
# - undefined
#
# The sanitizers "address", "memory" and "thread" are mutually exclusive. You
# cannot enable two of them in the same build.
#
# "leak" requires the "address" sanitizer.
#
# .. note::
#
# To reduce the overhead induced by the instrumentation of the sanitizers, it
# is advised to enable compiler optimizations (``-O1`` or higher).
#
# Example
# =======
#
# This is an example of usage::
#
# mkdir build
# cd build
# cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' ..
#
# .. note::
#
# Most of the sanitizers will require Clang. To enable it, use::
#
# -DCMAKE_CXX_COMPILER=clang++
#
# Since 1.3.0.
#=============================================================================
# Copyright 2014 Mathieu Tarral <mathieu.tarral@gmail.com>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# MACRO check_compiler_version
#-----------------------------
macro (check_compiler_version gcc_required_version clang_required_version)
if (
(
CMAKE_CXX_COMPILER_ID MATCHES "GNU"
AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${gcc_required_version}
)
OR
(
CMAKE_CXX_COMPILER_ID MATCHES "Clang"
AND
CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${clang_required_version}
)
)
# error !
message(FATAL_ERROR "You ask to enable the sanitizer ${CUR_SANITIZER},
but your compiler ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}
does not support it !
You should use at least GCC ${gcc_required_version} or Clang ${clang_required_version}
(99.99 means not implemented yet)")
endif ()
endmacro ()
# MACRO check_compiler_support
#------------------------------
macro (enable_sanitizer_flags sanitize_option)
if (${sanitize_option} MATCHES "address")
check_compiler_version("4.8" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(XSAN_LINKER_FLAGS "asan")
elseif (${sanitize_option} MATCHES "thread")
check_compiler_version("4.8" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
set(XSAN_LINKER_FLAGS "tsan")
elseif (${sanitize_option} MATCHES "memory")
check_compiler_version("99.99" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
elseif (${sanitize_option} MATCHES "leak")
check_compiler_version("4.9" "3.4")
set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
set(XSAN_LINKER_FLAGS "lsan")
elseif (${sanitize_option} MATCHES "undefined")
check_compiler_version("4.9" "3.1")
set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls")
else ()
message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
endif ()
endmacro ()
if (ECM_ENABLE_SANITIZERS)
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# for each element of the ECM_ENABLE_SANITIZERS list
foreach ( CUR_SANITIZER ${ECM_ENABLE_SANITIZERS} )
# lowercase filter
string(TOLOWER ${CUR_SANITIZER} CUR_SANITIZER)
# check option and enable appropriate flags
enable_sanitizer_flags ( ${CUR_SANITIZER} )
# TODO: GCC will not link pthread library if enabled ASan
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${XSAN_COMPILE_FLAGS}" )
endif()
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}" )
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
link_libraries(${XSAN_LINKER_FLAGS})
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
string(REPLACE "-Wl,--no-undefined" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")
endif ()
endforeach()
else()
message(STATUS "Tried to enable sanitizers (-DECM_ENABLE_SANITIZERS=${ECM_ENABLE_SANITIZERS}), \
but compiler (${CMAKE_CXX_COMPILER_ID}) does not have sanitizer support")
endif()
endif()

View File

@ -0,0 +1,297 @@
#.rst:
# ECMFindModuleHelpers
# --------------------
#
# Helper macros for find modules: ecm_find_package_version_check(),
# ecm_find_package_parse_components() and
# ecm_find_package_handle_library_components().
#
# ::
#
# ecm_find_package_version_check(<name>)
#
# Prints warnings if the CMake version or the project's required CMake version
# is older than that required by extra-cmake-modules.
#
# ::
#
# ecm_find_package_parse_components(<name>
# RESULT_VAR <variable>
# KNOWN_COMPONENTS <component1> [<component2> [...]]
# [SKIP_DEPENDENCY_HANDLING])
#
# This macro will populate <variable> with a list of components found in
# <name>_FIND_COMPONENTS, after checking that all those components are in the
# list of KNOWN_COMPONENTS; if there are any unknown components, it will print
# an error or warning (depending on the value of <name>_FIND_REQUIRED) and call
# return().
#
# The order of components in <variable> is guaranteed to match the order they
# are listed in the KNOWN_COMPONENTS argument.
#
# If SKIP_DEPENDENCY_HANDLING is not set, for each component the variable
# <name>_<component>_component_deps will be checked for dependent components.
# If <component> is listed in <name>_FIND_COMPONENTS, then all its (transitive)
# dependencies will also be added to <variable>.
#
# ::
#
# ecm_find_package_handle_library_components(<name>
# COMPONENTS <component> [<component> [...]]
# [SKIP_DEPENDENCY_HANDLING])
# [SKIP_PKG_CONFIG])
#
# Creates an imported library target for each component. The operation of this
# macro depends on the presence of a number of CMake variables.
#
# The <name>_<component>_lib variable should contain the name of this library,
# and <name>_<component>_header variable should contain the name of a header
# file associated with it (whatever relative path is normally passed to
# '#include'). <name>_<component>_header_subdir variable can be used to specify
# which subdirectory of the include path the headers will be found in.
# ecm_find_package_components() will then search for the library
# and include directory (creating appropriate cache variables) and create an
# imported library target named <name>::<component>.
#
# Additional variables can be used to provide additional information:
#
# If SKIP_PKG_CONFIG, the <name>_<component>_pkg_config variable is set, and
# pkg-config is found, the pkg-config module given by
# <name>_<component>_pkg_config will be searched for and used to help locate the
# library and header file. It will also be used to set
# <name>_<component>_VERSION.
#
# Note that if version information is found via pkg-config,
# <name>_<component>_FIND_VERSION can be set to require a particular version
# for each component.
#
# If SKIP_DEPENDENCY_HANDLING is not set, the INTERFACE_LINK_LIBRARIES property
# of the imported target for <component> will be set to contain the imported
# targets for the components listed in <name>_<component>_component_deps.
# <component>_FOUND will also be set to false if any of the compoments in
# <name>_<component>_component_deps are not found. This requires the components
# in <name>_<component>_component_deps to be listed before <component> in the
# COMPONENTS argument.
#
# The following variables will be set:
#
# ``<name>_TARGETS``
# the imported targets
# ``<name>_LIBRARIES``
# the found libraries
# ``<name>_INCLUDE_DIRS``
# the combined required include directories for the components
# ``<name>_DEFINITIONS``
# the "other" CFLAGS provided by pkg-config, if any
# ``<name>_VERSION``
# the value of ``<name>_<component>_VERSION`` for the first component that
# has this variable set (note that components are searched for in the order
# they are passed to the macro), although if it is already set, it will not
# be altered
#
# Note that these variables are never cleared, so if
# ecm_find_package_handle_library_components() is called multiple times with
# different components (typically because of multiple find_package() calls) then
# ``<name>_TARGETS``, for example, will contain all the targets found in any
# call (although no duplicates).
#
# Since pre-1.0.0.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
include(CMakeParseArguments)
macro(ecm_find_package_version_check module_name)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by Find${module_name}.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Find${module_name}.cmake")
endif()
endmacro()
macro(ecm_find_package_parse_components module_name)
set(ecm_fppc_options SKIP_DEPENDENCY_HANDLING)
set(ecm_fppc_oneValueArgs RESULT_VAR)
set(ecm_fppc_multiValueArgs KNOWN_COMPONENTS DEFAULT_COMPONENTS)
cmake_parse_arguments(ECM_FPPC "${ecm_fppc_options}" "${ecm_fppc_oneValueArgs}" "${ecm_fppc_multiValueArgs}" ${ARGN})
if(ECM_FPPC_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unexpected arguments to ecm_find_package_parse_components: ${ECM_FPPC_UNPARSED_ARGUMENTS}")
endif()
if(NOT ECM_FPPC_RESULT_VAR)
message(FATAL_ERROR "Missing RESULT_VAR argument to ecm_find_package_parse_components")
endif()
if(NOT ECM_FPPC_KNOWN_COMPONENTS)
message(FATAL_ERROR "Missing KNOWN_COMPONENTS argument to ecm_find_package_parse_components")
endif()
if(NOT ECM_FPPC_DEFAULT_COMPONENTS)
set(ECM_FPPC_DEFAULT_COMPONENTS ${ECM_FPPC_KNOWN_COMPONENTS})
endif()
if(${module_name}_FIND_COMPONENTS)
set(ecm_fppc_requestedComps ${${module_name}_FIND_COMPONENTS})
if(NOT ECM_FPPC_SKIP_DEPENDENCY_HANDLING)
# Make sure deps are included
foreach(ecm_fppc_comp ${ecm_fppc_requestedComps})
foreach(ecm_fppc_dep_comp ${${module_name}_${ecm_fppc_comp}_component_deps})
list(FIND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}" ecm_fppc_index)
if("${ecm_fppc_index}" STREQUAL "-1")
if(NOT ${module_name}_FIND_QUIETLY)
message(STATUS "${module_name}: ${ecm_fppc_comp} requires ${${module_name}_${ecm_fppc_comp}_component_deps}")
endif()
list(APPEND ecm_fppc_requestedComps "${ecm_fppc_dep_comp}")
endif()
endforeach()
endforeach()
else()
message(STATUS "Skipping dependency handling for ${module_name}")
endif()
list(REMOVE_DUPLICATES ecm_fppc_requestedComps)
# This makes sure components are listed in the same order as
# KNOWN_COMPONENTS (potentially important for inter-dependencies)
set(${ECM_FPPC_RESULT_VAR})
foreach(ecm_fppc_comp ${ECM_FPPC_KNOWN_COMPONENTS})
list(FIND ecm_fppc_requestedComps "${ecm_fppc_comp}" ecm_fppc_index)
if(NOT "${ecm_fppc_index}" STREQUAL "-1")
list(APPEND ${ECM_FPPC_RESULT_VAR} "${ecm_fppc_comp}")
list(REMOVE_AT ecm_fppc_requestedComps ${ecm_fppc_index})
endif()
endforeach()
# if there are any left, they are unknown components
if(ecm_fppc_requestedComps)
set(ecm_fppc_msgType STATUS)
if(${module_name}_FIND_REQUIRED)
set(ecm_fppc_msgType FATAL_ERROR)
endif()
if(NOT ${module_name}_FIND_QUIETLY)
message(${ecm_fppc_msgType} "${module_name}: requested unknown components ${ecm_fppc_requestedComps}")
endif()
return()
endif()
else()
set(${ECM_FPPC_RESULT_VAR} ${ECM_FPPC_DEFAULT_COMPONENTS})
endif()
endmacro()
macro(ecm_find_package_handle_library_components module_name)
set(ecm_fpwc_options SKIP_PKG_CONFIG SKIP_DEPENDENCY_HANDLING)
set(ecm_fpwc_oneValueArgs)
set(ecm_fpwc_multiValueArgs COMPONENTS)
cmake_parse_arguments(ECM_FPWC "${ecm_fpwc_options}" "${ecm_fpwc_oneValueArgs}" "${ecm_fpwc_multiValueArgs}" ${ARGN})
if(ECM_FPWC_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unexpected arguments to ecm_find_package_handle_components: ${ECM_FPWC_UNPARSED_ARGUMENTS}")
endif()
if(NOT ECM_FPWC_COMPONENTS)
message(FATAL_ERROR "Missing COMPONENTS argument to ecm_find_package_handle_components")
endif()
include(FindPackageHandleStandardArgs)
find_package(PkgConfig)
foreach(ecm_fpwc_comp ${ECM_FPWC_COMPONENTS})
set(ecm_fpwc_dep_vars)
set(ecm_fpwc_dep_targets)
if(NOT SKIP_DEPENDENCY_HANDLING)
foreach(ecm_fpwc_dep ${${module_name}_${ecm_fpwc_comp}_component_deps})
list(APPEND ecm_fpwc_dep_vars "${module_name}_${ecm_fpwc_dep}_FOUND")
list(APPEND ecm_fpwc_dep_targets "${module_name}::${ecm_fpwc_dep}")
endforeach()
endif()
if(NOT ECM_FPWC_SKIP_PKG_CONFIG AND ${module_name}_${ecm_fpwc_comp}_pkg_config)
pkg_check_modules(PKG_${module_name}_${ecm_fpwc_comp} QUIET
${${module_name}_${ecm_fpwc_comp}_pkg_config})
endif()
find_path(${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
NAMES ${${module_name}_${ecm_fpwc_comp}_header}
HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_INCLUDE_DIRS}
PATH_SUFFIXES ${${module_name}_${ecm_fpwc_comp}_header_subdir}
)
find_library(${module_name}_${ecm_fpwc_comp}_LIBRARY
NAMES ${${module_name}_${ecm_fpwc_comp}_lib}
HINTS ${PKG_${module_name}_${ecm_fpwc_comp}_LIBRARY_DIRS}
)
set(${module_name}_${ecm_fpwc_comp}_VERSION "${PKG_${module_name}_${ecm_fpwc_comp}_VERSION}")
if(NOT ${module_name}_VERSION)
set(${module_name}_VERSION ${${module_name}_${ecm_fpwc_comp}_VERSION})
endif()
find_package_handle_standard_args(${module_name}_${ecm_fpwc_comp}
FOUND_VAR
${module_name}_${ecm_fpwc_comp}_FOUND
REQUIRED_VARS
${module_name}_${ecm_fpwc_comp}_LIBRARY
${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
${ecm_fpwc_dep_vars}
VERSION_VAR
${module_name}_${ecm_fpwc_comp}_VERSION
)
mark_as_advanced(
${module_name}_${ecm_fpwc_comp}_LIBRARY
${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR
)
if(${module_name}_${ecm_fpwc_comp}_FOUND)
list(APPEND ${module_name}_LIBRARIES
"${${module_name}_${ecm_fpwc_comp}_LIBRARY}")
list(APPEND ${module_name}_INCLUDE_DIRS
"${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}")
set(${module_name}_DEFINITIONS
${${module_name}_DEFINITIONS}
${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS})
if(NOT TARGET ${module_name}::${ecm_fpwc_comp})
add_library(${module_name}::${ecm_fpwc_comp} UNKNOWN IMPORTED)
set_target_properties(${module_name}::${ecm_fpwc_comp} PROPERTIES
IMPORTED_LOCATION "${${module_name}_${ecm_fpwc_comp}_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PKG_${module_name}_${ecm_fpwc_comp}_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${${module_name}_${ecm_fpwc_comp}_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${ecm_fpwc_dep_targets}"
)
endif()
list(APPEND ${module_name}_TARGETS
"${module_name}::${ecm_fpwc_comp}")
endif()
endforeach()
if(${module_name}_LIBRARIES)
list(REMOVE_DUPLICATES ${module_name}_LIBRARIES)
endif()
if(${module_name}_INCLUDE_DIRS)
list(REMOVE_DUPLICATES ${module_name}_INCLUDE_DIRS)
endif()
if(${module_name}_DEFINITIONS)
list(REMOVE_DUPLICATES ${module_name}_DEFINITIONS)
endif()
if(${module_name}_TARGETS)
list(REMOVE_DUPLICATES ${module_name}_TARGETS)
endif()
endmacro()

View File

@ -0,0 +1,15 @@
{
"Id": "extra-cmake-modules",
"Name": "extra-cmake-modules",
"QDocModule": "qtcore",
"QtUsage": "Used as part of the build system.",
"Description": "Additional CMake modules.",
"Homepage": "https://api.kde.org/ecm/",
"Version": "5.50.0",
"License": "BSD-3-Clause",
"LicenseId": "BSD 3-Clause License",
"LicenseFile": "COPYING-CMAKE-SCRIPTS",
"Copyright": "Copyright © 2011-2018 The KDE community"
}

View File

@ -0,0 +1,22 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

126
cmake/3rdparty/kwin/FindLibdrm.cmake vendored Normal file
View File

@ -0,0 +1,126 @@
#.rst:
# FindLibdrm
# -------
#
# Try to find libdrm on a Unix system.
#
# This will define the following variables:
#
# ``Libdrm_FOUND``
# True if (the requested version of) libdrm is available
# ``Libdrm_VERSION``
# The version of libdrm
# ``Libdrm_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``Libdrm::Libdrm``
# target
# ``Libdrm_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``Libdrm_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``Libdrm_FOUND`` is TRUE, it will also define the following imported target:
#
# ``Libdrm::Libdrm``
# The libdrm library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by FindLibdrm.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindLibdrm.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_Libdrm QUIET libdrm)
set(Libdrm_DEFINITIONS ${PKG_Libdrm_CFLAGS_OTHER})
set(Libdrm_VERSION ${PKG_Libdrm_VERSION})
find_path(Libdrm_INCLUDE_DIR
NAMES
xf86drm.h
HINTS
${PKG_Libdrm_INCLUDE_DIRS}
)
find_library(Libdrm_LIBRARY
NAMES
drm
HINTS
${PKG_Libdrm_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libdrm
FOUND_VAR
Libdrm_FOUND
REQUIRED_VARS
Libdrm_LIBRARY
Libdrm_INCLUDE_DIR
VERSION_VAR
Libdrm_VERSION
)
if(Libdrm_FOUND AND NOT TARGET Libdrm::Libdrm)
add_library(Libdrm::Libdrm UNKNOWN IMPORTED)
set_target_properties(Libdrm::Libdrm PROPERTIES
IMPORTED_LOCATION "${Libdrm_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Libdrm_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}"
INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIR}/libdrm"
)
endif()
mark_as_advanced(Libdrm_LIBRARY Libdrm_INCLUDE_DIR)
# compatibility variables
set(Libdrm_LIBRARIES ${Libdrm_LIBRARY})
set(Libdrm_INCLUDE_DIRS ${Libdrm_INCLUDE_DIR} "${Libdrm_INCLUDE_DIR}/libdrm")
set(Libdrm_VERSION_STRING ${Libdrm_VERSION})
else()
message(STATUS "FindLibdrm.cmake cannot find libdrm on Windows systems.")
set(Libdrm_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(Libdrm PROPERTIES
URL "https://wiki.freedesktop.org/dri/"
DESCRIPTION "Userspace interface to kernel DRM services."
)

125
cmake/3rdparty/kwin/FindLibinput.cmake vendored Normal file
View File

@ -0,0 +1,125 @@
#.rst:
# FindLibinput
# -------
#
# Try to find libinput on a Unix system.
#
# This will define the following variables:
#
# ``Libinput_FOUND``
# True if (the requested version of) libinput is available
# ``Libinput_VERSION``
# The version of libinput
# ``Libinput_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``Libinput::Libinput``
# target
# ``Libinput_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``Libinput_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``Libinput_FOUND`` is TRUE, it will also define the following imported target:
#
# ``Libinput::Libinput``
# The libinput library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by FindLibinput.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindLibinput.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_Libinput QUIET libinput)
set(Libinput_DEFINITIONS ${PKG_Libinput_CFLAGS_OTHER})
set(Libinput_VERSION ${PKG_Libinput_VERSION})
find_path(Libinput_INCLUDE_DIR
NAMES
libinput.h
HINTS
${PKG_Libinput_INCLUDE_DIRS}
)
find_library(Libinput_LIBRARY
NAMES
input
HINTS
${PKG_Libinput_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Libinput
FOUND_VAR
Libinput_FOUND
REQUIRED_VARS
Libinput_LIBRARY
Libinput_INCLUDE_DIR
VERSION_VAR
Libinput_VERSION
)
if(Libinput_FOUND AND NOT TARGET Libinput::Libinput)
add_library(Libinput::Libinput UNKNOWN IMPORTED)
set_target_properties(Libinput::Libinput PROPERTIES
IMPORTED_LOCATION "${Libinput_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${Libinput_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${Libinput_INCLUDE_DIR}"
)
endif()
mark_as_advanced(Libinput_LIBRARY Libinput_INCLUDE_DIR)
# compatibility variables
set(Libinput_LIBRARIES ${Libinput_LIBRARY})
set(Libinput_INCLUDE_DIRS ${Libinput_INCLUDE_DIR})
set(Libinput_VERSION_STRING ${Libinput_VERSION})
else()
message(STATUS "FindLibinput.cmake cannot find libinput on Windows systems.")
set(Libinput_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(Libinput PROPERTIES
URL "http://www.freedesktop.org/wiki/Software/libinput/"
DESCRIPTION "Library to handle input devices in Wayland compositors and to provide a generic X.Org input driver."
)

101
cmake/3rdparty/kwin/FindXKB.cmake vendored Normal file
View File

@ -0,0 +1,101 @@
# Try to find xkbcommon on a Unix system
#
# This will define:
#
# XKB_FOUND - True if XKB is available
# XKB_LIBRARIES - Link these to use XKB
# XKB_INCLUDE_DIRS - Include directory for XKB
# XKB_DEFINITIONS - Compiler flags for using XKB
#
# Additionally, the following imported targets will be defined:
#
# XKB::XKB
#
# Copyright (c) 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by FindXKB.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use FindXKB.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_XKB QUIET xkbcommon)
set(XKB_DEFINITIONS ${PKG_XKB_CFLAGS_OTHER})
find_path(XKB_INCLUDE_DIR
NAMES
xkbcommon/xkbcommon.h
HINTS
${PKG_XKB_INCLUDE_DIRS}
)
find_library(XKB_LIBRARY
NAMES
xkbcommon
HINTS
${PKG_XKB_LIBRARY_DIRS}
)
set(XKB_LIBRARIES ${XKB_LIBRARY})
set(XKB_INCLUDE_DIRS ${XKB_INCLUDE_DIR})
set(XKB_VERSION ${PKG_XKB_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(XKB
FOUND_VAR
XKB_FOUND
REQUIRED_VARS
XKB_LIBRARY
XKB_INCLUDE_DIR
VERSION_VAR
XKB_VERSION
)
if(XKB_FOUND AND NOT TARGET XKB::XKB)
add_library(XKB::XKB UNKNOWN IMPORTED)
set_target_properties(XKB::XKB PROPERTIES
IMPORTED_LOCATION "${XKB_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${XKB_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${XKB_INCLUDE_DIR}"
)
endif()
else()
message(STATUS "FindXKB.cmake cannot find XKB on Windows systems.")
set(XKB_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(XKB PROPERTIES
URL "http://xkbcommon.org"
DESCRIPTION "XKB API common to servers and clients."
)

125
cmake/3rdparty/kwin/Findgbm.cmake vendored Normal file
View File

@ -0,0 +1,125 @@
#.rst:
# Findgbm
# -------
#
# Try to find gbm on a Unix system.
#
# This will define the following variables:
#
# ``gbm_FOUND``
# True if (the requested version of) gbm is available
# ``gbm_VERSION``
# The version of gbm
# ``gbm_LIBRARIES``
# This can be passed to target_link_libraries() instead of the ``gbm::gbm``
# target
# ``gbm_INCLUDE_DIRS``
# This should be passed to target_include_directories() if the target is not
# used for linking
# ``gbm_DEFINITIONS``
# This should be passed to target_compile_options() if the target is not
# used for linking
#
# If ``gbm_FOUND`` is TRUE, it will also define the following imported target:
#
# ``gbm::gbm``
# The gbm library
#
# In general we recommend using the imported target, as it is easier to use.
# Bear in mind, however, that if the target is in the link interface of an
# exported library, it must be made available by the package config file.
#=============================================================================
# Copyright 2014 Alex Merry <alex.merry@kde.org>
# Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by Findgbm.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Findgbm.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_gbm QUIET gbm)
set(gbm_DEFINITIONS ${PKG_gbm_CFLAGS_OTHER})
set(gbm_VERSION ${PKG_gbm_VERSION})
find_path(gbm_INCLUDE_DIR
NAMES
gbm.h
HINTS
${PKG_gbm_INCLUDE_DIRS}
)
find_library(gbm_LIBRARY
NAMES
gbm
HINTS
${PKG_gbm_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(gbm
FOUND_VAR
gbm_FOUND
REQUIRED_VARS
gbm_LIBRARY
gbm_INCLUDE_DIR
VERSION_VAR
gbm_VERSION
)
if(gbm_FOUND AND NOT TARGET gbm::gbm)
add_library(gbm::gbm UNKNOWN IMPORTED)
set_target_properties(gbm::gbm PROPERTIES
IMPORTED_LOCATION "${gbm_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${gbm_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${gbm_INCLUDE_DIR}"
)
endif()
mark_as_advanced(gbm_LIBRARY gbm_INCLUDE_DIR)
# compatibility variables
set(gbm_LIBRARIES ${gbm_LIBRARY})
set(gbm_INCLUDE_DIRS ${gbm_INCLUDE_DIR})
set(gbm_VERSION_STRING ${gbm_VERSION})
else()
message(STATUS "Findgbm.cmake cannot find gbm on Windows systems.")
set(gbm_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(gbm PROPERTIES
URL "http://www.mesa3d.org"
DESCRIPTION "Mesa gbm library."
)

17
cmake/3rdparty/kwin/qt_attribution.json vendored Normal file
View File

@ -0,0 +1,17 @@
{
"Id": "kwin",
"Name": "KWin",
"QDocModule": "qtcore",
"QtUsage": "Used as part of the build system.",
"Description": "Additional CMake modules for graphics system dependencies.",
"Homepage": "https://www.kde.org/",
"Version": "5.13.4",
"License": "BSD-3-Clause",
"LicenseId": "BSD 3-Clause License",
"LicenseFile": "COPYING-CMAKE-SCRIPTS",
"Copyright": "Copyright 2014 Alex Merry <alex.merry@kde.org>
Copyright 2014 Martin Gräßlin <mgraesslin@kde.org>,
Copyright (c) 2006,2007 Laurent Montel, <montel@kde.org>"
}

View File

@ -0,0 +1,15 @@
@PACKAGE_INIT@
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
set(old_CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}")
set(CMAKE_MODULE_PATH "${_import_prefix}" ${CMAKE_MODULE_PATH} )
@3RDPARTY_ADDITIONAL_SETUP_CODE@
set(CMAKE_MODULE_PATH "${old_CMAKE_MODULE_PATH}")
if (NOT QT_NO_CREATE_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@target@Targets.cmake")
endif()

7
cmake/FindATSPI2.cmake Normal file
View File

@ -0,0 +1,7 @@
include(FindPkgConfig)
pkg_check_modules(ATSPI2 atspi-2 IMPORTED_TARGET)
if (NOT TARGET PkgConfig::ATSPI2)
set(ATSPI2_FOUND 0)
endif()

44
cmake/FindAtomic.cmake Normal file
View File

@ -0,0 +1,44 @@
# We can't create the same interface imported target multiple times, CMake will complain if we do
# that. This can happen if the find_package call is done in multiple different subdirectories.
if(TARGET Atomic)
set(Atomic_FOUND ON)
return()
endif()
include(CheckCXXSourceCompiles)
set (atomic_test_sources "#include <atomic>
#include <cstdint>
void test(volatile std::atomic<std::int64_t> &a)
{
std::int64_t v = a.load(std::memory_order_acquire);
while (!a.compare_exchange_strong(v, v + 1,
std::memory_order_acq_rel,
std::memory_order_acquire)) {
v = a.exchange(v - 1);
}
a.store(v + 1, std::memory_order_release);
}
int main(int, char **)
{
void *ptr = (void*)0xffffffc0; // any random pointer
test(*reinterpret_cast<std::atomic<std::int64_t> *>(ptr));
return 0;
}")
check_cxx_source_compiles("${atomic_test_sources}" HAVE_STDATOMIC)
if(NOT HAVE_STDATOMIC)
set(_req_libraries "${CMAKE_REQUIRE_LIBRARIES}")
set(CMAKE_REQUIRE_LIBRARIES "atomic")
check_cxx_source_compiles("${atomic_test_sources}" HAVE_STDATOMIC_WITH_LIB)
set(CMAKE_REQUIRE_LIBRARIES "${_req_libraries}")
endif()
add_library(Atomic INTERFACE IMPORTED)
if(HAVE_STDATOMIC_WITH_LIB)
target_link_libraries(Atomic INTERFACE atomic)
endif()
set(Atomic_FOUND 1)

98
cmake/FindCups.cmake Normal file
View File

@ -0,0 +1,98 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#[=======================================================================[.rst:
FindCups
--------
Find the CUPS printing system.
Set CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE to TRUE if you need a version which
features this function (i.e. at least 1.1.19)
Imported targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` target ``Cups::Cups``, if Cups has
been found.
Result variables
^^^^^^^^^^^^^^^^
This module will set the following variables in your project:
``CUPS_FOUND``
true if CUPS headers and libraries were found
``CUPS_INCLUDE_DIRS``
the directory containing the Cups headers
``CUPS_LIBRARIES``
the libraries to link against to use CUPS.
``CUPS_VERSION_STRING``
the version of CUPS found (since CMake 2.8.8)
Cache variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``CUPS_INCLUDE_DIR``
the directory containing the Cups headers
#]=======================================================================]
find_path(CUPS_INCLUDE_DIR cups/cups.h )
find_library(CUPS_LIBRARIES NAMES cups )
if (CUPS_INCLUDE_DIR AND CUPS_LIBRARIES AND CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
include(${CMAKE_CURRENT_LIST_DIR}/CheckLibraryExists.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CMakePushCheckState.cmake)
cmake_push_check_state()
set(CMAKE_REQUIRED_QUIET ${Cups_FIND_QUIETLY})
# ippDeleteAttribute is new in cups-1.1.19 (and used by kdeprint)
CHECK_LIBRARY_EXISTS(cups ippDeleteAttribute "" CUPS_HAS_IPP_DELETE_ATTRIBUTE)
cmake_pop_check_state()
endif ()
if (CUPS_INCLUDE_DIR AND EXISTS "${CUPS_INCLUDE_DIR}/cups/cups.h")
file(STRINGS "${CUPS_INCLUDE_DIR}/cups/cups.h" cups_version_str
REGEX "^#[\t ]*define[\t ]+CUPS_VERSION_(MAJOR|MINOR|PATCH)[\t ]+[0-9]+$")
unset(CUPS_VERSION_STRING)
foreach(VPART MAJOR MINOR PATCH)
foreach(VLINE ${cups_version_str})
if(VLINE MATCHES "^#[\t ]*define[\t ]+CUPS_VERSION_${VPART}[\t ]+([0-9]+)$")
set(CUPS_VERSION_PART "${CMAKE_MATCH_1}")
if(CUPS_VERSION_STRING)
string(APPEND CUPS_VERSION_STRING ".${CUPS_VERSION_PART}")
else()
set(CUPS_VERSION_STRING "${CUPS_VERSION_PART}")
endif()
endif()
endforeach()
endforeach()
endif ()
include(FindPackageHandleStandardArgs)
if (CUPS_REQUIRE_IPP_DELETE_ATTRIBUTE)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cups
REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR CUPS_HAS_IPP_DELETE_ATTRIBUTE
VERSION_VAR CUPS_VERSION_STRING)
else ()
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cups
REQUIRED_VARS CUPS_LIBRARIES CUPS_INCLUDE_DIR
VERSION_VAR CUPS_VERSION_STRING)
endif ()
mark_as_advanced(CUPS_INCLUDE_DIR CUPS_LIBRARIES)
if (CUPS_FOUND)
set(CUPS_INCLUDE_DIRS "${CUPS_INCLUDE_DIR}")
if (NOT TARGET Cups::Cups)
add_library(Cups::Cups INTERFACE IMPORTED)
set_target_properties(Cups::Cups PROPERTIES
INTERFACE_LINK_LIBRARIES "${CUPS_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${CUPS_INCLUDE_DIR}")
endif ()
endif ()

59
cmake/FindDB2.cmake Normal file
View File

@ -0,0 +1,59 @@
#.rst:
# FindDB2
# ---------
#
# Try to locate the db2 client library.
# If found, this will define the following variables:
#
# ``DB2_FOUND``
# True if the db2 library is available
# ``DB2_INCLUDE_DIRS``
# The db2 include directories
# ``DB2_LIBRARIES``
# The db2 libraries for linking
#
# If ``DB2_FOUND`` is TRUE, it will also define the following
# imported target:
#
# ``DB2::DB2``
# The db2 client library
if (NOT DEFINED DB2_INCLUDE_DIR)
find_path(DB2_INCLUDE_DIRS
NAMES sqlcli1.h
HINTS ENV DB2_HOME
PATH_SUFFIXES include)
else()
find_path(DB2_INCLUDE_DIRS
NAMES sqlcli1.h
HINTS ${DB2_INCLUDE_DIR})
endif()
if (NOT DEFINED DB2_LIBRARY_DIR)
find_library(DB2_LIBRARIES
NAMES db2
HINTS ENV DB2LIB)
else()
find_library(DB2_LIBRARIES
NAMES db2
HINTS ${DB2_LIBRARY_DIR})
endif()
if (NOT DB2_INCLUDE_DIRS STREQUAL "DB2_INCLUDE_DIRS-NOTFOUND" AND NOT DB2_LIBRARIES STREQUAL "DB2_LIBRARIES-NOTFOUND")
set(DB2_FOUND ON)
endif()
if(DB2_FOUND AND NOT TARGET DB2::DB2)
add_library(DB2::DB2 UNKNOWN IMPORTED)
set_target_properties(DB2::DB2 PROPERTIES
IMPORTED_LOCATION "${DB2_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${DB2_INCLUDE_DIRS}")
endif()
mark_as_advanced(DB2_INCLUDE_DIRS DB2_LIBRARIES)
include(FeatureSummary)
set_package_properties(DB2 PROPERTIES
URL "https://www.ibm.com"
DESCRIPTION "IBM DB2 client library")

7
cmake/FindDirectFB.cmake Normal file
View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(DirectFB directfb IMPORTED_TARGET)
if (NOT TARGET PkgConfig::DirectFB)
set(DirectFB_FOUND 0)
endif()

72
cmake/FindGLESv2.cmake Normal file
View File

@ -0,0 +1,72 @@
include(CheckCXXSourceCompiles)
# No library linkage is necessary to use GLESv2 with Emscripten. The headers are also
# system headers, so we don't need to search for them.
if(EMSCRIPTEN)
set(HAVE_GLESv2 ON)
else()
find_library(GLESv2_LIBRARY NAMES GLESv2 OpenGLES)
find_path(GLESv2_INCLUDE_DIR NAMES "GLES2/gl2.h" "OpenGLES/ES2/gl.h" DOC "The OpenGLES 2 include path")
set(_libraries "${CMAKE_REQUIRED_LIBRARIES}")
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GLESv2_LIBRARY}")
set(_includes "${CMAKE_REQUIRED_INCLUDES}")
list(APPEND CMAKE_REQUIRED_INCLUDES "${GLESv2_INCLUDE_DIR}")
check_cxx_source_compiles("
#ifdef __APPLE__
# include <OpenGLES/ES2/gl.h>
#else
# define GL_GLEXT_PROTOTYPES
# include <GLES2/gl2.h>
#endif
int main(int argc, char *argv[]) {
glUniform1f(1, GLfloat(1.0));
glClear(GL_COLOR_BUFFER_BIT);
}" HAVE_GLESv2)
set(CMAKE_REQUIRED_LIBRARY "${_libraries}")
unset(_libraries)
set(CMAKE_REQUIRED_INCLUDES "${_includes}")
unset(_includes)
set(package_args GLESv2_INCLUDE_DIR GLESv2_LIBRARY HAVE_GLESv2)
endif()
# Framework handling partially inspired by FindGLUT.cmake.
if(GLESv2_LIBRARY MATCHES "/([^/]+)\\.framework$")
# TODO: Might need to handle non .tbd suffixes, but didn't find an
# example like that.
# TODO: Might need to handle INTERFACE_INCLUDE_DIRECTORIES differently.
set(_library_imported_location "${GLESv2_LIBRARY}/${CMAKE_MATCH_1}.tbd")
if(NOT EXISTS "${_library_imported_location}")
set(_library_imported_location "")
endif()
else()
set(_library_imported_location "${GLESv2_LIBRARY}")
endif()
set(GLESv2_LIBRARY "${_library_imported_location}")
list(APPEND package_args HAVE_GLESv2)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GLESv2 DEFAULT_MSG ${package_args})
mark_as_advanced(${package_args})
if(GLESv2_FOUND AND NOT TARGET GLESv2::GLESv2)
if(EMSCRIPTEN OR APPLE_UIKIT)
add_library(GLESv2::GLESv2 INTERFACE IMPORTED)
if(APPLE_UIKIT)
# For simulator_and_device builds we can't specify the full library path, because
# it's specific to either the device or the simulator. Resort to passing a link
# flag instead.
set_target_properties(GLESv2::GLESv2 PROPERTIES
INTERFACE_LINK_LIBRARIES "-framework OpenGLES")
endif()
else()
add_library(GLESv2::GLESv2 UNKNOWN IMPORTED)
set_target_properties(GLESv2::GLESv2 PROPERTIES
IMPORTED_LOCATION "${GLESv2_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${GLESv2_INCLUDE_DIR}")
endif()
endif()

39
cmake/FindGSSAPI.cmake Normal file
View File

@ -0,0 +1,39 @@
find_package(PkgConfig)
pkg_check_modules(PC_GSSAPI QUIET krb5-gssapi)
find_path(GSSAPI_INCLUDE_DIRS
NAMES gssapi/gssapi.h
HINTS ${PC_GSSAPI_INCLUDEDIR}
PATH_SUFFIXES gssapi)
find_library(GSSAPI_LIBRARIES
NAMES
GSS # framework
gssapi_krb5
HINTS ${PC_GSSAPILIBDIR}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GSSAPI DEFAULT_MSG GSSAPI_LIBRARIES GSSAPI_INCLUDE_DIRS)
if(GSSAPI_FOUND AND NOT TARGET GSSAPI::GSSAPI)
if(GSSAPI_LIBRARIES MATCHES "/([^/]+)\\.framework$")
add_library(GSSAPI::GSSAPI INTERFACE IMPORTED)
set_target_properties(GSSAPI::GSSAPI PROPERTIES
INTERFACE_LINK_LIBRARIES "${GSSAPI_LIBRARIES}")
else()
add_library(GSSAPI::GSSAPI UNKNOWN IMPORTED)
set_target_properties(GSSAPI::GSSAPI PROPERTIES
IMPORTED_LOCATION "${GSSAPI_LIBRARIES}")
endif()
set_target_properties(GSSAPI::GSSAPI PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${GSSAPI_INCLUDE_DIRS}")
endif()
mark_as_advanced(GSSAPI_INCLUDE_DIRS GSSAPI_LIBRARIES)
include(FeatureSummary)
set_package_properties(GSSAPI PROPERTIES
DESCRIPTION "Generic Security Services Application Program Interface")

7
cmake/FindGTK3.cmake Normal file
View File

@ -0,0 +1,7 @@
include(FindPkgConfig)
pkg_check_modules(GTK3 "gtk+-3.0 >= 3.6" IMPORTED_TARGET)
if (NOT TARGET PkgConfig::GTK3)
set(GTK3_FOUND 0)
endif()

7
cmake/FindLibproxy.cmake Normal file
View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(Libproxy libproxy-1.0 IMPORTED_TARGET)
if (NOT TARGET PkgConfig::Libproxy)
set(Libproxy_FOUND 0)
endif()

View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(Libsystemd libsystemd IMPORTED_TARGET)
if (NOT TARGET PkgConfig::Libsystemd)
set(Libsystemd_FOUND 0)
endif()

7
cmake/FindLibudev.cmake Normal file
View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(Libudev libudev IMPORTED_TARGET)
if (NOT TARGET PkgConfig::Libudev)
set(Libudev_FOUND 0)
endif()

7
cmake/FindMtdev.cmake Normal file
View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(Mtdev mtdev IMPORTED_TARGET)
if (NOT TARGET PkgConfig::MtDev)
set(Mtdev_FOUND 0)
endif()

50
cmake/FindMySQL.cmake Normal file
View File

@ -0,0 +1,50 @@
#.rst:
# FindMySQL
# ---------
#
# Try to locate the mysql client library.
# If found, this will define the following variables:
#
# ``MySQL_FOUND``
# True if the mysql library is available
# ``MySQL_INCLUDE_DIRS``
# The mysql include directories
# ``MySQL_LIBRARIES``
# The mysql libraries for linking
#
# If ``MySQL_FOUND`` is TRUE, it will also define the following
# imported target:
#
# ``MySQL::MySQL``
# The mysql client library
find_package(PkgConfig)
pkg_check_modules(PC_MySQL QUIET mysqlclient)
find_path(MySQL_INCLUDE_DIRS
NAMES mysql.h
HINTS ${PC_MySQL_INCLUDEDIR}
PATH_SUFFIXES mysql)
find_library(MySQL_LIBRARIES
NAMES mysqlclient
HINTS ${PC_MySQL_LIBDIR}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MySQL DEFAULT_MSG MySQL_LIBRARIES MySQL_INCLUDE_DIRS)
if(MySQL_FOUND AND NOT TARGET MySQL::MySQL)
add_library(MySQL::MySQL UNKNOWN IMPORTED)
set_target_properties(MySQL::MySQL PROPERTIES
IMPORTED_LOCATION "${MySQL_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${MySQL_INCLUDE_DIRS}")
endif()
mark_as_advanced(MySQL_INCLUDE_DIRS MySQL_LIBRARIES)
include(FeatureSummary)
set_package_properties(MySQL PROPERTIES
URL "https://www.mysql.com"
DESCRIPTION "MySQL client library")

48
cmake/FindOracle.cmake Normal file
View File

@ -0,0 +1,48 @@
#.rst:
# FindOracle
# ---------
#
# Try to locate the oracle client library.
# If found, this will define the following variables:
#
# ``Oracle_FOUND``
# True if the oracle library is available
# ``Oracle_INCLUDE_DIRS``
# The oracle include directories
# ``Oracle_LIBRARIES``
# The oracle libraries for linking
#
# If ``Oracle_FOUND`` is TRUE, it will also define the following
# imported target:
#
# ``Oracle::Oracle``
# The oracle instant client library
find_path(Oracle_INCLUDE_DIRS
NAMES oci.h
HINTS ${Oracle_INCLUDE_DIR})
set(ORACLE_OCI_NAMES clntsh ociei oraociei12)
find_library(Oracle_LIBRARIES
NAMES NAMES ${ORACLE_OCI_NAMES}
HINTS ${Oracle_LIBRARY_DIR})
if (NOT Oracle_INCLUDE_DIRS STREQUAL "Oracle_INCLUDE_DIRS-NOTFOUND" AND NOT Oracle_LIBRARIES STREQUAL "Oracle_LIBRARIES-NOTFOUND")
set(Oracle_FOUND ON)
endif()
if(Oracle_FOUND AND NOT TARGET Oracle::OCI)
add_library(Oracle::OCI UNKNOWN IMPORTED)
set_target_properties(Oracle::OCI PROPERTIES
IMPORTED_LOCATION "${Oracle_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${Oracle_INCLUDE_DIRS}")
endif()
mark_as_advanced(Oracle_INCLUDE_DIRS Oracle_LIBRARIES)
include(FeatureSummary)
set_package_properties(Oracle PROPERTIES
URL "https://www.oracle.com"
DESCRIPTION "Oracle client library")

19
cmake/FindPPS.cmake Normal file
View File

@ -0,0 +1,19 @@
# Find the PPS library
# Will make the target PPS::PPS available when found.
find_library(PPS_LIBRARY NAMES "pps")
find_path(PPS_INCLUDE_DIR NAMES "sys/pps.h" DOC "The PPS Include path")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PPS DEFAULT_MSG PPS_INCLUDE_DIR PPS_LIBRARY)
mark_as_advanced(PPS_INCLUDE_DIR PPS_LIBRARY)
if(PPS_FOUND)
add_library(__PPS INTERFACE IMPORTED)
target_link_libraries(__PPS INTERFACE ${PPS_LIBRARY})
target_include_directories(__PPS INTERFACE ${PPS_INCLUDE_DIR})
add_library(PPS::PPS ALIAS __PPS)
endif()

19
cmake/FindSlog2.cmake Normal file
View File

@ -0,0 +1,19 @@
# Find the Slog2 library
# Will make the target Slog2::Slog2 available when found.
find_library(Slog2_LIBRARY NAMES "slog2")
find_path(Slog2_INCLUDE_DIR NAMES "sys/slog2.h" DOC "The Slog2 Include path")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Slog2 DEFAULT_MSG Slog2_INCLUDE_DIR Slog2_LIBRARY)
mark_as_advanced(Slog2_INCLUDE_DIR Slog2_LIBRARY)
if(Slog2_FOUND)
add_library(__Slog2 INTERFACE IMPORTED)
target_link_libraries(__Slog2 INTERFACE ${Slog2_LIBRARY})
target_include_directories(__Slog2 INTERFACE ${Slog2_INCLUDE_DIR})
add_library(Slog2::Slog2 ALIAS __Slog2)
endif()

7
cmake/FindTslib.cmake Normal file
View File

@ -0,0 +1,7 @@
find_package(PkgConfig)
pkg_check_modules(Tslib tslib IMPORTED_TARGET)
if (NOT TARGET PkgConfig::Tslib)
set(Tslib_FOUND 0)
endif()

35
cmake/FindWrapDBus1.cmake Normal file
View File

@ -0,0 +1,35 @@
# DBus1 is buggy and breaks PKG_CONFIG environment.
# Work around that:-/
# See https://gitlab.freedesktop.org/dbus/dbus/issues/267 for more information
if(DEFINED ENV{PKG_CONFIG_DIR})
set(__qt_dbus_pcd "$ENV{PKG_CONFIG_DIR}")
endif()
if(DEFINED ENV{PKG_CONFIG_PATH})
set(__qt_dbus_pcp "$ENV{PKG_CONFIG_PATH}")
endif()
if(DEFINED ENV{PKG_CONFIG_LIBDIR})
set(__qt_dbus_pcl "$ENV{PKG_CONFIG_LIBDIR}")
endif()
find_package(DBus1)
if(DEFINED __qt_dbus_pcd)
set(ENV{PKG_CONFIG_DIR} "${__qt_dbus_pcd}")
else()
unset(ENV{PKG_CONFIG_DIR})
endif()
if(DEFINED __qt_dbus_pcp)
set(ENV{PKG_CONFIG_PATH} "${__qt_dbus_pcp}")
else()
unset(ENV{PKG_CONFIG_PATH})
endif()
if(DEFINED __qt_dbus_pcl)
set(ENV{PKG_CONFIG_LIBDIR} "${__qt_dbus_pcl}")
else()
unset(ENV{PKG_CONFIG_LIBDIR})
endif()
if(DBus1_FOUND)
set(WrapDBus1_FOUND 1)
endif()

View File

@ -0,0 +1,61 @@
# We can't create the same interface imported target multiple times, CMake will complain if we do
# that. This can happen if the find_package call is done in multiple different subdirectories.
if(TARGET WrapDoubleConversion::WrapDoubleConversion)
set(WrapDoubleConversion_FOUND ON)
return()
endif()
add_library(WrapDoubleConversion::WrapDoubleConversion INTERFACE IMPORTED)
find_package(double-conversion)
if (double-conversion_FOUND)
include(FeatureSummary)
set_package_properties(double-conversion PROPERTIES TYPE REQUIRED)
target_link_libraries(WrapDoubleConversion::WrapDoubleConversion
INTERFACE double-conversion::double-conversion)
set(WrapDoubleConversion_FOUND 1)
return()
endif()
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <stdio.h>
#include <locale.h>
int main(int argc, char *argv[]) {
_locale_t invalidLocale = NULL;
double a = 3.14;
const char *format = \"invalid format\";
_sscanf_l(argv[0], invalidLocale, format, &a, &argc);
_snprintf_l(argv[0], 1, invalidLocale, format, a);
}" HAVE__SPRINTF_L)
check_cxx_source_compiles("
#include <stdio.h>
#include <xlocale.h>
int main(int argc, char *argv[]) {
locale_t invalidLocale = NULL;
double a = 3.14;
const char *format = \"invalid format\";
snprintf_l(argv[0], 1, invalidLocale, format, a);
sscanf_l(argv[0], invalidLocale, format, &a, &argc);
return 0;
}" HAVE_SPRINTF_L)
# In a static build, we need to find the package to bring the target into scope.
find_package(QtDoubleConversion QUIET)
if (HAVE__SPRINTF_L OR HAVE_SPRINTF_L)
target_compile_definitions(WrapDoubleConversion::WrapDoubleConversion
INTERFACE QT_NO_DOUBLECONVERSION)
set(WrapDoubleConversion_FOUND 1)
elseif(TARGET QtDoubleConversion)
# If a Config package wasn't found, and the C++ library doesn't contain the necessary functions,
# use the library bundled with Qt.
target_link_libraries(WrapDoubleConversion::WrapDoubleConversion INTERFACE QtDoubleConversion)
set(WrapDoubleConversion_FOUND 1)
else()
set(WrapDoubleConversion_FOUND 0)
endif()

View File

@ -0,0 +1,33 @@
# We can't create the same interface imported target multiple times, CMake will complain if we do
# that. This can happen if the find_package call is done in multiple different subdirectories.
if(TARGET WrapFreetype::WrapFreetype)
set(WrapFreetype_FOUND ON)
return()
endif()
set(WrapFreetype_FOUND OFF)
# Hunter has the package named freetype, but exports the Freetype::Freetype target as upstream
# First try the CONFIG package, and afterwards the MODULE if not found
find_package(Freetype CONFIG NAMES Freetype freetype QUIET)
if(NOT Freetype_FOUND)
find_package(Freetype MODULE)
endif()
if(Freetype_FOUND)
# vcpkg defines a lower case target name, while upstream Find module defines a prefixed
# upper case name.
set(potential_target_names Freetype::Freetype freetype)
foreach(target_name ${potential_target_names})
if(TARGET ${target_name})
set(WrapFreetype_FOUND ON)
set(final_target_name ${target_name})
add_library(WrapFreetype::WrapFreetype INTERFACE IMPORTED)
target_link_libraries(WrapFreetype::WrapFreetype INTERFACE ${final_target_name})
break()
endif()
endforeach()
endif()

View File

@ -0,0 +1,45 @@
# We can't create the same interface imported target multiple times, CMake will complain if we do
# that. This can happen if the find_package call is done in multiple different subdirectories.
if(TARGET WrapHarfbuzz::WrapHarfbuzz)
set(WrapHarfbuzz_FOUND ON)
return()
endif()
set(WrapHarfbuzz_FOUND OFF)
find_package(harfbuzz)
# Gentoo has some buggy version of a harfbuzz Config file. Check if include paths are valid.
set(__harfbuzz_target_name "harfbuzz::harfbuzz")
if(harfbuzz_FOUND AND TARGET "${__harfbuzz_target_name}")
get_property(__harfbuzz_include_paths TARGET "${__harfbuzz_target_name}"
PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
foreach(__harfbuzz_include_dir ${__harfbuzz_include_paths})
if(NOT EXISTS "${__harfbuzz_include_dir}")
# Must be the broken Gentoo harfbuzzConfig.cmake file. Try to use pkg-config instead.
set(__harfbuzz_broken_config_file TRUE)
break()
endif()
endforeach()
endif()
if(__harfbuzz_broken_config_file)
find_package(PkgConfig)
pkg_check_modules(harfbuzz harfbuzz IMPORTED_TARGET)
set(__harfbuzz_target_name "PkgConfig::harfbuzz")
if (NOT TARGET "${__harfbuzz_target_name}")
set(harfbuzz_FOUND 0)
endif()
endif()
if(TARGET "${__harfbuzz_target_name}")
set(WrapHarfbuzz_FOUND ON)
add_library(WrapHarfbuzz::WrapHarfbuzz INTERFACE IMPORTED)
target_link_libraries(WrapHarfbuzz::WrapHarfbuzz INTERFACE ${__harfbuzz_target_name})
endif()
unset(__harfbuzz_target_name)
unset(__harfbuzz_include_dir)
unset(__harfbuzz_broken_config_file)

23
cmake/FindWrapPCRE2.cmake Normal file
View File

@ -0,0 +1,23 @@
if(TARGET WrapPCRE2::WrapPCRE2)
set(WrapPCRE2_FOUND TRUE)
return()
endif()
find_package(PCRE2 CONFIG QUIET)
if(PCRE2_FOUND AND TARGET PCRE2::pcre2-16)
# Hunter case.
add_library(WrapPCRE2::WrapPCRE2 INTERFACE IMPORTED)
target_link_libraries(WrapPCRE2::WrapPCRE2 INTERFACE PCRE2::pcre2-16)
set(WrapPCRE2_FOUND TRUE)
else()
find_library(PCRE2_LIBRARIES NAMES pcre2-16)
find_path(PCRE2_INCLUDE_DIRS pcre2.h)
if (PCRE2_LIBRARIES AND PCRE2_INCLUDE_DIRS)
add_library(WrapPCRE2::WrapPCRE2 INTERFACE IMPORTED)
target_link_libraries(WrapPCRE2::WrapPCRE2 INTERFACE ${PCRE2_LIBRARIES})
target_include_directories(WrapPCRE2::WrapPCRE2 INTERFACE ${PCRE2_INCLUDE_DIRS})
set(WrapPCRE2_FOUND TRUE)
endif()
endif()

34
cmake/FindWrapRt.cmake Normal file
View File

@ -0,0 +1,34 @@
# We can't create the same interface imported target multiple times, CMake will complain if we do
# that. This can happen if the find_package call is done in multiple different subdirectories.
if(TARGET WrapRt)
set(WrapRt_FOUND ON)
return()
endif()
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
find_library(LIBRT rt)
cmake_push_check_state()
if(LIBRT_FOUND)
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBRT}")
endif()
check_cxx_source_compiles("
#include <unistd.h>
#include <time.h>
int main(int argc, char *argv[]) {
timespec ts; clock_gettime(CLOCK_REALTIME, &ts);
}" HAVE_GETTIME)
cmake_pop_check_state()
add_library(WrapRt INTERFACE IMPORTED)
if (LIBRT_FOUND)
target_link_libraries(WrapRt INTERFACE "${LIBRT}")
endif()
set(WrapRt_FOUND "${HAVE_GETTIME}")

View File

@ -0,0 +1,7 @@
include(FindPkgConfig)
pkg_check_modules(XKB_COMMON_X11 "xkbcommon-x11>=0.4.1" IMPORTED_TARGET)
if (NOT TARGET PkgConfig::XKB_COMMON_X11)
set(XKB_COMMON_X11_FOUND 0)
endif()

11
cmake/FindXRender.cmake Normal file
View File

@ -0,0 +1,11 @@
include(FindPkgConfig)
if(NOT TARGET PkgConfig::XRender)
pkg_check_modules(XRender xrender IMPORTED_TARGET)
if (NOT TARGET PkgConfig::XRender)
set(XRender_FOUND 0)
endif()
else()
set(XRender_FOUND 1)
endif()

50
cmake/FindZSTD.cmake Normal file
View File

@ -0,0 +1,50 @@
#.rst:
# FindZstd
# ---------
#
# Try to locate the Zstd library.
# If found, this will define the following variables:
#
# ``ZSTD_FOUND``
# True if the zstd library is available
# ``ZSTD_INCLUDE_DIRS``
# The zstd include directories
# ``ZSTD_LIBRARIES``
# The zstd libraries for linking
#
# If ``ZSTD_FOUND`` is TRUE, it will also define the following
# imported target:
#
# ``ZSTD::ZSTD``
# The zstd library
find_package(PkgConfig)
pkg_check_modules(PC_ZSTD QUIET libzstd)
find_path(ZSTD_INCLUDE_DIRS
NAMES zstd.h
HINTS ${PC_ZSTD_INCLUDEDIR}
PATH_SUFFIXES zstd)
find_library(ZSTD_LIBRARIES
NAMES zstd zstd_static
HINTS ${PC_ZSTD_LIBDIR}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(ZSTD DEFAULT_MSG ZSTD_LIBRARIES ZSTD_INCLUDE_DIRS)
if(ZSTD_FOUND AND NOT TARGET ZSTD::ZSTD)
add_library(ZSTD::ZSTD UNKNOWN IMPORTED)
set_target_properties(ZSTD::ZSTD PROPERTIES
IMPORTED_LOCATION "${ZSTD_LIBRARIES}"
INTERFACE_INCLUDE_DIRECTORIES "${ZSTD_INCLUDE_DIRS}")
endif()
mark_as_advanced(ZSTD_INCLUDE_DIRS ZSTD_LIBRARIES)
include(FeatureSummary)
set_package_properties(ZSTD PROPERTIES
URL "https://github.com/facebook/zstd"
DESCRIPTION "ZSTD compression library")

View File

@ -0,0 +1,32 @@
# Fallback find module for double-conversion
# if double-conversion is built with CMake it'll install a config module, which we prefer
# if it's built with Scons (their default), we search ourselves
find_package(double-conversion CONFIG)
if (double-conversion_FOUND)
if(TARGET double-conversion::double-conversion)
return()
endif()
endif()
find_path(DOUBLE_CONVERSION_INCLUDE_DIR
NAMES
double-conversion.h
PATH_SUFFIXES
double-conversion
)
find_library(DOUBLE_CONVERSION_LIBRARY NAMES double-conversion)
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(
double-conversion DEFAULT_MSG
DOUBLE_CONVERSION_LIBRARY DOUBLE_CONVERSION_INCLUDE_DIR)
if(double-conversion_FOUND AND NOT TARGET double-conversion::double-conversion)
add_library(double-conversion::double-conversion UNKNOWN IMPORTED)
set_target_properties(double-conversion::double-conversion PROPERTIES
IMPORTED_LOCATION "${DOUBLE_CONVERSION_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${DOUBLE_CONVERSION_INCLUDE_DIR}")
endif()
mark_as_advanced(DOUBLE_CONVERSION_INCLUDE_DIR DOUBLE_CONVERSION_LIBRARY)

View File

@ -0,0 +1,11 @@
{
"module_name": "${target}",
"version": "${CMAKE_PROJECT_VERSION}",
"built_with": {
"compiler_id": "${CMAKE_CXX_COMPILER_ID}",
"compiler_target": "${CMAKE_CXX_COMPILER_TARGET}",
"compiler_version": "${CMAKE_CXX_COMPILER_VERSION}",
"cross_compiled": ${cross_compilation},
"target_system": "${CMAKE_SYSTEM_NAME}"
}
}

179
cmake/QtAutoDetect.cmake Normal file
View File

@ -0,0 +1,179 @@
#
# Collection of auto dection routines to improve the user eperience when
# building Qt from source.
#
# Make sure to not run detection when building standalone tests, because the detection was already
# done when initially configuring qtbase.
function(qt_auto_detect_android)
if(DEFINED CMAKE_TOOLCHAIN_FILE AND NOT DEFINED QT_AUTODETECT_ANDROID
AND NOT QT_BUILD_STANDALONE_TESTS)
file(READ ${CMAKE_TOOLCHAIN_FILE} toolchain_file_content OFFSET 0 LIMIT 80)
string(FIND ${toolchain_file_content} "The Android Open Source Project" find_result REVERSE)
if (NOT ${find_result} EQUAL -1)
set(android_detected TRUE)
else()
set(android_detected FALSE)
endif()
if(android_detected)
message(STATUS "Android toolchain file detected, checking configuration defaults...")
if(NOT DEFINED ANDROID_NATIVE_API_LEVEL)
message(STATUS "ANDROID_NATIVE_API_LEVEL was not specified, using API level 21 as default")
set(ANDROID_NATIVE_API_LEVEL 21 CACHE STRING "")
endif()
if(NOT DEFINED ANDROID_STL)
set(ANDROID_STL "c++_shared" CACHE STRING "")
endif()
endif()
set(QT_AUTODETECT_ANDROID ${android_detected} CACHE STRING "")
elseif (QT_AUTODETECT_ANDROID)
message(STATUS "Android toolchain file detected")
endif()
endfunction()
function(qt_auto_detect_vpckg)
if(DEFINED ENV{VCPKG_ROOT} AND NOT QT_BUILD_STANDALONE_TESTS)
set(vcpkg_toolchain_file "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
get_filename_component(vcpkg_toolchain_file "${vcpkg_toolchain_file}" ABSOLUTE)
if(DEFINED CMAKE_TOOLCHAIN_FILE)
get_filename_component(supplied_toolchain_file "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE)
if(NOT supplied_toolchain_file STREQUAL vcpkg_toolchain_file)
set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" CACHE STRING "")
endif()
unset(supplied_toolchain_file)
endif()
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_toolchain_file}" CACHE STRING "" FORCE)
message(STATUS "Using vcpkg from $ENV{VCPKG_ROOT}")
if(DEFINED ENV{VCPKG_DEFAULT_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{VCPKG_DEFAULT_TRIPLET}" CACHE STRING "")
message(STATUS "Using vcpkg triplet ${VCPKG_TARGET_TRIPLET}")
endif()
unset(vcpkg_toolchain_file)
message(STATUS "CMAKE_TOOLCHAIN_FILE is: ${CMAKE_TOOLCHAIN_FILE}")
if(DEFINED VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
message(STATUS "VCPKG_CHAINLOAD_TOOLCHAIN_FILE is: ${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
endif()
endif()
endfunction()
function(qt_auto_detect_ios)
if(CMAKE_SYSTEM_NAME STREQUAL iOS
OR CMAKE_SYSTEM_NAME STREQUAL watchOS
OR CMAKE_SYSTEM_NAME STREQUAL tvOS)
message(STATUS "Using internal CMake ${CMAKE_SYSTEM_NAME} toolchain file.")
# The QT_UIKIT_SDK check simulates the input.sdk condition for simulator_and_device in
# configure.json.
# If the variable is explicitly provided, assume simulator_and_device to be off.
if(QT_UIKIT_SDK)
set(simulator_and_device OFF)
elseif(QT_FORCE_SIMULATOR_AND_DEVICE)
# TODO: Once we get simulator_and_device support in upstream CMake, only then allow
# usage of simulator_and_device without forcing.
set(simulator_and_device ON)
else()
# If QT_UIKIT_SDK is not provided, default to simulator.
set(simulator_and_device OFF)
set(QT_UIKIT_SDK "iphonesimulator" CACHE "STRING" "Chosen uikit SDK.")
endif()
message(STATUS "simulator_and_device set to: \"${simulator_and_device}\".")
# Choose relevant architectures.
# Using a non xcode generator requires explicit setting of the
# architectures, otherwise compilation fails with unknown defines.
if(CMAKE_SYSTEM_NAME STREQUAL iOS)
if(simulator_and_device)
set(osx_architectures "arm64;x86_64")
elseif(QT_UIKIT_SDK STREQUAL "iphoneos")
set(osx_architectures "arm64")
elseif(QT_UIKIT_SDK STREQUAL "iphonesimulator")
set(osx_architectures "x86_64")
else()
if(NOT DEFINED QT_UIKIT_SDK)
message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
" Possible values: iphoneos, iphonesimulator.")
else()
message(FATAL_ERROR
"Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
endif()
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL tvOS)
if(simulator_and_device)
set(osx_architectures "arm64;x86_64")
elseif(QT_UIKIT_SDK STREQUAL "appletvos")
set(osx_architectures "arm64")
elseif(QT_UIKIT_SDK STREQUAL "appletvsimulator")
set(osx_architectures "x86_64")
else()
if(NOT DEFINED QT_UIKIT_SDK)
message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
" Possible values: appletvos, appletvsimulator.")
else()
message(FATAL_ERROR
"Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
endif()
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL watchOS)
if(simulator_and_device)
set(osx_architectures "armv7k;i386")
elseif(QT_UIKIT_SDK STREQUAL "watchos")
set(osx_architectures "armv7k")
elseif(QT_UIKIT_SDK STREQUAL "watchsimulator")
set(osx_architectures "i386")
else()
if(NOT DEFINED QT_UIKIT_SDK)
message(FATAL_ERROR "Please proviude a value for -DQT_UIKIT_SDK."
" Possible values: watchos, watchsimulator.")
else()
message(FATAL_ERROR
"Unknown SDK argument given to QT_UIKIT_SDK: ${QT_UIKIT_SDK}.")
endif()
endif()
endif()
# For non simulator_and_device builds, we need to explicitly set the SYSROOT aka the sdk
# value.
if(QT_UIKIT_SDK)
set(CMAKE_OSX_SYSROOT "${QT_UIKIT_SDK}" CACHE STRING "")
endif()
message(STATUS "CMAKE_OSX_SYSROOT set to: \"${CMAKE_OSX_SYSROOT}\".")
message(STATUS "CMAKE_OSX_ARCHITECTURES set to: \"${osx_architectures}\".")
set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "")
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Qt statically or dynamically" FORCE)
endif()
if(BUILD_SHARED_LIBS)
message(FATAL_ERROR
"Building Qt for ${CMAKE_SYSTEM_NAME} as shared libraries is not supported.")
endif()
endif()
endfunction()
function(qt_auto_detect_cmake_config)
if(CMAKE_CONFIGURATION_TYPES)
# Allow users to specify this option.
if(NOT QT_MULTI_CONFIG_FIRST_CONFIG)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}")
set(QT_MULTI_CONFIG_FIRST_CONFIG "${first_config_type}" PARENT_SCOPE)
endif()
set(CMAKE_TRY_COMPILE_CONFIGURATION "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config")
set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE ON PARENT_SCOPE)
set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE "${QT_MULTI_CONFIG_FIRST_CONFIG}" PARENT_SCOPE)
endif()
endif()
endfunction()
qt_auto_detect_cmake_config()
qt_auto_detect_ios()
qt_auto_detect_android()
qt_auto_detect_vpckg()

View File

@ -0,0 +1,9 @@
## Test the cmake build system:
option(BUILD_CMAKE_TESTING "Build tests for the Qt build system" OFF)
mark_as_advanced(BUILD_CMAKE_TESTING)
if(BUILD_CMAKE_TESTING)
add_subdirectory("${PROJECT_SOURCE_DIR}/cmake/tests")
endif()

View File

@ -0,0 +1,198 @@
include(CheckCXXSourceCompiles)
function(qt_run_config_test_architecture)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT
"" CACHE INTERNAL "Test variables that should be exported" FORCE)
# Compile test to find the target architecture and sub-architectures.
set(flags "")
qt_get_platform_try_compile_vars(platform_try_compile_vars)
list(APPEND flags ${platform_try_compile_vars})
try_compile(
_arch_result
"${CMAKE_CURRENT_BINARY_DIR}/config.tests/arch"
"${CMAKE_CURRENT_SOURCE_DIR}/config.tests/arch"
arch
CMAKE_FLAGS ${flags}
)
if (NOT _arch_result)
message(FATAL_ERROR "Failed to compile architecture detection file.")
endif()
set(_arch_file_suffix "${CMAKE_EXECUTABLE_SUFFIX}")
# With emscripten the application entry point is a .js file (to be run with node for example),
# but the real "data" is in the .wasm file, so that's where we need to look for the ABI, etc.
# information.
if (EMSCRIPTEN)
set(_arch_file_suffix ".wasm")
endif()
set(arch_test_location "config.tests/arch")
if(QT_MULTI_CONFIG_FIRST_CONFIG)
string(APPEND arch_test_location "/${QT_MULTI_CONFIG_FIRST_CONFIG}")
endif()
set(_arch_file
"${CMAKE_CURRENT_BINARY_DIR}/${arch_test_location}/architecture_test${_arch_file_suffix}")
if (NOT EXISTS "${_arch_file}")
message(FATAL_ERROR
"Failed to find compiled architecture detection executable at ${_arch_file}.")
endif()
message(STATUS "Extracting architecture info from ${_arch_file}.")
file(STRINGS "${_arch_file}" _arch_lines LENGTH_MINIMUM 16 LENGTH_MAXIMUM 1024 ENCODING UTF-8)
foreach (_line ${_arch_lines})
string(LENGTH "${_line}" lineLength)
string(FIND "${_line}" "==Qt=magic=Qt== Architecture:" _pos)
if (_pos GREATER -1)
math(EXPR _pos "${_pos}+29")
string(SUBSTRING "${_line}" ${_pos} -1 _architecture)
endif()
string(FIND "${_line}" "==Qt=magic=Qt== Sub-architecture:" _pos)
if (_pos GREATER -1 AND ${lineLength} GREATER 33)
math(EXPR _pos "${_pos}+34")
string(SUBSTRING "${_line}" ${_pos} -1 _sub_architecture)
string(REPLACE " " ";" _sub_architecture "${_sub_architecture}")
endif()
string(FIND "${_line}" "==Qt=magic=Qt== Build-ABI:" _pos)
if (_pos GREATER -1)
math(EXPR _pos "${_pos}+26")
string(SUBSTRING "${_line}" ${_pos} -1 _build_abi)
endif()
endforeach()
if (NOT _architecture OR NOT _build_abi)
message(FATAL_ERROR "Failed to extract architecture data from file.")
endif()
set(TEST_architecture 1 CACHE INTERNAL "Ran the architecture test")
set(TEST_architecture_arch "${_architecture}" CACHE INTERNAL "Target machine architecture")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_architecture_arch)
set(TEST_subarch 1 CACHE INTERNAL "Ran machine subArchitecture test")
foreach(it ${_sub_architecture})
# Equivalent to qmake's QT_CPU_FEATURES.$arch.
set(TEST_arch_${TEST_architecture_arch}_subarch_${it} 1 CACHE INTERNAL "Target sub architecture result")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_arch_${TEST_architecture_arch}_subarch_${it})
endforeach()
set(TEST_buildAbi "${_build_abi}" CACHE INTERNAL "Target machine buildAbi")
list(APPEND QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT TEST_buildAbi)
set(QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT ${QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT} CACHE INTERNAL "Test variables that should be exported")
list(JOIN _sub_architecture " " subarch_summary)
message(STATUS "Building for: ${QT_QMAKE_TARGET_MKSPEC} (${TEST_architecture_arch}, CPU features: ${subarch_summary})")
endfunction()
function(qt_run_config_test_posix_iconv)
set(source "#include <iconv.h>
int main(int, char **)
{
iconv_t x = iconv_open(\"\", \"\");
char *inp;
char *outp;
size_t inbytes, outbytes;
iconv(x, &inp, &inbytes, &outp, &outbytes);
iconv_close(x);
return 0;
}")
check_cxx_source_compiles("${source}" HAVE_POSIX_ICONV)
if(NOT HAVE_POSIX_ICONV)
set(_req_libraries "${CMAKE_REQUIRE_LIBRARIES}")
set(CMAKE_REQUIRE_LIBRARIES "iconv")
check_cxx_source_compiles("${source}" HAVE_POSIX_ICONV)
set(CMAKE_REQUIRE_LIBRARIES "${_req_libraries}")
if(HAVE_POSIX_ICONV)
set(TEST_iconv_needlib 1 CACHE INTERNAL "Need to link against libiconv")
endif()
endif()
set(TEST_posix_iconv "${HAVE_POSIX_ICONV}" CACHE INTERNAL "POSIX iconv")
endfunction()
function(qt_run_config_test_sun_iconv)
set(source "#include <iconv.h>
int main(int, char **)
{
iconv_t x = iconv_open(\"\", \"\");
const char *inp;
char *outp;
size_t inbytes, outbytes;
iconv(x, &inp, &inbytes, &outp, &outbytes);
iconv_close(x);
return 0;
}")
if(DARWIN)
# as per !config.darwin in configure.json
set(HAVE_SUN_ICONV OFF)
else()
check_cxx_source_compiles("${source}" HAVE_SUN_ICONV)
endif()
set(TEST_sun_iconv "${HAVE_SUN_ICONV}" CACHE INTERNAL "SUN libiconv")
endfunction()
function(qt_run_linker_version_script_support)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/version_flag.map" "VERS_1 { global: sym; };
VERS_2 { global: sym; }
VERS_1;
")
if(DEFINED CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})
else()
set(CMAKE_REQUIRED_FLAGS "")
endif()
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS} "-Wl,--version-script=\"${CMAKE_CURRENT_BINARY_DIR}/version_flag.map\"")
check_cxx_source_compiles("int main(void){return 0;}" HAVE_LD_VERSION_SCRIPT)
if(DEFINED CMAKE_REQUIRED_FLAGS_SAVE)
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
endif()
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map")
# For some reason the linker command line written by the XCode generator, which is
# subsequently executed by xcodebuild, ignores the linker flag, and thus the test
# seemingly succeeds. Explicitly disable the version script test on darwin platforms.
if(APPLE)
set(HAVE_LD_VERSION_SCRIPT OFF)
endif()
set(TEST_ld_version_script "${HAVE_LD_VERSION_SCRIPT}" CACHE INTERNAL "linker version script support")
endfunction()
function(qt_run_qtbase_config_tests)
qt_run_config_test_posix_iconv()
add_library(Iconv INTERFACE)
if(TEST_iconv_needlib)
target_link_libraries(Iconv PUBLIC iconv)
endif()
if(NOT TEST_posix_iconv)
qt_run_config_test_sun_iconv()
endif()
qt_run_config_test_architecture()
qt_run_linker_version_script_support()
endfunction()
# The qmake build of android does not perform the right architecture tests and
# forcefully disables sse4 on android x86. We have to mimic this behavior
# for now
if (CMAKE_ANDROID_ARCH_ABI STREQUAL x86)
set(QT_FEATURE_sse4_1 OFF CACHE BOOL INTERNAL FORCE)
set(QT_FEATURE_sse4_2 OFF CACHE BOOL INTERNAL FORCE)
set(TEST_subarch_sse4_1 FALSE CACHE BOOL INTERNAL FORCE)
set(TEST_subarch_sse4_2 FALSE CACHE BOOL INTERNAL FORCE)
endif()
qt_run_qtbase_config_tests()

View File

@ -0,0 +1,287 @@
## QtPlatform Target:
add_library(Platform INTERFACE)
add_library(Qt::Platform ALIAS Platform)
target_include_directories(Platform
INTERFACE
$<BUILD_INTERFACE:${QT_PLATFORM_DEFINITION_DIR_ABSOLUTE}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${QT_PLATFORM_DEFINITION_DIR}>
$<INSTALL_INTERFACE:${INSTALL_INCLUDEDIR}>
)
target_compile_definitions(Platform INTERFACE ${QT_PLATFORM_DEFINITIONS})
# When building on android we need to link against the logging library
# in order to satisfy linker dependencies. Both of these libraries are part of
# the NDK.
if (ANDROID)
target_link_libraries(Platform INTERFACE log)
endif()
set(__GlobalConfig_path_suffix "${INSTALL_CMAKE_NAMESPACE}")
qt_path_join(__GlobalConfig_build_dir ${QT_CONFIG_BUILD_DIR} ${__GlobalConfig_path_suffix})
qt_path_join(__GlobalConfig_install_dir ${QT_CONFIG_INSTALL_DIR} ${__GlobalConfig_path_suffix})
set(__GlobalConfig_install_dir_absolute "${__GlobalConfig_install_dir}")
if(QT_WILL_INSTALL)
# Need to prepend the install prefix when doing prefix builds, because the config install dir
# is relative then.
qt_path_join(__GlobalConfig_install_dir_absolute
${CMAKE_INSTALL_PREFIX} ${__GlobalConfig_install_dir_absolute})
endif()
# Generate and install Qt6 config file.
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/QtConfig.cmake.in"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}Config.cmake"
INSTALL_DESTINATION "${__GlobalConfig_install_dir}"
)
write_basic_package_version_file(
${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
# Generate and install Qt6Tools config file.
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/cmake/QtToolsConfig.cmake.in"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ToolsConfig.cmake"
INSTALL_DESTINATION "${__GlobalConfig_install_dir}"
)
write_basic_package_version_file(
${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ToolsConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
qt_install(FILES
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}Config.cmake"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ConfigVersion.cmake"
DESTINATION "${__GlobalConfig_install_dir}"
COMPONENT Devel
)
qt_install(FILES
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ToolsConfig.cmake"
"${__GlobalConfig_build_dir}/${INSTALL_CMAKE_NAMESPACE}ToolsConfigVersion.cmake"
DESTINATION "${__GlobalConfig_install_dir}Tools"
COMPONENT Devel
)
# Generate toolchain file for convenience
if(QT_HOST_PATH)
get_filename_component(init_qt_host_path "${QT_HOST_PATH}" ABSOLUTE)
set(init_qt_host_path "set(QT_HOST_PATH \"${init_qt_host_path}\" CACHE PATH \"\" FORCE)")
endif()
if(CMAKE_TOOLCHAIN_FILE)
set(init_original_toolchain_file "set(qt_chainload_toolchain_file \"${CMAKE_TOOLCHAIN_FILE}\")")
endif()
if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
list(APPEND init_vcpkg "set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE \"${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}\")")
endif()
if(VCPKG_TARGET_TRIPLET)
list(APPEND init_vcpkg "set(VCPKG_TARGET_TRIPLET \"${VCPKG_TARGET_TRIPLET}\" CACHE STRING \"\")")
endif()
# On Windows compilers aren't easily mixed. Avoid that qtbase is built using cl.exe for example and then for another
# build gcc is picked up from %PATH%. The same goes when using a custom compiler on other platforms, such as ICC.
list(APPEND init_platform "set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACHE STRING \"\")")
list(APPEND init_platform "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE STRING \"\")")
if(APPLE)
# For simulator_and_device build, we should not explicitly set the sysroot.
list(LENGTH CMAKE_OSX_ARCHITECTURES _qt_osx_architectures_count)
if(CMAKE_OSX_SYSROOT AND NOT _qt_osx_architectures_count GREATER 1 AND APPLE_UIKIT)
list(APPEND init_platform "set(CMAKE_OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\" CACHE PATH \"\")")
endif()
unset(_qt_osx_architectures_count)
if(CMAKE_OSX_DEPLOYMENT_TARGET)
list(APPEND init_platform
"set(CMAKE_OSX_DEPLOYMENT_TARGET \"${CMAKE_OSX_DEPLOYMENT_TARGET}\" CACHE STRING \"\")")
endif()
if(APPLE_UIKIT)
list(APPEND init_platform
"set(CMAKE_SYSTEM_NAME \"${CMAKE_SYSTEM_NAME}\" CACHE STRING \"\")")
set(_qt_osx_architectures_escaped "${CMAKE_OSX_ARCHITECTURES}")
string(REPLACE ";" "LITERAL_SEMICOLON"
_qt_osx_architectures_escaped "${_qt_osx_architectures_escaped}")
list(APPEND init_platform
"set(CMAKE_OSX_ARCHITECTURES \"${_qt_osx_architectures_escaped}\" CACHE STRING \"\")")
unset(_qt_osx_architectures_escaped)
endif()
elseif(ANDROID)
list(APPEND init_platform "set(ANDROID_NATIVE_API_LEVEL \"${ANDROID_NATIVE_API_LEVEL}\" CACHE STRING \"\")")
list(APPEND init_platform "set(ANDROID_STL \"${ANDROID_STL}\" CACHE STRING \"\")")
list(APPEND init_platform "set(ANDROID_ABI \"${ANDROID_ABI}\" CACHE STRING \"\")")
list(APPEND init_platform "if (NOT DEFINED ANDROID_SDK_ROOT)")
list(APPEND init_platform " set(ANDROID_SDK_ROOT \"${ANDROID_SDK_ROOT}\" CACHE STRING \"\")")
list(APPEND init_platform "endif()")
endif()
string(REPLACE ";" "\n" init_vcpkg "${init_vcpkg}")
string(REPLACE ";" "\n" init_platform "${init_platform}")
string(REPLACE "LITERAL_SEMICOLON" ";" init_platform "${init_platform}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt.toolchain.cmake.in" "${__GlobalConfig_build_dir}/qt.toolchain.cmake" @ONLY)
qt_install(FILES "${__GlobalConfig_build_dir}/qt.toolchain.cmake" DESTINATION "${__GlobalConfig_install_dir}" COMPONENT Devel)
# Also provide a convenience cmake wrapper
if(UNIX)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in" "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake" DESTINATION "${INSTALL_BINDIR}")
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in" "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake.bat" DESTINATION "${INSTALL_BINDIR}")
endif()
# Provide a private convenience wrapper with options which should not be propagated via the public
# qt-cmake wrapper e.g. CMAKE_GENERATOR.
# These options can not be set in a toolchain file, but only on the command line.
# These options should not be in the public wrapper, because a consumer of Qt might want to build
# their CMake app with the Unix Makefiles generator, while Qt should be built with the Ninja
# generator.
# The private wrapper is more conveient for building Qt itself, because a developer doesn't need
# to specify the same options for each qt module built.
set(__qt_cmake_extra "-G\"${CMAKE_GENERATOR}\"")
if(UNIX)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private" DESTINATION "${INSTALL_BINDIR}")
else()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.bat.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" @ONLY)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-private.bat" DESTINATION "${INSTALL_BINDIR}")
endif()
unset(__qt_cmake_extra)
## Library to hold global features:
## These features are stored and accessed via Qt::GlobalConfig, but the
## files always lived in Qt::Core, so we keep it that way
add_library(GlobalConfig INTERFACE)
target_include_directories(GlobalConfig INTERFACE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/QtCore>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:include/QtCore>
)
qt_feature_module_begin(NO_MODULE
PUBLIC_FILE src/corelib/global/qconfig.h
PRIVATE_FILE src/corelib/global/qconfig_p.h
)
include("${CMAKE_CURRENT_SOURCE_DIR}/configure.cmake")
# Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for
# simulator_and_device_builds.
if(APPLE_UIKIT AND NOT QT_UIKIT_SDK)
set(__QtFeature_custom_enabled_cache_variables
TEST_subarch_sse2
FEATURE_sse2
QT_FEATURE_sse2)
endif()
qt_feature_module_end(GlobalConfig OUT_VAR_PREFIX "__GlobalConfig_")
qt_generate_global_config_pri_file()
add_library(Qt::GlobalConfig ALIAS GlobalConfig)
add_library(GlobalConfigPrivate INTERFACE)
target_link_libraries(GlobalConfigPrivate INTERFACE GlobalConfig)
target_include_directories(GlobalConfigPrivate INTERFACE
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/QtCore/${PROJECT_VERSION}>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include/QtCore/${PROJECT_VERSION}/QtCore>
$<INSTALL_INTERFACE:include/QtCore/${PROJECT_VERSION}>
$<INSTALL_INTERFACE:include/QtCore/${PROJECT_VERSION}/QtCore>
)
add_library(Qt::GlobalConfigPrivate ALIAS GlobalConfigPrivate)
# defines PlatformCommonInternal PlatformModuleInternal PlatformPluginInternal PlatformToolInternal
include(QtInternalTargets)
set(__export_targets Platform
GlobalConfig
GlobalConfigPrivate
PlatformCommonInternal
PlatformModuleInternal
PlatformPluginInternal
PlatformToolInternal)
set(__export_name "${INSTALL_CMAKE_NAMESPACE}Targets")
qt_install(TARGETS ${__export_targets} EXPORT "${__export_name}")
qt_install(EXPORT ${__export_name}
NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE}::
DESTINATION "${__GlobalConfig_install_dir}")
qt_internal_export_modern_cmake_config_targets_file(TARGETS ${__export_targets}
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}
CONFIG_INSTALL_DIR
${__GlobalConfig_install_dir})
## Install some QtBase specific CMake files:
qt_copy_or_install(FILES
cmake/ModuleDescription.json.in
cmake/QtBuild.cmake
cmake/QtBuildInformation.cmake
cmake/QtCompilerFlags.cmake
cmake/QtCompilerOptimization.cmake
cmake/QtFeature.cmake
cmake/QtPlatformSupport.cmake
cmake/QtPlatformAndroid.cmake
cmake/QtPostProcess.cmake
cmake/QtSetup.cmake
cmake/QtModuleConfig.cmake.in
cmake/QtModuleDependencies.cmake.in
cmake/QtModuleToolsDependencies.cmake.in
cmake/QtModuleToolsConfig.cmake.in
cmake/QtModuleToolsVersionlessTargets.cmake.in
cmake/QtStandaloneTestsConfig.cmake.in
cmake/QtPlugins.cmake.in
cmake/QtPluginConfig.cmake.in
cmake/QtPluginDependencies.cmake.in
DESTINATION "${__GlobalConfig_install_dir}"
)
file(COPY cmake/QtFeature.cmake DESTINATION "${__GlobalConfig_build_dir}")
# TODO: Check whether this is the right place to install these
qt_copy_or_install(DIRECTORY cmake/3rdparty DESTINATION "${__GlobalConfig_install_dir}")
# Install our custom Find modules, which will be used by the find_dependency() calls
# inside the generated ModuleDependencies cmake files.
qt_copy_or_install(DIRECTORY cmake/
DESTINATION "${__GlobalConfig_install_dir}"
FILES_MATCHING PATTERN "Find*.cmake"
PATTERN "tests" EXCLUDE
PATTERN "3rdparty" EXCLUDE
)
# Configure and install the QtBuildInternals package.
set(__build_internals_path_suffix "${INSTALL_CMAKE_NAMESPACE}BuildInternals")
qt_path_join(__build_internals_build_dir ${QT_CONFIG_BUILD_DIR} ${__build_internals_path_suffix})
qt_path_join(__build_internals_install_dir ${QT_CONFIG_INSTALL_DIR}
${__build_internals_path_suffix})
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake"
"${__build_internals_build_dir}/${INSTALL_CMAKE_NAMESPACE}BuildInternalsConfig.cmake"
@ONLY
)
qt_install(FILES
"${__build_internals_build_dir}/${INSTALL_CMAKE_NAMESPACE}BuildInternalsConfig.cmake"
"${__build_internals_build_dir}/QtBuildInternalsExtra.cmake"
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtBuildInternals/QtBuildInternalsAndroid.cmake"
DESTINATION "${__build_internals_install_dir}"
COMPONENT Devel
)
# Generate the new resource API
set(QT_CORE_RESOURCE_GENERATED_FILE_NAME "${INSTALL_CMAKE_NAMESPACE}CoreResource.cmake" CACHE INTERNAL "")
set(QT_CORE_RESOURCE_GENERATED_FILE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${QT_CORE_RESOURCE_GENERATED_FILE_NAME}" CACHE INTERNAL "")
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/QtResource.cmake.in"
"${QT_CORE_RESOURCE_GENERATED_FILE_PATH}"
@ONLY
)
include(${QT_CORE_RESOURCE_GENERATED_FILE_PATH})

4056
cmake/QtBuild.cmake Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
function(qt_print_feature_summary)
include(FeatureSummary)
feature_summary(WHAT PACKAGES_FOUND
REQUIRED_PACKAGES_NOT_FOUND
RECOMMENDED_PACKAGES_NOT_FOUND
OPTIONAL_PACKAGES_NOT_FOUND
RUNTIME_PACKAGES_NOT_FOUND
FATAL_ON_MISSING_REQUIRED_PACKAGES)
endfunction()
function(qt_print_build_instructions)
if((NOT PROJECT_NAME STREQUAL "QtBase" AND
NOT PROJECT_NAME STREQUAL "Qt") OR
QT_BUILD_STANDALONE_TESTS)
return()
endif()
set(build_command "cmake --build . --parallel")
set(install_command "cmake --install .")
message("Qt is now configured for building. Just run '${build_command}'.")
if(QT_WILL_INSTALL)
message("Once everything is built, you must run '${install_command}'.")
message("Qt will be installed into '${CMAKE_INSTALL_PREFIX}'")
else()
message("Once everything is built, Qt is installed.")
message("You should NOT run '${install_command}'")
message("Note that this build cannot be deployed to other machines or devices.")
endif()
message("To configure and build other modules, you can use the following convenience script:
${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}/qt-cmake")
message("\nIf reconfiguration fails for some reason, try to remove 'CMakeCache.txt' \
from the build directory \n")
endfunction()

View File

@ -0,0 +1,217 @@
#
# Android specific functions/macros/properties required for building Qt Modules
#
define_property(TARGET
PROPERTY
QT_ANDROID_MODULE_INSTALL_DIR
BRIEF_DOCS
"Recorded install location for a Qt Module."
FULL_DOCS
"Recorded install location for a Qt Module. Used by qt_android_dependencies()."
)
define_property(TARGET
PROPERTY
QT_ANDROID_JAR_DEPENDENCIES
BRIEF_DOCS
"Qt Module Jar dependencies list."
FULL_DOCS
"Qt Module Jar dependencies list."
)
define_property(TARGET
PROPERTY
QT_ANDROID_BUNDLED_JAR_DEPENDENCIES
BRIEF_DOCS
"Qt Module Jars that should be bundled with it during packing."
FULL_DOCS
"Qt Module Jars that should be bundled with it during packing."
)
define_property(TARGET
PROPERTY
QT_ANDROID_LIB_DEPENDENCIES
BRIEF_DOCS
"Qt Module C++ libraries that should be bundled with it during packing."
FULL_DOCS
"Qt Module C++ libraries that should be bundled with it during packing."
)
define_property(TARGET
PROPERTY
QT_ANDROID_LIB_DEPENDENCY_REPLACEMENTS
BRIEF_DOCS
"Qt Module C++ libraries that can replace libraries declared with the QT_ANDROID_LIB_DEPENDENCIES property."
FULL_DOCS
"Qt Module C++ libraries that can replace libraries declared with the QT_ANDROID_LIB_DEPENDENCIES property."
)
define_property(TARGET
PROPERTY
QT_ANDROID_BUNDLED_FILES
BRIEF_DOCS
"Qt Module files that need to be bundled during packing."
FULL_DOCS
"Qt Module files that need to be bundled during packing."
)
define_property(TARGET
PROPERTY
QT_ANDROID_PERMISSIONS
BRIEF_DOCS
"Qt Module android permission list."
FULL_DOCS
"Qt Module android permission list."
)
# Generate Qt Module -android-dependencies.xml required by the
# androiddeploytoolqt to successfully copy all the plugins and other dependent
# items into tha APK
function(qt_android_dependencies target)
get_target_property(target_type "${target}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
return()
endif()
get_target_property(arg_JAR_DEPENDENCIES ${target} QT_ANDROID_JAR_DEPENDENCIES)
get_target_property(arg_BUNDLED_JAR_DEPENDENCIES ${target} QT_ANDROID_BUNDLED_JAR_DEPENDENCIES)
get_target_property(arg_LIB_DEPENDENCIES ${target} QT_ANDROID_LIB_DEPENDENCIES)
get_target_property(arg_LIB_DEPENDENCY_REPLACEMENTS ${target} QT_ANDROID_LIB_DEPENDENCY_REPLACEMENTS)
get_target_property(arg_BUNDLED_FILES ${target} QT_ANDROID_BUNDLED_FILES)
get_target_property(arg_PERMISSIONS ${target} QT_ANDROID_PERMISSIONS)
get_target_property(module_plugins ${target} MODULE_PLUGIN_TYPES)
if ((NOT module_plugins)
AND (NOT arg_JAR_DEPENDENCIES)
AND (NOT arg_LIB_DEPENDENCY_REPLACEMENTS)
AND (NOT arg_LIB_DEPENDENCIES)
AND (NOT arg_BUNDLED_JAR_DEPENDENCIES)
AND (NOT arg_PERMISSIONS)
AND (NOT arg_BUNDLED_FILES))
# None of the values were set, so there's nothing to do
return()
endif()
get_target_property(target_output_name ${target} OUTPUT_NAME)
if (NOT target_output_name)
set(target_name ${target})
else()
set(target_name ${target_output_name})
endif()
# mimic qmake's section and string splitting from
# mkspecs/feature/qt_android_deps.prf
macro(section string delimiter first second)
string(FIND ${string} ${delimiter} delimiter_location)
if (NOT ${delimiter_location} EQUAL -1)
string(SUBSTRING ${string} 0 ${delimiter_location} ${first})
math(EXPR delimiter_location "${delimiter_location} + 1")
string(SUBSTRING ${string} ${delimiter_location} -1 ${second})
else()
set(${first} ${string})
set(${second} "")
endif()
endmacro()
get_target_property(target_bin_dir ${target} BINARY_DIR)
set(dependency_file "${target_bin_dir}/${target_name}_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml")
set(file_contents "<rules><dependencies>\n")
string(APPEND file_contents "<lib name=\"${target_name}_${CMAKE_ANDROID_ARCH_ABI}\"><depends>\n")
# Jar Dependencies
if(arg_JAR_DEPENDENCIES)
foreach(jar_dependency IN LISTS arg_JAR_DEPENDENCIES)
section(${jar_dependency} ":" jar_file init_class)
if (init_class)
set(init_class "initClass=\"${init_class}\"")
endif()
file(TO_NATIVE_PATH ${jar_file} jar_file_native)
string(APPEND file_contents "<jar file=\"${jar_file_native}\" ${init_class} />\n")
endforeach()
endif()
# Bundled Jar Dependencies
if(arg_BUNDLED_JAR_DEPENDENCIES)
foreach(jar_bundle IN LISTS arg_BUNDLED_JAR_DEPENDENCIES)
section(${jar_bundle} ":" bundle_file init_calss)
if (init_class)
set(init_class "initClass=\"${init_class}\"")
endif()
file(TO_NATIVE_PATH ${jar_bundle} jar_bundle_native)
string(APPEND file_contents "<jar bundling=\"1\" file=\"${jar_bundle_native}\" ${init_class} />\n")
endforeach()
endif()
# Lib Dependencies
if(arg_LIB_DEPENDENCIES)
foreach(lib IN LISTS arg_LIB_DEPENDENCIES)
string(REPLACE ".so" "_${CMAKE_ANDROID_ARCH_ABI}.so" lib ${lib})
section(${lib} ":" lib_file lib_extends)
if (lib_extends)
set(lib_extends "extends=\"${lib_extends}\"")
endif()
file(TO_NATIVE_PATH ${lib_file} lib_file_native)
string(APPEND file_contents "<lib file=\"${lib_file_native}\" ${lib_extends} />\n")
endforeach()
endif()
# Lib Dependencies Replacements
if(arg_LIB_DEPENDENCY_REPLACEMENTS)
foreach(lib IN LISTS arg_LIB_DEPENDENCY_REPLACEMENTS)
string(REPLACE ".so" "_${CMAKE_ANDROID_ARCH_ABI}.so" lib ${lib})
section(${lib} ":" lib_file lib_replacement)
if (lib_replacement)
file(TO_NATIVE_PATH ${lib_replacement} lib_replacement_native)
set(lib_replacement "replaces=\"${lib_replacement_native}\"")
endif()
file(TO_NATIVE_PATH ${lib_file} lib_file_native)
string(APPEND file_contents "<lib file=\"${lib_file_native}\" ${lib_replacement} />\n")
endforeach()
endif()
# Bundled files
if(arg_BUNDLED_FILES)
foreach(file IN LISTS arg_BUNDLED_FILES)
file(TO_NATIVE_PATH ${lib_file} file_native)
string(APPEND file_contents "<bundled file=\"${file_native}\" />\n")
endforeach()
endif()
# Module plugins
if(module_plugins)
foreach(plugin IN LISTS module_plugins)
string(APPEND file_contents "<bundled file=\"plugins/${plugin}\" />\n")
endforeach()
endif()
# Android Permissions
if(arg_PERMISSIONS)
foreach(permission IN LISTS arg_PERMISSIONS)
string(APPEND file_contents "<permission name=\"${permission}\" />\n")
endforeach()
endif()
string(APPEND file_contents "</depends></lib>")
string(APPEND file_contents "</dependencies></rules>\n")
file(WRITE ${dependency_file} ${file_contents})
get_target_property(target_install_dir ${target} QT_ANDROID_MODULE_INSTALL_DIR)
if (NOT target_install_dir)
message(SEND_ERROR "qt_android_dependencies: Target ${target} is either not a Qt Module or has no recorded install location")
return()
endif()
# Copy file into install directory, required by the androiddeployqt tool.
qt_install(FILES
${dependency_file}
DESTINATION
${target_install_dir}
COMPONENT
Devel)
endfunction()

View File

@ -0,0 +1,237 @@
if (CMAKE_VERSION VERSION_LESS 3.1.0)
message(FATAL_ERROR "Qt requires at least CMake version 3.1.0")
endif()
######################################
#
# Macros for building Qt modules
#
######################################
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake")
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake)
endif()
macro(qt_set_up_build_internals_paths)
# Set up the paths for the cmake modules located in the prefix dir. Prepend, so the paths are
# least important compared to the source dir ones, but more important than command line
# provided ones.
set(QT_CMAKE_MODULE_PATH "${QT_BUILD_INTERNALS_PATH}/../${QT_CMAKE_EXPORT_NAMESPACE}")
list(PREPEND CMAKE_MODULE_PATH "${QT_CMAKE_MODULE_PATH}")
# Prepend the qtbase source cmake directory to CMAKE_MODULE_PATH,
# so that if a change is done in cmake/QtBuild.cmake, it gets automatically picked up when
# building qtdeclarative, rather than having to build qtbase first (which will copy
# QtBuild.cmake to the build dir). This is similar to qmake non-prefix builds, where the
# source qtbase/mkspecs directory is used.
if(EXISTS "${QT_SOURCE_TREE}/cmake")
list(PREPEND CMAKE_MODULE_PATH "${QT_SOURCE_TREE}/cmake")
endif()
# If the repo has its own cmake modules, include those in the module path.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
endif()
# Find the cmake files when doing a standalone tests build.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
endif()
endmacro()
# Set up the build internal paths unless explicitly requested not to.
if(NOT QT_BUILD_INTERNALS_SKIP_CMAKE_MODULE_PATH_ADDITION)
qt_set_up_build_internals_paths()
endif()
# Define some constants to check for certain platforms, etc.
# Needs to be loaded before qt_repo_build() to handle require() clauses before even starting a repo
# build.
include(QtPlatformSupport)
macro(qt_build_repo_begin)
# Qt specific setup common for all modules:
include(QtSetup)
include(FeatureSummary)
# Optionally include a repo specific Setup module.
include(${PROJECT_NAME}Setup OPTIONAL)
include(QtRepoSetup OPTIONAL)
# Find Apple frameworks if needed.
qt_find_apple_system_frameworks()
# Decide whether tools will be built.
qt_check_if_tools_will_be_built()
string(TOLOWER ${PROJECT_NAME} project_name_lower)
set(qt_docs_target_name docs_${project_name_lower})
set(qt_docs_prepare_target_name prepare_docs_${project_name_lower})
set(qt_docs_generate_target_name generate_docs_${project_name_lower})
set(qt_docs_html_target_name html_docs_${project_name_lower})
set(qt_docs_qch_target_name qch_docs_${project_name_lower})
set(qt_docs_install_html_target_name install_html_docs_${project_name_lower})
set(qt_docs_install_qch_target_name install_qch_docs_${project_name_lower})
set(qt_docs_install_target_name install_docs_${project_name_lower})
add_custom_target(${qt_docs_target_name})
add_custom_target(${qt_docs_prepare_target_name})
add_custom_target(${qt_docs_generate_target_name})
add_custom_target(${qt_docs_qch_target_name})
add_custom_target(${qt_docs_html_target_name})
add_custom_target(${qt_docs_install_html_target_name})
add_custom_target(${qt_docs_install_qch_target_name})
add_custom_target(${qt_docs_install_target_name})
add_dependencies(${qt_docs_generate_target_name} ${qt_docs_prepare_target_name})
add_dependencies(${qt_docs_html_target_name} ${qt_docs_generate_target_name})
add_dependencies(${qt_docs_target_name} ${qt_docs_html_target_name} ${qt_docs_qch_target_name})
add_dependencies(${qt_docs_install_html_target_name} ${qt_docs_html_target_name})
add_dependencies(${qt_docs_install_qch_target_name} ${qt_docs_qch_target_name})
add_dependencies(${qt_docs_install_target_name} ${qt_docs_install_html_target_name} ${qt_docs_install_qch_target_name})
endmacro()
macro(qt_build_repo_end)
include(QtBuildInformation)
if(NOT QT_BUILD_STANDALONE_TESTS)
# Delayed actions on some of the Qt targets:
include(QtPostProcess)
# Install the repo-specific cmake find modules.
qt_path_join(__qt_repo_install_dir ${QT_CONFIG_INSTALL_DIR} ${INSTALL_CMAKE_NAMESPACE})
if(NOT PROJECT_NAME STREQUAL "QtBase")
if (EXISTS cmake)
qt_copy_or_install(DIRECTORY cmake/
DESTINATION "${__qt_repo_install_dir}"
FILES_MATCHING PATTERN "Find*.cmake"
)
endif()
endif()
if(NOT QT_SUPERBUILD)
qt_print_feature_summary()
endif()
endif()
if(NOT QT_SUPERBUILD)
qt_print_build_instructions()
endif()
endmacro()
macro(qt_build_repo)
qt_build_repo_begin(${ARGN})
# If testing is enabled, try to find the qtbase Test package.
# Do this before adding src, because there might be test related conditions
# in source.
if (BUILD_TESTING AND NOT QT_BUILD_STANDALONE_TESTS)
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Test)
endif()
if(NOT QT_BUILD_STANDALONE_TESTS)
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/CMakeLists.txt")
add_subdirectory(src)
endif()
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tools/CMakeLists.txt")
add_subdirectory(tools)
endif()
endif()
if (BUILD_TESTING AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
add_subdirectory(tests)
if(QT_NO_MAKE_TESTS)
set_property(DIRECTORY tests PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()
endif()
qt_build_repo_end()
if (BUILD_EXAMPLES AND BUILD_SHARED_LIBS
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt"
AND NOT QT_BUILD_STANDALONE_TESTS)
add_subdirectory(examples)
if(QT_NO_MAKE_EXAMPLES)
set_property(DIRECTORY examples PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()
endif()
endmacro()
macro(qt_set_up_standalone_tests_build)
# Remove this macro once all usages of it have been removed.
# Standalone tests are not handled via the main repo project and qt_build_tests.
endmacro()
macro(qt_build_tests)
if(QT_BUILD_STANDALONE_TESTS)
# Find location of TestsConfig.cmake. These contain the modules that need to be
# find_package'd when testing.
set(_qt_build_tests_install_prefix
"${QT_CONFIG_INSTALL_DIR}/${INSTALL_CMAKE_NAMESPACE}BuildInternals/StandaloneTests")
if(QT_WILL_INSTALL)
qt_path_join(_qt_build_tests_install_prefix
${CMAKE_INSTALL_PREFIX} ${_qt_build_tests_install_prefix})
endif()
include("${_qt_build_tests_install_prefix}/${PROJECT_NAME}TestsConfig.cmake" OPTIONAL)
# Of course we always need the test module as well.
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Test)
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/auto/CMakeLists.txt")
add_subdirectory(auto)
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/CMakeLists.txt" AND QT_BUILD_BENCHMARKS)
add_subdirectory(benchmarks)
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manual/CMakeLists.txt")
add_subdirectory(manual)
endif()
endmacro()
macro(qt_examples_build_begin)
# Examples that are built as part of the Qt build need to use the CMake config files from the
# build dir, because they are not installed yet in a prefix build.
# Appending to CMAKE_PREFIX_PATH helps find the initial Qt6Config.cmake.
# Appending to QT_EXAMPLES_CMAKE_PREFIX_PATH helps find components of Qt6, because those
# find_package calls use NO_DEFAULT_PATH, and thus CMAKE_PREFIX_PATH is ignored.
list(APPEND CMAKE_PREFIX_PATH "${QT_BUILD_DIR}")
list(APPEND QT_EXAMPLES_CMAKE_PREFIX_PATH "${QT_BUILD_DIR}")
# Also make sure the CMake config files do not recreate the already-existing targets
set(QT_NO_CREATE_TARGETS TRUE)
set(BACKUP_CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE})
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "BOTH")
endmacro()
macro(qt_examples_build_end)
# We use AUTOMOC/UIC/RCC in the examples. Make sure to not fail on a fresh Qt build, that e.g. the moc binary does not exist yet.
# This function gets all targets below this directory
function(get_all_targets _result _dir)
get_property(_subdirs DIRECTORY "${_dir}" PROPERTY SUBDIRECTORIES)
foreach(_subdir IN LISTS _subdirs)
get_all_targets(${_result} "${_subdir}")
endforeach()
get_property(_sub_targets DIRECTORY "${_dir}" PROPERTY BUILDSYSTEM_TARGETS)
set(${_result} ${${_result}} ${_sub_targets} PARENT_SCOPE)
endfunction()
get_all_targets(targets "${CMAKE_CURRENT_SOURCE_DIR}")
foreach(target ${targets})
qt_autogen_tools(${target} ENABLE_AUTOGEN_TOOLS "moc" "rcc")
if(TARGET Qt::Widgets)
qt_autogen_tools(${target} ENABLE_AUTOGEN_TOOLS "uic")
endif()
endforeach()
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ${BACKUP_CMAKE_FIND_ROOT_PATH_MODE_PACKAGE})
endmacro()
if (ANDROID)
include(${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsAndroid.cmake)
endif()

View File

@ -0,0 +1,37 @@
# Propagate common variables via BuildInternals package.
set(QT_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
option(BUILD_SHARED_LIBS "Build Qt statically or dynamically" @BUILD_SHARED_LIBS@)
set(QT_CMAKE_EXPORT_NAMESPACE @QT_CMAKE_EXPORT_NAMESPACE@)
set(INSTALL_CMAKE_NAMESPACE @INSTALL_CMAKE_NAMESPACE@)
set(QT_BUILD_INTERNALS_PATH "${CMAKE_CURRENT_LIST_DIR}")
# Propagate the original install prefix, so that a developer building a child module can
# specify CMAKE_PREFIX_PATH for finding the Qt modules instead of CMAKE_INSTALL_PREFIX.
set(CMAKE_INSTALL_PREFIX @CMAKE_INSTALL_PREFIX@ CACHE PATH
"Install path prefix, prepended onto install directories." FORCE)
# Propagate developer builds to other modules via BuildInternals package.
if(@FEATURE_developer_build@)
set(FEATURE_developer_build ON CACHE BOOL "Developer build." FORCE)
endif()
# Propagate non-prefix builds.
set(QT_WILL_INSTALL @QT_WILL_INSTALL@ CACHE BOOL
"Boolean indicating if doing a Qt prefix build (vs non-prefix build)." FORCE)
set(QT_SOURCE_TREE "@QT_SOURCE_TREE@" CACHE PATH
"A path to the source tree of the previously configured QtBase project." FORCE)
# Propagate decision of building tests and examples to other repositories.
set(BUILD_TESTING @BUILD_TESTING@ CACHE BOOL "Build the testing tree.")
set(BUILD_EXAMPLES @BUILD_EXAMPLES@ CACHE BOOL "Build Qt examples")
set(QT_NO_MAKE_TESTS @QT_NO_MAKE_TESTS@ CACHE BOOL
"Should tests be built as part of the default 'all' target.")
set(QT_NO_MAKE_EXAMPLES @QT_NO_MAKE_EXAMPLES@ CACHE BOOL
"Should examples be built as part of the default 'all' target.")
# Propagate usage of ccache.
set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache")
# Extra set of exported variables
@QT_EXTRA_BUILD_INTERNALS_VARS@

View File

@ -0,0 +1,6 @@
# Set warnings. All compilers except MSVC support -Wall -Wextra
if (MSVC)
add_compile_options(/W3)
else()
add_compile_options(-Wall -Wextra)
endif()

View File

@ -0,0 +1,123 @@
if (QCC)
set(QT_CFLAGS_SSE2 "-msse2")
set(QT_CFLAGS_SSE3 "-msse3")
set(QT_CFLAGS_SSSE3 "-mssse3")
set(QT_CFLAGS_SSE4_1 "-msse4.1")
set(QT_CFLAGS_SSE4_2 "-msse4.2")
set(QT_CFLAGS_AVX "-mavx")
set(QT_CFLAGS_AVX2 "-mavx2")
set(QT_CFLAGS_AESNI "-maes")
set(QT_CFLAGS_SHANI "-msha")
endif()
if (MSVC)
if (QT_64BIT)
# SSE2 is mandatory on 64-bit mode, so skip the option. It triggers:
# cl : Command line warning D9002 : ignoring unknown option '-arch:SSE2'
set(QT_CFLAGS_SSE2 "")
else()
set(QT_CFLAGS_SSE2 "-arch:SSE2")
endif()
set(QT_CFLAGS_SSE3 "${QT_CFLAGS_SSE2}")
set(QT_CFLAGS_SSSE3 "${QT_CFLAGS_SSE2}")
set(QT_CFLAGS_SSE4_1 "${QT_CFLAGS_SSE2}")
set(QT_CFLAGS_SSE4_2 "${QT_CFLAGS_SSE2}")
set(QT_CFLAGS_AESNI "${QT_CFLAGS_SSE2}")
set(QT_CFLAGS_SHANI "${QT_CFLAGS_SSE2}")
# FIXME to be Visual Studio version specific, like in mkspecs/common/msvc-version.conf
set(QT_CFLAGS_AVX "-arch:AVX")
set(QT_CFLAGS_AVX2 "-arch:AVX2")
set(QT_CFLAGS_F16C "-arch:AVX")
set(QT_CFLAGS_RDRND "")
set(QT_CFLAGS_AVX512F "-arch:AVX512")
set(QT_CFLAGS_AVX512ER "-arch:AVX512")
set(QT_CFLAGS_AVX512CD "-arch:AVX512")
set(QT_CFLAGS_AVX512PF "-arch:AVX512")
set(QT_CFLAGS_AVX512DQ "-arch:AVX512")
set(QT_CFLAGS_AVX512BW "-arch:AVX512")
set(QT_CFLAGS_AVX512VL "-arch:AVX512")
set(QT_CFLAGS_AVX512IFMA "-arch:AVX512")
set(QT_CFLAGS_AVX512VBMI "-arch:AVX512")
endif()
if(GCC OR CLANG)
set(QT_CFLAGS_SSE2 "-msse2")
set(QT_CFLAGS_SSE3 "-msse3")
set(QT_CFLAGS_SSSE3 "-mssse3")
set(QT_CFLAGS_SSE4_1 "-msse4.1")
set(QT_CFLAGS_SSE4_2 "-msse4.2")
set(QT_CFLAGS_F16C "-mf16c")
set(QT_CFLAGS_RDRND "-mrdrnd")
set(QT_CFLAGS_AVX "-mavx")
set(QT_CFLAGS_AVX2 "-mavx2")
set(QT_CFLAGS_AVX512F "-mavx512f")
set(QT_CFLAGS_AVX512ER "-mavx512er")
set(QT_CFLAGS_AVX512CD "-mavx512cd")
set(QT_CFLAGS_AVX512PF "-mavx512pf")
set(QT_CFLAGS_AVX512DQ "-mavx512dq")
set(QT_CFLAGS_AVX512BW "-mavx512bw")
set(QT_CFLAGS_AVX512VL "-mavx512vl")
set(QT_CFLAGS_AVX512IFMA "-mavx512ifma")
set(QT_CFLAGS_AVX512VBMI "-mavx512vbmi")
set(QT_CFLAGS_AESNI "-maes")
set(QT_CFLAGS_SHANI "-msha")
if(NOT APPLE_UIKIT)
set(QT_CFLAGS_NEON "-mfpu=neon")
endif()
set(QT_CFLAGS_MIPS_DSP "-mdsp")
set(QT_CFLAGS_MIPS_DSPR2 "-mdspr2")
endif()
if (winrt) # FIXME: Correct variable
set(QT_CFLAGS_SSE2 "-arch:SSE2")
set(QT_CFLAGS_SSE3 "-arch:SSE2")
set(QT_CFLAGS_SSSE3 "-arch:SSE2")
set(QT_CFLAGS_SSE4_1 "-arch:SSE2")
set(QT_CFLAGS_SSE4_2 "-arch:SSE2")
set(QT_CFLAGS_AVX "-arch:AVX")
set(QT_CFLAGS_AVX2 "-arch:AVX")
set(QT_CFLAGS_AESNI "-arch:SSE2")
set(QT_CFLAGS_SHANI "-arch:SSE2")
endif()
if (ICC)
if (MSVC)
set(QT_CFLAGS_SSE2 "-QxSSE2")
set(QT_CFLAGS_SSE3 "-QxSSE3")
set(QT_CFLAGS_SSSE3 "-QxSSSE3")
set(QT_CFLAGS_SSE4_1 "-QxSSE4.1")
set(QT_CFLAGS_SSE4_2 "-QxSSE4.2")
set(QT_CFLAGS_AVX "-QxAVX")
set(QT_CFLAGS_AVX2 "-QxCORE-AVX2")
set(QT_CFLAGS_AVX512F "-QxCOMMON-AVX512")
set(QT_CFLAGS_AVX512CD "-QxCOMMON-AVX512")
set(QT_CFLAGS_AVX512ER "-QxMIC-AVX512")
set(QT_CFLAGS_AVX512PF "-QxMIC-AVX512")
set(QT_CFLAGS_AVX512DQ "-QxCORE-AVX512")
set(QT_CFLAGS_AVX512BW "-QxCORE-AVX512")
set(QT_CFLAGS_AVX512VL "-QxCORE-AVX512")
set(QT_CFLAGS_F16C "${QT_CFLAGS_AVX2}")
set(QT_CFLAGS_AESNI "-QxSSE2")
set(QT_CFLAGS_SHANI "-QxSSE4.2")
else()
set(QT_CFLAGS_SSE2 "-msse2")
set(QT_CFLAGS_SSE3 "-msse3")
set(QT_CFLAGS_SSSE3 "-mssse3")
set(QT_CFLAGS_SSE4_1 "-msse4.1")
set(QT_CFLAGS_SSE4_2 "-msse4.2")
set(QT_CFLAGS_AVX "-march=core-avx")
set(QT_CFLAGS_AVX2 "-march=core-avx2")
set(QT_CFLAGS_AVX512F "-march=broadwell -xCOMMON-AVX512")
set(QT_CFLAGS_AVX512CD "-march=broadwell -xCOMMON-AVX512")
set(QT_CFLAGS_AVX512ER "-march=knl")
set(QT_CFLAGS_AVX512PF "-march=knl")
set(QT_CFLAGS_AVX512DQ "-march=skylake-avx512")
set(QT_CFLAGS_AVX512BW "-march=skylake-avx512")
set(QT_CFLAGS_AVX512VL "-march=skylake-avx512")
set(QT_CFLAGS_AESNI "-maes")
set(QT_CFLAGS_F16C "${QT_CFLAGS_AVX2}")
set(QT_CFLAGS_RDRND "-mrdrnd")
set(QT_CFLAGS_SHANI "-msha")
endif()
endif()

59
cmake/QtConfig.cmake.in Normal file
View File

@ -0,0 +1,59 @@
@PACKAGE_INIT@
# Slightly amended version of ./src/corelib/Qt6Config.cmake.in
if (CMAKE_VERSION VERSION_LESS 3.1.0)
message(FATAL_ERROR "Qt requires at least CMake version 3.1.0")
endif()
get_filename_component(_qt_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
set(_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir "${CMAKE_CURRENT_LIST_DIR}")
if (NOT QT_NO_CREATE_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@Targets.cmake")
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@VersionlessTargets.cmake")
endif()
else()
# For examples using `find_package(...)` inside their CMakeLists.txt files:
# Make CMake's AUTOGEN detect this Qt version properly
set_directory_properties(PROPERTIES
QT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
QT_VERSION_MINOR @PROJECT_VERSION_MINOR@
QT_VERSION_PATCH @PROJECT_VERSION_PATCH@)
endif()
# if (NOT @INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS)
# set(@INSTALL_CMAKE_NAMESPACE@_NOT_FOUND_MESSAGE "The Qt package requires at least one component")
# set(@INSTALL_CMAKE_NAMESPACE@_FOUND False)
# return()
# endif()
get_filename_component(_qt_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_qt_import_prefix "${_qt_import_prefix}" REALPATH)
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}")
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/extra-cmake-modules/find-modules")
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/3rdparty/kwin")
foreach(module ${@INSTALL_CMAKE_NAMESPACE@_FIND_COMPONENTS})
find_package(@INSTALL_CMAKE_NAMESPACE@${module}
${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_QUIET}
${_@INSTALL_CMAKE_NAMESPACE@_FIND_PARTS_REQUIRED}
PATHS ${_qt_cmake_dir} ${QT_EXAMPLES_CMAKE_PREFIX_PATH} NO_DEFAULT_PATH
)
if (NOT @INSTALL_CMAKE_NAMESPACE@${module}_FOUND)
string(CONFIGURE ${_qt5_module_location_template} _expected_module_location @ONLY)
if (@INSTALL_CMAKE_NAMESPACE@_FIND_REQUIRED_${module})
set(_Qt_NOTFOUND_MESSAGE "${_Qt_NOTFOUND_MESSAGE}Failed to find Qt component \"${module}\" config file at \"${_expected_module_location}\"\n")
elseif(NOT @INSTALL_CMAKE_NAMESPACE@_FIND_QUIETLY)
message(WARNING "Failed to find Qt component \"${module}\" config file at \"${_expected_module_location}\"")
endif()
unset(_expected_module_location)
endif()
endforeach()
if (_Qt_NOTFOUND_MESSAGE)
set(@INSTALL_CMAKE_NAMESPACE@_NOT_FOUND_MESSAGE "${_Qt_NOTFOUND_MESSAGE}")
set(@INSTALL_CMAKE_NAMESPACE@_FOUND False)
endif()

760
cmake/QtFeature.cmake Normal file
View File

@ -0,0 +1,760 @@
function(qt_feature_module_begin)
qt_parse_all_arguments(arg "qt_feature_module_begin"
"NO_MODULE" "LIBRARY;PRIVATE_FILE;PUBLIC_FILE" "PUBLIC_DEPENDENCIES;PRIVATE_DEPENDENCIES" ${ARGN})
if ("${arg_LIBRARY}" STREQUAL "" AND (NOT ${arg_NO_MODULE}))
message(FATAL_ERROR "qt_feature_begin_module needs a LIBRARY name! (or specify NO_MODULE)")
endif()
if ("${arg_PUBLIC_FILE}" STREQUAL "")
message(FATAL_ERROR "qt_feature_begin_module needs a PUBLIC_FILE name!")
endif()
if ("${arg_PRIVATE_FILE}" STREQUAL "")
message(FATAL_ERROR "qt_feature_begin_module needs a PRIVATE_FILE name!")
endif()
set(__QtFeature_library "${arg_LIBRARY}" PARENT_SCOPE)
set(__QtFeature_public_features "" PARENT_SCOPE)
set(__QtFeature_private_features "" PARENT_SCOPE)
set(__QtFeature_internal_features "" PARENT_SCOPE)
set(__QtFeature_private_file "${arg_PRIVATE_FILE}" PARENT_SCOPE)
set(__QtFeature_public_file "${arg_PUBLIC_FILE}" PARENT_SCOPE)
set(__QtFeature_private_extra "" PARENT_SCOPE)
set(__QtFeature_public_extra "" PARENT_SCOPE)
set(__QtFeature_config_definitions "" PARENT_SCOPE)
set(__QtFeature_define_definitions "" PARENT_SCOPE)
endfunction()
function(qt_feature_normalize_name name out_var)
# Normalize the feature name to something CMake can deal with.
if(name MATCHES "c\\+\\+")
string(REGEX REPLACE "[^a-zA-Z0-9_]" "x" name "${name}")
else()
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" name "${name}")
endif()
set(${out_var} "${name}" PARENT_SCOPE)
endfunction()
function(qt_feature feature)
set(original_name "${feature}")
qt_feature_normalize_name("${feature}" feature)
set_property(GLOBAL PROPERTY QT_FEATURE_ORIGINAL_NAME_${feature} "${original_name}")
qt_parse_all_arguments(arg "qt_feature"
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;" "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" ${ARGN})
set(_QT_FEATURE_DEFINITION_${feature} ${ARGN} PARENT_SCOPE)
# Register feature for future use:
if (arg_PUBLIC)
list(APPEND __QtFeature_public_features "${feature}")
endif()
if (arg_PRIVATE)
list(APPEND __QtFeature_private_features "${feature}")
endif()
if (NOT arg_PUBLIC AND NOT arg_PRIVATE)
list(APPEND __QtFeature_internal_features "${feature}")
endif()
set(__QtFeature_public_features ${__QtFeature_public_features} PARENT_SCOPE)
set(__QtFeature_private_features ${__QtFeature_private_features} PARENT_SCOPE)
set(__QtFeature_internal_features ${__QtFeature_internal_features} PARENT_SCOPE)
endfunction()
function(qt_evaluate_to_boolean expressionVar)
if(${${expressionVar}})
set(${expressionVar} ON PARENT_SCOPE)
else()
set(${expressionVar} OFF PARENT_SCOPE)
endif()
endfunction()
function(qt_evaluate_config_expression resultVar)
set(result "")
set(nestingLevel 0)
set(skipNext OFF)
set(expression "${ARGN}")
list(LENGTH expression length)
math(EXPR length "${length}-1")
foreach(memberIdx RANGE ${length})
if(${skipNext})
set(skipNext OFF)
continue()
endif()
list(GET expression ${memberIdx} member)
if("${member}" STREQUAL "(")
if(${nestingLevel} GREATER 0)
list(APPEND result ${member})
endif()
math(EXPR nestingLevel "${nestingLevel} + 1")
continue()
elseif("${member}" STREQUAL ")")
math(EXPR nestingLevel "${nestingLevel} - 1")
if(nestingLevel LESS 0)
break()
endif()
if(${nestingLevel} EQUAL 0)
qt_evaluate_config_expression(result ${result})
else()
list(APPEND result ${member})
endif()
continue()
elseif(${nestingLevel} GREATER 0)
list(APPEND result ${member})
continue()
elseif("${member}" STREQUAL "NOT")
list(APPEND result ${member})
continue()
elseif("${member}" STREQUAL "AND")
qt_evaluate_to_boolean(result)
if(NOT ${result})
break()
endif()
set(result "")
elseif("${member}" STREQUAL "OR")
qt_evaluate_to_boolean(result)
if(${result})
break()
endif()
set(result "")
elseif("${member}" STREQUAL "STREQUAL" AND memberIdx LESS ${length})
# Unfortunately the semantics for STREQUAL in if() are broken when the
# RHS is an empty string and the parameters to if are coming through a variable.
# So we expect people to write the empty string with single quotes and then we
# do the comparison manually here.
list(LENGTH result lhsIndex)
math(EXPR lhsIndex "${lhsIndex}-1")
list(GET result ${lhsIndex} lhs)
list(REMOVE_AT result ${lhsIndex})
set(lhs "${${lhs}}")
math(EXPR rhsIndex "${memberIdx}+1")
set(skipNext ON)
list(GET expression ${rhsIndex} rhs)
# We can't pass through an empty string with double quotes through various
# stages of substitution, so instead it is represented using single quotes
# and resolve here.
string(REGEX REPLACE "'(.*)'" "\\1" rhs "${rhs}")
string(COMPARE EQUAL "${lhs}" "${rhs}" stringCompareResult)
list(APPEND result ${stringCompareResult})
else()
string(FIND "${member}" "QT_FEATURE_" idx)
if(idx EQUAL 0)
# Remove the QT_FEATURE_ prefix
string(SUBSTRING "${member}" 11 -1 feature)
qt_evaluate_feature(${feature})
endif()
list(APPEND result ${member})
endif()
endforeach()
# The 'TARGET Gui' case is handled by qt_evaluate_to_boolean, by passing those tokens verbatim
# to if().
if("${result}" STREQUAL "")
set(result ON)
else()
qt_evaluate_to_boolean(result)
endif()
set(${resultVar} ${result} PARENT_SCOPE)
endfunction()
function(qt_feature_set_cache_value resultVar feature emit_if calculated label)
if (DEFINED "FEATURE_${feature}")
# Must set up the cache
if (NOT (emit_if))
message(FATAL_ERROR "Sanity check failed: FEATURE_${feature} that was not emitted was found in the CMakeCache.")
endif()
# Revisit value:
set(cache "${FEATURE_${feature}}")
set(booly_values OFF NO FALSE N ON YES TRUE Y)
if ((cache IN_LIST booly_values) OR (cache GREATER_EQUAL 0))
set(result "${cache}")
else()
message(FATAL_ERROR "Sanity check failed: FEATURE_${feature} has invalid value \"${cache}\"!")
endif()
# Fix-up user-provided values
set("FEATURE_${feature}" "${cache}" CACHE BOOL "${label}")
else()
# Initial setup:
if (emit_if)
set("FEATURE_${feature}" "${calculated}" CACHE BOOL "${label}")
set(result "${calculated}")
else()
set(result OFF)
endif()
endif()
set("${resultVar}" "${result}" PARENT_SCOPE)
endfunction()
macro(qt_feature_set_value feature cache emit_if condition label)
set(result "${cache}")
if (NOT (condition) AND (cache))
message(SEND_ERROR "Feature \"${feature}\": Forcing to \"${cache}\" breaks its condition.")
endif()
if (DEFINED "QT_FEATURE_${feature}")
message(FATAL_ERROR "Feature ${feature} is already defined when evaluating configure.cmake features for ${target}.")
endif()
set(QT_FEATURE_${feature} "${result}" CACHE INTERNAL "Qt feature: ${feature}")
endmacro()
function(qt_evaluate_feature feature)
# If the feature was set explicitly by the user to be on or off, in the cache, then
# there's nothing for us to do.
if(DEFINED "QT_FEATURE_${feature}")
return()
endif()
if(NOT DEFINED _QT_FEATURE_DEFINITION_${feature})
qt_debug_print_variables(DEDUP MATCH "^QT_FEATURE")
message(FATAL_ERROR "Attempting to evaluate feature ${feature} but its definition is missing. Either the feature does not exist or a dependency to the module that defines it is missing")
endif()
cmake_parse_arguments(arg
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;" "AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF" ${_QT_FEATURE_DEFINITION_${feature}})
if(DEFINED QT_FEATURE_${feature})
return()
endif()
if("${arg_ENABLE}" STREQUAL "")
set(arg_ENABLE OFF)
endif()
if("${arg_DISABLE}" STREQUAL "")
set(arg_DISABLE OFF)
endif()
if("${arg_AUTODETECT}" STREQUAL "")
set(arg_AUTODETECT ON)
endif()
if("${arg_CONDITION}" STREQUAL "")
set(condition ON)
else()
qt_evaluate_config_expression(condition ${arg_CONDITION})
endif()
qt_evaluate_config_expression(disable_result ${arg_DISABLE})
qt_evaluate_config_expression(enable_result ${arg_ENABLE})
if(${disable_result})
set(result OFF)
elseif((${enable_result}) OR (${arg_AUTODETECT}))
set(result ${condition})
else()
# feature not auto-detected and not explicitly enabled
set(result OFF)
endif()
if("${arg_EMIT_IF}" STREQUAL "")
set(emit_if ON)
else()
qt_evaluate_config_expression(emit_if ${arg_EMIT_IF})
endif()
if (NOT (condition) AND (calculated))
message(FATAL_ERROR "Sanity check failed: Feature ${feature} is enabled but condition does not hold true.")
endif()
qt_feature_set_cache_value(cache "${feature}" "${emit_if}" "${result}" "${arg_LABEL}")
qt_feature_set_value("${feature}" "${cache}" "${emit_if}" "${condition}" "${arg_LABEL}")
endfunction()
function(qt_feature_config feature config_var_name)
qt_feature_normalize_name("${feature}" feature)
qt_parse_all_arguments(arg "qt_feature_config" "NEGATE" "NAME" "" ${ARGN})
# Store all the config related info in a unique variable key.
set(key_name "_QT_FEATURE_CONFIG_DEFINITION_${feature}_${config_var_name}")
set(${key_name} "FEATURE;${feature};CONFIG_VAR_NAME;${config_var_name};${ARGN}" PARENT_SCOPE)
# Store the key for later evaluation.
list(APPEND __QtFeature_config_definitions "${key_name}")
set(__QtFeature_config_definitions ${__QtFeature_config_definitions} PARENT_SCOPE)
endfunction()
function(qt_evaluate_qmake_config_values key)
if(NOT DEFINED ${key})
qt_debug_print_variables(DEDUP MATCH "^_QT_FEATURE_CONFIG_DEFINITION")
message(FATAL_ERROR
"Attempting to evaluate feature config ${key} but its definition is missing. ")
endif()
cmake_parse_arguments(arg
"NEGATE"
"FEATURE;NAME;CONFIG_VAR_NAME"
"" ${${key}})
set(expected "NOT")
if (arg_NEGATE)
set(expected "")
endif()
# If no custom name is specified, then the config value is the same as the feature name.
if(NOT arg_NAME)
set(arg_NAME "${arg_FEATURE}")
endif()
# The feature condition is false, there is no need to export any config values.
if(${expected} ${QT_FEATURE_${arg_FEATURE}})
return()
endif()
if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PUBLIC_CONFIG")
list(APPEND __QtFeature_qmake_public_config "${arg_NAME}")
set(__QtFeature_qmake_public_config "${__QtFeature_qmake_public_config}" PARENT_SCOPE)
endif()
if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PRIVATE_CONFIG")
list(APPEND __QtFeature_qmake_private_config "${arg_NAME}")
set(__QtFeature_qmake_private_config "${__QtFeature_qmake_private_config}" PARENT_SCOPE)
endif()
if(arg_CONFIG_VAR_NAME STREQUAL "QMAKE_PUBLIC_QT_CONFIG")
list(APPEND __QtFeature_qmake_public_qt_config "${arg_NAME}")
set(__QtFeature_qmake_public_qt_config "${__QtFeature_qmake_public_qt_config}" PARENT_SCOPE)
endif()
endfunction()
function(qt_feature_definition feature name)
qt_feature_normalize_name("${feature}" feature)
qt_parse_all_arguments(arg "qt_feature_definition" "NEGATE" "VALUE" "" ${ARGN})
# Store all the define related info in a unique variable key.
set(key_name "_QT_FEATURE_DEFINE_DEFINITION_${feature}_${name}")
set(${key_name} "FEATURE;${feature};NAME;${name};${ARGN}" PARENT_SCOPE)
# Store the key for later evaluation and subsequent define generation:
list(APPEND __QtFeature_define_definitions "${key_name}")
set(__QtFeature_define_definitions ${__QtFeature_define_definitions} PARENT_SCOPE)
endfunction()
function(qt_evaluate_feature_definition key)
if(NOT DEFINED ${key})
qt_debug_print_variables(DEDUP MATCH "^_QT_FEATURE_DEFINE_DEFINITION")
message(FATAL_ERROR "Attempting to evaluate feature define ${key} but its definition is missing. ")
endif()
cmake_parse_arguments(arg
"NEGATE;"
"FEATURE;NAME;VALUE;" "" ${${key}})
set(expected ON)
if (arg_NEGATE)
set(expected OFF)
endif()
set(msg "")
if(QT_FEATURE_${arg_FEATURE} STREQUAL expected)
if (arg_VALUE)
string(APPEND msg "#define ${arg_NAME} ${arg_VALUE}\n")
else()
string(APPEND msg "#define ${arg_NAME}\n")
endif()
string(APPEND __QtFeature_public_extra "${msg}")
endif()
set(__QtFeature_public_extra ${__QtFeature_public_extra} PARENT_SCOPE)
endfunction()
function(qt_extra_definition name value)
qt_parse_all_arguments(arg "qt_extra_definition" "PUBLIC;PRIVATE" "" "" ${ARGN})
if (arg_PUBLIC)
string(APPEND __QtFeature_public_extra "\n#define ${name} ${value}\n")
elseif(arg_PRIVATE)
string(APPEND __QtFeature_private_extra "\n#define ${name} ${value}\n")
endif()
set(__QtFeature_public_extra ${__QtFeature_public_extra} PARENT_SCOPE)
set(__QtFeature_private_extra ${__QtFeature_private_extra} PARENT_SCOPE)
endfunction()
function(qt_internal_generate_feature_line line feature)
if (QT_FEATURE_${feature} STREQUAL "ON")
set(line "#define QT_FEATURE_${feature} 1\n\n" PARENT_SCOPE)
elseif(QT_FEATURE_${feature} STREQUAL "OFF")
set(line "#define QT_FEATURE_${feature} -1\n\n" PARENT_SCOPE)
elseif(QT_FEATURE_${feature} STREQUAL "UNSET")
set(line "#define QT_FEATURE_${feature} 0\n\n" PARENT_SCOPE)
else()
message(FATAL_ERROR "${feature} has unexpected value \"${QT_FEATURE_${feature}}\"!")
endif()
endfunction()
function(qt_internal_feature_write_file file features extra)
message("Generating file ${file}.")
set(contents "")
foreach(it ${features})
qt_internal_generate_feature_line(line "${it}")
string(APPEND contents "${line}")
endforeach()
string(APPEND contents "${extra}")
file(GENERATE OUTPUT "${file}" CONTENT "${contents}")
endfunction()
function(qt_feature_module_end)
set(flags)
set(options OUT_VAR_PREFIX)
set(multiopts)
cmake_parse_arguments(arg "${flags}" "${options}" "${multiopts}" ${ARGN})
set(target ${arg_UNPARSED_ARGUMENTS})
# The value of OUT_VAR_PREFIX is used as a prefix for output variables that should be
# set in the parent scope.
if(NOT arg_OUT_VAR_PREFIX)
set(arg_OUT_VAR_PREFIX "")
endif()
set(all_features ${__QtFeature_public_features} ${__QtFeature_private_features} ${__QtFeature_internal_features})
list(REMOVE_DUPLICATES all_features)
foreach(feature ${all_features})
qt_evaluate_feature(${feature})
endforeach()
# Evaluate custom cache assignments.
foreach(cache_var_name ${__QtFeature_custom_enabled_cache_variables})
set(${cache_var_name} ON CACHE BOOL "Force enabled by platform." FORCE)
endforeach()
foreach(cache_var_name ${__QtFeature_custom_disabled_cache_variables})
set(${cache_var_name} OFF CACHE BOOL "Force disabled by platform." FORCE)
endforeach()
set(enabled_public_features "")
set(disabled_public_features "")
set(enabled_private_features "")
set(disabled_private_features "")
foreach(feature ${__QtFeature_public_features})
if(QT_FEATURE_${feature})
list(APPEND enabled_public_features ${feature})
else()
list(APPEND disabled_public_features ${feature})
endif()
endforeach()
foreach(feature ${__QtFeature_private_features})
if(QT_FEATURE_${feature})
list(APPEND enabled_private_features ${feature})
else()
list(APPEND disabled_private_features ${feature})
endif()
endforeach()
foreach(key ${__QtFeature_config_definitions})
qt_evaluate_qmake_config_values(${key})
unset(${key} PARENT_SCOPE)
endforeach()
foreach(key ${__QtFeature_define_definitions})
qt_evaluate_feature_definition(${key})
unset(${key} PARENT_SCOPE)
endforeach()
foreach(feature ${all_features})
unset(_QT_FEATURE_DEFINITION_${feature} PARENT_SCOPE)
endforeach()
qt_internal_feature_write_file("${CMAKE_CURRENT_BINARY_DIR}/${__QtFeature_private_file}"
"${__QtFeature_private_features}" "${__QtFeature_private_extra}"
)
qt_internal_feature_write_file("${CMAKE_CURRENT_BINARY_DIR}/${__QtFeature_public_file}"
"${__QtFeature_public_features}" "${__QtFeature_public_extra}"
)
# Extra header injections which have to have forwarding headers created by
# qt_install_injections.
# Skip creating forwarding headers if qt_feature_module_begin was called with NO_MODULE, aka
# there is no include/<module_name> so there's no place to put the forwarding headers.
if(__QtFeature_library)
set(injections "")
qt_compute_injection_forwarding_header("${__QtFeature_library}"
SOURCE "${__QtFeature_public_file}"
OUT_VAR injections)
qt_compute_injection_forwarding_header("${__QtFeature_library}"
SOURCE "${__QtFeature_private_file}" PRIVATE
OUT_VAR injections)
set(${arg_OUT_VAR_PREFIX}extra_library_injections ${injections} PARENT_SCOPE)
endif()
if (NOT ("${target}" STREQUAL "NO_MODULE"))
get_target_property(targetType "${target}" TYPE)
if("${targetType}" STREQUAL "INTERFACE_LIBRARY")
set(propertyPrefix "INTERFACE_")
else()
set(propertyPrefix "")
set_target_properties("${target}" PROPERTIES EXPORT_PROPERTIES "QT_ENABLED_PUBLIC_FEATURES;QT_DISABLED_PUBLIC_FEATURES;QT_ENABLED_PRIVATE_FEATURES;QT_DISABLED_PRIVATE_FEATURES;MODULE_PLUGIN_TYPES;QT_PLUGINS;QT_QMAKE_PUBLIC_CONFIG;QT_QMAKE_PRIVATE_CONFIG;QT_QMAKE_PUBLIC_QT_CONFIG")
endif()
foreach(visibility public private)
string(TOUPPER "${visibility}" capitalVisibility)
foreach(state enabled disabled)
string(TOUPPER "${state}" capitalState)
set_property(TARGET "${target}" PROPERTY ${propertyPrefix}QT_${capitalState}_${capitalVisibility}_FEATURES "${${state}_${visibility}_features}")
endforeach()
endforeach()
set_property(TARGET "${target}"
PROPERTY ${propertyPrefix}QT_QMAKE_PUBLIC_CONFIG
"${__QtFeature_qmake_public_config}")
set_property(TARGET "${target}"
PROPERTY ${propertyPrefix}QT_QMAKE_PRIVATE_CONFIG
"${__QtFeature_qmake_private_config}")
set_property(TARGET "${target}"
PROPERTY ${propertyPrefix}QT_QMAKE_PUBLIC_QT_CONFIG
"${__QtFeature_qmake_public_qt_config}")
# Config values were the old-school features before actual configure.json features were
# implemented. Therefore "CONFIG+=foo" values should be considered features as well,
# so that CMake can find them when building qtmultimedia for example.
if(__QtFeature_qmake_public_config)
set_property(TARGET "${target}"
APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PUBLIC_FEATURES
${__QtFeature_qmake_public_config})
endif()
if(__QtFeature_qmake_private_config)
set_property(TARGET "${target}"
APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PRIVATE_FEATURES
${__QtFeature_qmake_private_config})
endif()
if(__QtFeature_qmake_public_qt_config)
set_property(TARGET "${target}"
APPEND PROPERTY ${propertyPrefix}QT_ENABLED_PUBLIC_FEATURES
${__QtFeature_qmake_public_qt_config})
endif()
qt_feature_copy_global_config_features_to_core(${target})
endif()
unset(__QtFeature_library PARENT_SCOPE)
unset(__QtFeature_public_features PARENT_SCOPE)
unset(__QtFeature_private_features PARENT_SCOPE)
unset(__QtFeature_internal_features PARENT_SCOPE)
unset(__QtFeature_private_file PARENT_SCOPE)
unset(__QtFeature_public_file PARENT_SCOPE)
unset(__QtFeature_private_extra PARENT_SCOPE)
unset(__QtFeature_public_extra PARENT_SCOPE)
unset(__QtFeature_define_definitions PARENT_SCOPE)
unset(__QtFeature_custom_enabled_features PARENT_SCOPE)
unset(__QtFeature_custom_disabled_features PARENT_SCOPE)
endfunction()
function(qt_feature_copy_global_config_features_to_core target)
# CMake doesn't support setting custom properties on exported INTERFACE libraries
# See https://gitlab.kitware.com/cmake/cmake/issues/19261.
# To circumvent that, copy the properties from GlobalConfig to Core target.
# This way the global features actually get set in the generated CoreTargets.cmake file.
if(target STREQUAL Core)
foreach(visibility public private)
string(TOUPPER "${visibility}" capitalVisibility)
foreach(state enabled disabled)
string(TOUPPER "${state}" capitalState)
set(core_property_name "QT_${capitalState}_${capitalVisibility}_FEATURES")
set(global_property_name "INTERFACE_${core_property_name}")
get_property(core_values TARGET Core PROPERTY ${core_property_name})
get_property(global_values TARGET GlobalConfig PROPERTY ${global_property_name})
set(total_values ${core_values} ${global_values})
set_property(TARGET Core PROPERTY ${core_property_name} ${total_values})
endforeach()
endforeach()
set(config_property_names
QT_QMAKE_PUBLIC_CONFIG QT_QMAKE_PRIVATE_CONFIG QT_QMAKE_PUBLIC_QT_CONFIG )
foreach(property_name ${config_property_names})
set(core_property_name "${property_name}")
set(global_property_name "INTERFACE_${core_property_name}")
get_property(core_values TARGET Core PROPERTY ${core_property_name})
get_property(global_values TARGET GlobalConfig PROPERTY ${global_property_name})
set(total_values ${core_values} ${global_values})
set_property(TARGET Core PROPERTY ${core_property_name} ${total_values})
endforeach()
endif()
endfunction()
function(qt_config_compile_test name)
if(DEFINED "TEST_${name}")
return()
endif()
cmake_parse_arguments(arg "" "LABEL;PROJECT_PATH;C_STANDARD;CXX_STANDARD" "LIBRARIES;CODE" ${ARGN})
if(arg_PROJECT_PATH)
message(STATUS "Performing Test ${arg_LABEL}")
try_compile(HAVE_${name} "${CMAKE_BINARY_DIR}/config.tests/${name}" "${arg_PROJECT_PATH}"
"${name}")
if(${HAVE_${name}})
set(status_label "Success")
else()
set(status_label "Failed")
endif()
message(STATUS "Performing Test ${arg_LABEL} - ${status_label}")
else()
foreach(library IN ITEMS ${arg_LIBRARIES})
if(NOT TARGET "${library}")
# If the dependency looks like a cmake target, then make this compile test
# fail instead of cmake abort later via CMAKE_REQUIRED_LIBRARIES.
string(FIND "${library}" "::" cmake_target_namespace_separator)
if(NOT cmake_target_namespace_separator EQUAL -1)
set(HAVE_${name} FALSE)
break()
endif()
endif()
endforeach()
if(NOT DEFINED HAVE_${name})
set(_save_CMAKE_C_STANDARD "${CMAKE_C_STANDARD}")
set(_save_CMAKE_CXX_STANDARD "${CMAKE_CXX_STANDARD}")
if(arg_C_STANDARD)
set(CMAKE_C_STANDARD "${arg_C_STANDARD}")
endif()
if(arg_CXX_STANDARD)
set(CMAKE_CXX_STANDARD "${arg_CXX_STANDARD}")
endif()
set(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
set(CMAKE_REQUIRED_LIBRARIES "${arg_LIBRARIES}")
check_cxx_source_compiles("${arg_UNPARSED_ARGUMENTS} ${arg_CODE}" HAVE_${name})
set(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}")
set(CMAKE_C_STANDARD "${_save_CMAKE_C_STANDARD}")
set(CMAKE_CXX_STANDARD "${_save_CMAKE_CXX_STANDARD}")
endif()
endif()
set(TEST_${name} "${HAVE_${name}}" CACHE INTERNAL "${arg_LABEL}")
endfunction()
# This function should be used for passing required try compile platform variables to the
# project-based try_compile() call.
# out_var will be a list of -Dfoo=bar strings, suitable to pass to CMAKE_FLAGS.
function(qt_get_platform_try_compile_vars out_var)
# Use the regular variables that are used for source-based try_compile() calls.
set(flags "${CMAKE_TRY_COMPILE_PLATFORM_VARIABLES}")
# Pass toolchain files.
if(CMAKE_TOOLCHAIN_FILE)
list(APPEND flags "CMAKE_TOOLCHAIN_FILE")
endif()
if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
list(APPEND flags "VCPKG_CHAINLOAD_TOOLCHAIN_FILE")
endif()
# Assemble the list with regular options.
set(flags_cmd_line "")
foreach(flag ${flags})
if(${flag})
list(APPEND flags_cmd_line "-D${flag}=${${flag}}")
endif()
endforeach()
# Pass darwin specific options.
if(APPLE_UIKIT)
if(CMAKE_OSX_ARCHITECTURES)
list(GET CMAKE_OSX_ARCHITECTURES 0 osx_first_arch)
# Do what qmake does, aka when doing a simulator_and_device build, build the
# target architecture test only with the first given architecture, which should be the
# device architecture, aka some variation of "arm" (armv7, arm64).
list(APPEND flags_cmd_line "-DCMAKE_OSX_ARCHITECTURES:STRING=${osx_first_arch}")
endif()
# Also specify the sysroot, but only if not doing a simulator_and_device build.
# So keep the sysroot empty for simulator_and_device builds.
if(QT_UIKIT_SDK)
list(APPEND flags_cmd_line "-DCMAKE_OSX_SYSROOT:STRING=${QT_UIKIT_SDK}")
endif()
endif()
set("${out_var}" "${flags_cmd_line}" PARENT_SCOPE)
endfunction()
function(qt_config_compile_test_x86simd extension label)
if (DEFINED TEST_X86SIMD_${extension})
return()
endif()
set(flags "-DSIMD:string=${extension}")
qt_get_platform_try_compile_vars(platform_try_compile_vars)
list(APPEND flags ${platform_try_compile_vars})
message(STATUS "Performing SIMD Test ${label}")
try_compile("TEST_X86SIMD_${extension}"
"${CMAKE_CURRENT_BINARY_DIR}/config.tests/x86_simd_${extension}"
"${CMAKE_CURRENT_SOURCE_DIR}/config.tests/x86_simd"
x86_simd
CMAKE_FLAGS ${flags})
if(${TEST_X86SIMD_${extension}})
set(status_label "Success")
else()
set(status_label "Failed")
endif()
message(STATUS "Performing SIMD Test ${label} - ${status_label}")
set(TEST_subarch_${extension} "${TEST_X86SIMD_${extension}}" CACHE INTERNAL "${label}")
endfunction()
function(qt_make_features_available target)
if(NOT "${target}" MATCHES "^${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-Z][a-zA-Z0-9_-]*$")
message(FATAL_ERROR "${target} does not match ${QT_CMAKE_EXPORT_NAMESPACE}::[a-zA-Z][a-zA-Z0-9_-]*. INVALID NAME.")
endif()
if(NOT TARGET ${target})
message(FATAL_ERROR "${target} not found.")
endif()
get_target_property(target_type "${target}" TYPE)
if("${target_type}" STREQUAL "INTERFACE_LIBRARY")
set(property_prefix "INTERFACE_")
else()
set(property_prefix "")
endif()
foreach(visibility IN ITEMS PUBLIC PRIVATE)
set(value ON)
foreach(state IN ITEMS ENABLED DISABLED)
get_target_property(features "${target}" ${property_prefix}QT_${state}_${visibility}_FEATURES)
if("${features}" STREQUAL "features-NOTFOUND")
continue()
endif()
foreach(feature IN ITEMS ${features})
if (DEFINED "QT_FEATURE_${feature}" AND NOT "${QT_FEATURE_${feature}}" STREQUAL "${value}")
message(FATAL_ERROR "Feature ${feature} is already defined and has a different value when importing features from ${target}.")
endif()
set(QT_FEATURE_${feature} "${value}" CACHE INTERNAL "Qt feature: ${feature} (from target ${target})")
endforeach()
set(value OFF)
endforeach()
endforeach()
endfunction()

View File

@ -0,0 +1,114 @@
function(qt_internal_set_warnings_are_errors_flags target)
set(flags "")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# Regular clang 3.0+
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "3.0.0")
list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
# using AppleClang
# Apple clang 4.0+
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "4.0.0" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL "9.2")
list(APPEND flags -Werror -Wno-error=\#warnings -Wno-error=deprecated-declarations)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
list(APPEND flags -Werror -Wno-error=cpp -Wno-error=deprecated-declarations)
# GCC prints this bogus warning, after it has inlined a lot of code
# error: assuming signed overflow does not occur when assuming that (X + c) < X is always false
list(APPEND flags -Wno-error=strict-overflow)
# GCC 7 includes -Wimplicit-fallthrough in -Wextra, but Qt is not yet free of implicit fallthroughs.
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "7.0.0")
list(APPEND flags -Wno-error=implicit-fallthrough)
endif()
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0.0")
# GCC 9 introduced these but we are not clean for it.
list(APPEND flags -Wno-error=deprecated-copy -Wno-error=redundant-move -Wno-error=init-list-lifetime)
endif()
# Work-around for bug https://code.google.com/p/android/issues/detail?id=58135
if (ANDROID)
list(APPEND flags -Wno-error=literal-suffix)
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# Intel CC 13.0 +, on Linux only
if (LINUX)
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "13.0.0")
# 177: function "entity" was declared but never referenced
# (too aggressive; ICC reports even for functions created due to template instantiation)
# 1224: #warning directive
# 1478: function "entity" (declared at line N) was declared deprecated
# 1786: function "entity" (declared at line N of "file") was declared deprecated ("message")
# 1881: argument must be a constant null pointer value
# (NULL in C++ is usually a literal 0)
list(APPEND flags -Werror -ww177,1224,1478,1786,1881)
endif()
endif()
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# In qmake land, currently warnings as errors are only enabled for
# MSVC 2012, 2013, 2015.
# Respectively MSVC_VERRSIONs are: 1700-1799, 1800-1899, 1900-1909.
if(MSVC_VERSION GREATER_EQUAL 1700 AND MSVC_VERSION LESS_EQUAL 1909)
list(APPEND flags /WX)
endif()
endif()
set(add_flags "$<NOT:$<BOOL:$<TARGET_PROPERTY:QT_SKIP_WARNINGS_ARE_ERRORS>>>")
set(flags_generator_expression "$<${add_flags}:${flags}>")
target_compile_options("${target}" INTERFACE "${flags_generator_expression}")
endfunction()
add_library(PlatformCommonInternal INTERFACE)
add_library(Qt::PlatformCommonInternal ALIAS PlatformCommonInternal)
add_library(PlatformModuleInternal INTERFACE)
add_library(Qt::PlatformModuleInternal ALIAS PlatformModuleInternal)
target_link_libraries(PlatformModuleInternal INTERFACE PlatformCommonInternal)
add_library(PlatformPluginInternal INTERFACE)
add_library(Qt::PlatformPluginInternal ALIAS PlatformPluginInternal)
target_link_libraries(PlatformPluginInternal INTERFACE PlatformCommonInternal)
add_library(PlatformToolInternal INTERFACE)
add_library(Qt::PlatformToolInternal ALIAS PlatformToolInternal)
target_link_libraries(PlatformToolInternal INTERFACE PlatformCommonInternal)
if(WARNINGS_ARE_ERRORS)
qt_internal_set_warnings_are_errors_flags(PlatformModuleInternal)
qt_internal_set_warnings_are_errors_flags(PlatformPluginInternal)
qt_internal_set_warnings_are_errors_flags(PlatformToolInternal)
endif()
if(WIN32)
# Needed for M_PI define. Same as mkspecs/features/qt_module.prf.
# It's set for every module being built, but it's not propagated to user apps.
target_compile_definitions(PlatformModuleInternal INTERFACE _USE_MATH_DEFINES)
endif()
if(FEATURE_largefile AND UNIX)
target_compile_definitions(PlatformModuleInternal
INTERFACE "_LARGEFILE64_SOURCE;_LARGEFILE_SOURCE")
endif()
# We can't use the gold linker on android with the NDK, which is the default
# linker. To build our own target we will use the lld linker.
if (ANDROID)
target_link_options(PlatformModuleInternal INTERFACE -fuse-ld=lld)
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
target_compile_definitions(PlatformCommonInternal INTERFACE QT_NO_DEBUG)
endif()
if(APPLE_UIKIT)
# Do what mkspecs/features/uikit/default_pre.prf does, aka enable sse2 for
# simulator_and_device_builds.
if(FEATURE_simulator_and_device)
# Setting the definition on PlatformCommonInternal behaves slightly differently from what
# is done in qmake land. This way the define is not propagated to tests, examples, or
# user projects built with qmake, but only modules, plugins and tools.
# TODO: Figure out if this ok or not (sounds ok to me).
target_compile_definitions(PlatformCommonInternal INTERFACE QT_COMPILER_SUPPORTS_SSE2)
endif()
endif()

View File

@ -0,0 +1,68 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
# Extra cmake code begin
@extra_cmake_code@
# Extra cmake code end
# Find required dependencies, if any.
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
endif()
if (NOT QT_NO_CREATE_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
endif()
endif()
foreach(extra_cmake_include @extra_cmake_includes@)
include("${CMAKE_CURRENT_LIST_DIR}/${extra_cmake_include}")
endforeach()
include(${_qt_@PROJECT_VERSION_MAJOR@_config_cmake_dir}/QtFeature.cmake)
qt_make_features_available(@QT_CMAKE_EXPORT_NAMESPACE@::@target@)
set("@INSTALL_CMAKE_NAMESPACE@@target@_FOUND" TRUE)
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Plugins.cmake")
endif()
list(APPEND QT_ALL_MODULES_FOUND_VIA_FIND_PACKAGE "@target@")
get_target_property(_qt_module_target_type "@INSTALL_CMAKE_NAMESPACE@::@target@" TYPE)
if(NOT _qt_module_target_type STREQUAL "INTERFACE_LIBRARY")
get_target_property(_qt_module_plugin_types
@INSTALL_CMAKE_NAMESPACE@::@target@ MODULE_PLUGIN_TYPES)
if(_qt_module_plugin_types)
list(APPEND QT_ALL_PLUGIN_TYPES_FOUND_VIA_FIND_PACKAGE "${_qt_module_plugin_types}")
endif()
endif()
# Apply meta types properties
if (@QT_MODULE_HAS_META_TYPES_FILE@)
if (NOT QT_NO_CREATE_TARGETS)
set_target_properties("@INSTALL_CMAKE_NAMESPACE@::@target@" PROPERTIES
INTERFACE_QT_MODULE_HAS_META_TYPES TRUE
INTERFACE_QT_META_TYPES_INSTALL_FILE "@QT_MODULE_META_TYPES_FILE@"
INTERFACE_QT_META_TYPES_INSTALL_DEP_FILE "@QT_MODULE_META_TYPES_DEP_FILE@"
)
endif()
if (NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
get_target_property(is_alias_target "Qt::@target@" ALIASED_TARGET)
if (NOT is_alias_target)
set_target_properties("Qt::@target@" PROPERTIES
INTERFACE_QT_MODULE_HAS_META_TYPES TRUE
INTERFACE_QT_META_TYPES_INSTALL_FILE "@QT_MODULE_META_TYPES_FILE@"
INTERFACE_QT_META_TYPES_INSTALL_DEP_FILE "@QT_MODULE_META_TYPES_DEP_FILE@"
)
endif()
endif()
endif()

View File

@ -0,0 +1,66 @@
# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;"
set(_third_party_deps "@third_party_deps@")
foreach(_target_dep ${_third_party_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
list(GET _target_dep 2 components)
set(find_package_args "${pkg}")
if(version)
list(APPEND find_package_args "${version}")
endif()
if(components)
string(REPLACE " " ";" components "${components}")
find_dependency(${find_package_args} COMPONENTS ${components})
else()
find_dependency(${find_package_args})
endif()
if (NOT ${pkg}_FOUND)
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
return()
endif()
endforeach()
# Find Qt tool package.
set(_tool_deps "@main_module_tool_deps@")
# The tools do not provide linkage targets but executables, where a mismatch
# between 32-bit target and 64-bit host does not matter.
set(BACKUP_CMAKE_SIZEOF_VOID_P "${CMAKE_SIZEOF_VOID_P}")
set(CMAKE_SIZEOF_VOID_P "")
foreach(_target_dep ${_tool_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
find_dependency(${pkg} ${version})
if (NOT ${pkg}_FOUND)
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
set(CMAKE_SIZEOF_VOID_P "${BACKUP_CMAKE_SIZEOF_VOID_P}")
return()
endif()
endforeach()
set(CMAKE_SIZEOF_VOID_P "${BACKUP_CMAKE_SIZEOF_VOID_P}")
# note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0"
set(_target_deps "@target_deps@")
foreach(_target_dep ${_target_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
if (NOT ${pkg}_FOUND)
find_dependency(${pkg} ${version}
PATHS "${CMAKE_CURRENT_LIST_DIR}/.." ${QT_EXAMPLES_CMAKE_PREFIX_PATH} NO_DEFAULT_PATH
)
endif()
if (NOT ${pkg}_FOUND)
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
return()
endif()
endforeach()

View File

@ -0,0 +1,17 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
if (NOT QT_NO_CREATE_TARGETS)
# Find required dependencies, if any.
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Dependencies.cmake")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
endif()
endif()
@extra_cmake_statements@

View File

@ -0,0 +1,16 @@
# Find "ModuleTools" dependencies, which are other ModuleTools packages.
set(_tool_deps "@package_deps@")
foreach(_target_dep ${_tool_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
if (NOT ${pkg}_FOUND)
find_dependency(${pkg} ${version})
endif()
if (NOT ${pkg}_FOUND)
set(@INSTALL_CMAKE_NAMESPACE@@target@_FOUND FALSE)
return()
endif()
endforeach()

View File

@ -0,0 +1,23 @@
foreach(__qt_tool @tool_targets_non_prefixed@)
if(NOT TARGET Qt::${__qt_tool} AND TARGET Qt6::${__qt_tool})
add_executable(Qt::${__qt_tool} IMPORTED)
# Check all the usual imported location properties to find one that contains a path.
foreach(__qt_imported_location_config
IMPORTED_LOCATION
IMPORTED_LOCATION_RELEASE
IMPORTED_LOCATION_RELWITHDEBINFO
IMPORTED_LOCATION_MINSIZEREL
IMPORTED_LOCATION_DEBUG)
get_target_property(__qt_imported_location
Qt6::${__qt_tool} ${__qt_imported_location_config})
if(__qt_imported_location AND EXISTS "${__qt_imported_location}")
break()
endif()
endforeach()
set_target_properties(Qt::${__qt_tool}
PROPERTIES IMPORTED_LOCATION "${__qt_imported_location}")
endif()
endforeach()

View File

@ -0,0 +1,378 @@
#
# Self contained Platform Settings for Android
#
# Note: This file is used both by the internal and public builds.
#
#
# Public variables:
# QT_ANDROID_JAR
# Location of the adroid sdk jar for java code
# QT_ANDROID_APIVERSION
# Android API version
# QT_ANDROID_SDK_BUILD_TOOLS_VERSION
# Detected Android sdk build tools version
#
# Public functions:
#
# qt_android_generate_deployment_settings()
# Generate the deployment settings json file for a cmake target.
#
if (NOT DEFINED ANDROID_SDK_ROOT)
message(FATAL_ERROR "Please provide the location of the Android SDK directory via -DANDROID_SDK_ROOT=<path to Adndroid SDK>")
endif()
if (NOT IS_DIRECTORY "${ANDROID_SDK_ROOT}")
message(FATAL_ERROR "Could not find ANDROID_SDK_ROOT or path is not a directory: ${ANDROID_SDK_ROOT}")
endif()
# Get the Android SDK jar for an API version other than the one specified with
# QT_ANDROID_API_VERSION.
function(qt_get_android_sdk_jar_for_api api out_jar_location)
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${api}/android.jar")
if (NOT EXISTS "${jar_location}")
message(WARNING "Could not locate Android SDK jar for api '${api}', defaulting to ${QT_ANDROID_API_VERSION}")
set(${out_jar_location} ${QT_ANDROID_JAR} PARENT_SCOPE)
else()
set(${out_jar_location} ${jar_location} PARENT_SCOPE)
endif()
endfunction()
# Minimum recommend android SDK api version
set(QT_ANDROID_API_VERSION "android-21")
# Locate android.jar
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_VERSION}/android.jar")
if(NOT EXISTS "${QT_ANDROID_JAR}")
# Locate the highest available platform
file(GLOB android_platforms
LIST_DIRECTORIES true
RELATIVE "${ANDROID_SDK_ROOT}/platforms"
"${ANDROID_SDK_ROOT}/platforms/*")
# If list is not empty
if(android_platforms)
list(SORT android_platforms)
list(REVERSE android_platforms)
list(GET android_platforms 0 android_platform_latest)
set(QT_ANDROID_API_VERSION ${android_platform_latest})
set(QT_ANDROID_JAR "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_VERSION}/android.jar")
endif()
endif()
if(NOT EXISTS "${QT_ANDROID_JAR}")
message(FATAL_ERROR "No suitable Android SDK platform found. Minimum version is ${QT_ANDROID_API_VERSION}")
endif()
message(STATUS "Using Android SDK API ${QT_ANDROID_API_VERSION} from ${ANDROID_SDK_ROOT}/platforms")
# Locate Java
include(UseJava)
# Find JDK 8.0
find_package(Java 1.8 COMPONENTS Development REQUIRED)
# Locate newest android sdk build tools
if (NOT QT_ANDROID_SDK_BUILD_TOOLS_VERSION)
file(GLOB android_build_tools
LIST_DIRECTORIES true
RELATIVE "${ANDROID_SDK_ROOT}/build-tools"
"${ANDROID_SDK_ROOT}/build-tools/*")
if (NOT android_build_tools)
message(FATAL_ERROR "Could not locate Android SDK build tools under \"${ANDROID_SDK}/build-tools\"")
endif()
list(SORT android_build_tools)
list(REVERSE android_build_tools)
list(GET android_build_tools 0 android_build_tools_latest)
set(QT_ANDROID_SDK_BUILD_TOOLS_VERSION ${android_build_tools_latest})
endif()
# Ensure we are using the shared version of libc++
if(NOT ANDROID_STL STREQUAL c++_shared)
message(FATAL_ERROR "The Qt libraries on Android only supports the shared library configuration of stl. Please use -DANDROID_STL=\"c++_shared\" as configuration argument.")
endif()
# Target properties required for android deploy tool
define_property(TARGET
PROPERTY
QT_ANDROID_DEPLOYMENT_DEPENDENCIES
BRIEF_DOCS
"Specify additional plugins that need to be deployed with the current android application"
FULL_DOCS
"By default, androiddeployqt will detect the dependencies of your application. But since run-time usage of plugins cannot be detected, there could be false positives, as your application will depend on any plugins that are potential dependencies. If you want to minimize the size of your APK, it's possible to override the automatic detection using the ANDROID_DEPLOYMENT_DEPENDENCIES variable. This should contain a list of all Qt files which need to be included, with paths relative to the Qt install root. Note that only the Qt files specified here will be included. Failing to include the correct files can result in crashes. It's also important to make sure the files are listed in the correct loading order. This variable provides a way to override the automatic detection entirely, so if a library is listed before its dependencies, it will fail to load on some devices."
)
define_property(TARGET
PROPERTY
QT_ANDROID_EXTRA_LIBS
BRIEF_DOCS
"A list of external libraries that will be copied into your application's library folder and loaded on start-up."
FULL_DOCS
"A list of external libraries that will be copied into your application's library folder and loaded on start-up. This can be used, for instance, to enable OpenSSL in your application. Simply set the paths to the required libssl.so and libcrypto.so libraries here and OpenSSL should be enabled automatically."
)
define_property(TARGET
PROPERTY
QT_ANDROID_EXTRA_PLUGINS
BRIEF_DOCS
"This variable can be used to specify different resources that your project has to bundle but cannot be delivered through the assets system, such as qml plugins."
FULL_DOCS
"This variable can be used to specify different resources that your project has to bundle but cannot be delivered through the assets system, such as qml plugins. When using this variable, androiddeployqt will make sure everything is packaged and deployed properly."
)
define_property(TARGET
PROPERTY
QT_ANDROID_PACKAGE_SOURCE_DIR
BRIEF_DOCS
"This variable can be used to specify a directory where additions and modifications can be made to the default Android package template."
FULL_DOCS
"This variable can be used to specify a directory where additions and modifications can be made to the default Android package template. The androiddeployqt tool will copy the application template from Qt into the build directory, and then it will copy the contents of the ANDROID_PACKAGE_SOURCE_DIR on top of this, overwriting any existing files. The update step where parts of the source files are modified automatically to reflect your other settings is then run on the resulting merged package. If you, for instance, want to make a custom AndroidManifest.xml for your application, then place this directly into the folder specified in this variable. You can also add custom Java files in ANDROID_PACKAGE_SOURCE_DIR/src."
)
define_property(TARGET
PROPERTY
QT_ANDROID_DEPLOYMENT_SETTINGS_FILE
BRIEF_DOCS
" "
FULL_DOCS
" "
)
# Generate deployment tool json
function(qt_android_generate_deployment_settings target)
# Information extracted from mkspecs/features/android/android_deployment_settings.prf
if (NOT TARGET ${target})
message(SEND_ERROR "${target} is not a cmake target")
return()
endif()
get_target_property(target_type ${target} TYPE)
if (NOT "${target_type}" STREQUAL "MODULE_LIBRARY")
message(SEND_ERROR "QT_ANDROID_GENERATE_DEPLOYMENT_SETTINGS only works on Module targets")
return()
endif()
get_target_property(target_source_dir ${target} SOURCE_DIR)
get_target_property(target_binary_dir ${target} BINARY_DIR)
get_target_property(target_output_name ${target} OUTPUT_NAME)
if (NOT target_output_name)
set(target_output_name ${target})
endif()
set(deploy_file "${target_binary_dir}/android-lib${target_output_name}.so-deployment-settings.json")
set(file_contents "{\n")
# content begin
string(APPEND file_contents
" \"description\": \"This file is generated by cmake to be read by androiddeployqt and should not be modified by hand.\",\n")
# Host Qt Android install path
if (NOT QT_BUILDING_QT)
set(file_check "${Qt6_DIR}/plugins/platforms/android/libqtforandroid_${CMAKE_ANDROID_ARCH_ABI}.so")
if (NOT EXISTS ${file_check})
message(SEND_ERROR "Detected Qt installation does not contain libqtforandroid.so. This is most likely due to the installation not being a build of Qt for Android. Please update your settings.")
return()
endif()
set(qt_android_install_dir ${Qt6_Dir})
else()
# Building from source, use the same install prefix
set(qt_android_install_dir ${CMAKE_INSTALL_PREFIX})
endif()
file(TO_NATIVE_PATH "${qt_android_install_dir}" qt_android_install_dir_native)
string(APPEND file_contents
" \"qt\": \"${qt_android_install_dir_native}\",\n")
# Android SDK path
file(TO_NATIVE_PATH "${ANDROID_SDK_ROOT}" android_sdk_root_native)
string(APPEND file_contents
" \"sdk\": \"${android_sdk_root_native}\",\n")
# Android SDK Build Tools Revision
string(APPEND file_contents
" \"sdkBuildToolsRevision\": \"${QT_ANDROID_SDK_BUILD_TOOLS_VERSION}\",\n")
# Android NDK
file(TO_NATIVE_PATH "${ANDROID_NDK}" android_ndk_root_native)
string(APPEND file_contents
" \"ndk\": \"${android_ndk_root_native}\",\n")
# Setup LLVM toolchain
string(APPEND file_contents
" \"toolchain-prefix\": \"llvm\",\n")
string(APPEND file_contents
" \"tool-prefix\": \"llvm\",\n")
string(APPEND file_contents
" \"useLLVM\": true,\n")
# NDK Toolchain Version
string(APPEND file_contents
" \"toolchain-version\": \"${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}\",\n")
# NDK Host
string(APPEND file_contents
" \"ndk-host\": \"${ANDROID_NDK_HOST_SYSTEM_NAME}\",\n")
if (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86")
set(arch_value "i686-linux-android")
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
set(arch_value "x86_64-linux-android")
elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "armv64-v8a")
set(arch_value "aarch64-linux-android")
else()
set(arch_value "arm-linux-androideabi")
endif()
# Architecture
string(APPEND file_contents
" \"architectures\": { \"${CMAKE_ANDROID_ARCH_ABI}\" : \"${arch_value}\" },\n")
# deployment dependencies
get_target_property(android_deployment_dependencies
${target} QT_ANDROID_DEPLOYMENT_DEPENDENCIES)
if (android_deployment_dependencies)
list(JOIN android_deployment_dependencies "," android_deployment_dependencies)
string(APPEND file_contents
" \"deployment-dependencies\": \"${android_deployment_dependencies}\",\n")
endif()
# Extra plugins
get_target_property(android_extra_plugins
${target} QT_ANDROID_EXTRA_PLUGINS)
if (android_extra_plugins)
list(JOIN android_extra_plugins "," android_extra_plugins)
string(APPEND file_contents
" \"android-extra-plugins\": \"${android_extra_plugins}\",\n")
endif()
# Extra libs
get_target_property(android_extra_libs
${target} QT_ANDROID_EXTRA_LIBS)
if (android_extra_libs)
list(JOIN android_extra_libs "," android_extra_libs)
string(APPEND file_contents
" \"android-extra-libs\": \"${android_extra_libs}\",\n")
endif()
# package source dir
get_target_property(android_package_source_dir
${target} QT_ANDROID_PACKAGE_SOURCE_DIR)
if (android_package_source_dir)
file(TO_NATIVE_PATH "${android_package_source_dir}" android_package_source_dir_native)
string(APPEND file_contents
" \"android-package-source-directory\": \"${android_package_source_dir_native}\",\n")
endif()
#TODO: ANDROID_VERSION_NAME, doesn't seem to be used?
#TODO: ANDROID_VERSION_CODE, doesn't seem to be used?
get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH)
if (qml_import_path)
file(TO_NATIVE_PATH "${qml_import_path}" qml_import_path_native)
string(APPEND file_contents
" \"qml-import-path\": \"${qml_import_path_native}\",\n")
endif()
get_target_property(qml_root_path ${target} QT_QML_ROOT_PATH)
if(NOT qml_root_path)
set(qml_root_path "${target_source_dir}")
endif()
file(TO_NATIVE_PATH "${qml_root_path}" qml_root_path_native)
string(APPEND file_contents
" \"qml-root-path\": \"${qml_root_path_native}\",\n")
# App binary
string(APPEND file_contents
" \"application-binary\": \"${target_output_name}\",\n")
# Override qmlimportscanner binary path
set(qml_importscanner_binary_path "${QT_HOST_PATH}/bin/qmlimportscanner")
if (WIN32)
string(APPEND qml_importscanner_binary_path ".exe")
endif()
file(TO_NATIVE_PATH "${qml_importscanner_binary_path}" qml_importscanner_binary_path_native)
string(APPEND file_contents
" \"qml-importscanner-binary\" : \"${qml_importscanner_binary_path_native}\",\n")
# Last item in json file
# base location of stdlibc++, will be suffixed by androiddeploy qt
set(android_ndk_stdlib_base_path
"${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/"
)
string(APPEND file_contents
" \"stdcpp-path\": \"${android_ndk_stdlib_base_path}\"\n")
# content end
string(APPEND file_contents "}\n")
file(WRITE ${deploy_file} ${file_contents})
set_target_properties(${target}
PROPERTIES
QT_ANDROID_DEPLOYMENT_SETTINGS_FILE ${deploy_file}
)
endfunction()
function(qt_android_apply_arch_suffix target)
get_target_property(target_type ${target} TYPE)
if (target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY")
set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.so")
elseif (target_type STREQUAL "STATIC_LIBRARY")
set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.a")
endif()
endfunction()
# Add custom target to package the APK
function(qt_android_add_apk_target target)
get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE)
if (NOT deployment_file)
message(FATAL_ERROR "Target ${target} is not a valid android executable target\n")
endif()
set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt")
set(apk_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>/android-build")
add_custom_target(${target}_prepare_apk_dir
DEPENDS ${target}
COMMAND ${CMAKE_COMMAND}
-E copy $<TARGET_FILE:${target}>
"${apk_dir}/libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>"
COMMENT "Copying ${target} binarty to apk folder"
)
add_custom_target(${target}_make_apk
DEPENDS ${target}_prepare_apk_dir
COMMAND ${deployment_tool}
--input ${deployment_file}
--output ${apk_dir}
COMMENT "Creating APK for ${target}"
)
endfunction()
# Add a test for Android which will be run by the android test runner tool
function(qt_android_add_test target)
set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt")
set(test_runner "${QT_HOST_PATH}/bin/androidtestrunner")
get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE)
if (NOT deployment_file)
message(FATAL_ERROR "Target ${target} is not a valid android executable target\n")
endif()
set(target_binary_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>")
set(apk_dir "${target_binary_dir}/android-build")
add_test(NAME "${target}"
COMMAND "${test_runner}"
--androiddeployqt "${deployment_tool} --input ${deployment_file}"
--adb "${ANDROID_SDK_ROOT}/platform-tools/adb"
--path "${apk_dir}"
--skip-install-root
--make "${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target ${target}_make_apk"
--apk "${apk_dir}/${target}.apk"
--verbose
)
endfunction()

View File

@ -0,0 +1,81 @@
function(qt_set01 result)
if (${ARGN})
set("${result}" 1 PARENT_SCOPE)
else()
set("${result}" 0 PARENT_SCOPE)
endif()
endfunction()
qt_set01(LINUX CMAKE_SYSTEM_NAME STREQUAL "Linux")
qt_set01(HPUX CMAKE_SYSTEM_NAME STREQUAL "HPUX")
qt_set01(ANDROID CMAKE_SYSTEM_NAME STREQUAL "Android") # FIXME: How to identify this?
qt_set01(NACL CMAKE_SYSTEM_NAME STREQUAL "NaCl") # FIXME: How to identify this?
qt_set01(INTEGRITY CMAKE_SYSTEM_NAME STREQUAL "Integrity") # FIXME: How to identify this?
qt_set01(VXWORKS CMAKE_SYSTEM_NAME STREQUAL "VxWorks") # FIXME: How to identify this?
qt_set01(QNX CMAKE_SYSTEM_NAME STREQUAL "QNX") # FIXME: How to identify this?
qt_set01(OPENBSD CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") # FIXME: How to identify this?
qt_set01(FREEBSD CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") # FIXME: How to identify this?
qt_set01(NETBSD CMAKE_SYSTEM_NAME STREQUAL "NetBSD") # FIXME: How to identify this?
qt_set01(WASM CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
qt_set01(BSD APPLE OR OPENBSD OR FREEBSD OR NETBSD)
qt_set01(WINRT WIN32 AND CMAKE_VS_PLATFORM_TOOSLET STREQUAL "winrt") # FIXME: How to identify this?
qt_set01(APPLE_IOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
qt_set01(APPLE_TVOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "tvOS")
qt_set01(APPLE_WATCHOS APPLE AND CMAKE_SYSTEM_NAME STREQUAL "watchOS")
qt_set01(APPLE_UIKIT APPLE AND (APPLE_IOS OR APPLE_TVOS OR APPLE_WATCHOS))
qt_set01(APPLE_OSX APPLE AND NOT APPLE_UIKIT)
qt_set01(GCC CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
qt_set01(CLANG CMAKE_CXX_COMPILER_ID MATCHES "Clang")
qt_set01(ICC CMAKE_C_COMPILER MATCHES "icc|icl")
qt_set01(QCC CMAKE_C_COMPILER MATCHES "qcc") # FIXME: How to identify this?
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(QT_64BIT TRUE)
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(QT_32BIT TRUE)
endif()
# Parses a version string like "xx.yy.zz" and sets the major, minor and patch variables.
function(qt_parse_version_string version_string out_var_prefix)
string(REPLACE "." ";" version_list ${version_string})
list(LENGTH version_list length)
set(out_var "${out_var_prefix}_MAJOR")
set(value "")
if(length GREATER 0)
list(GET version_list 0 value)
list(REMOVE_AT version_list 0)
math(EXPR length "${length}-1")
endif()
set(${out_var} "${value}" PARENT_SCOPE)
set(out_var "${out_var_prefix}_MINOR")
set(value "")
if(length GREATER 0)
list(GET version_list 0 value)
set(${out_var} "${value}" PARENT_SCOPE)
list(REMOVE_AT version_list 0)
math(EXPR length "${length}-1")
endif()
set(${out_var} "${value}" PARENT_SCOPE)
set(out_var "${out_var_prefix}_PATCH")
set(value "")
if(length GREATER 0)
list(GET version_list 0 value)
set(${out_var} "${value}" PARENT_SCOPE)
list(REMOVE_AT version_list 0)
math(EXPR length "${length}-1")
endif()
set(${out_var} "${value}" PARENT_SCOPE)
endfunction()
# Set up the separate version components for the compiler version, to allow mapping of qmake
# conditions like 'equals(QT_GCC_MAJOR_VERSION,5)'.
if(CMAKE_CXX_COMPILER_VERSION)
qt_parse_version_string("${CMAKE_CXX_COMPILER_VERSION}" "QT_COMPILER_VERSION")
endif()

View File

@ -0,0 +1,17 @@
include_guard(DIRECTORY)
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
get_filename_component(_import_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_import_prefix "${_import_prefix}" REALPATH)
if (NOT QT_NO_CREATE_TARGETS)
# Find required dependencies, if any.
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/@target@Dependencies.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@target@Dependencies.cmake")
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
endif()

View File

@ -0,0 +1,42 @@
# note: _third_party_deps example: "ICU\\;1.0\\;i18n uc data;ZLIB\\;\\;"
set(_third_party_deps "@third_party_deps@")
foreach(_target_dep ${_third_party_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
list(GET _target_dep 2 components)
set(find_package_args "${pkg}")
if(version)
list(APPEND find_package_args "${version}")
endif()
if(components)
string(REPLACE " " ";" components "${components}")
find_dependency(${find_package_args} COMPONENTS ${components})
else()
find_dependency(${find_package_args})
endif()
if (NOT ${pkg}_FOUND)
set(@target@_FOUND FALSE)
return()
endif()
endforeach()
# note: target_deps example: "Qt6Core\;5.12.0;Qt6Gui\;5.12.0"
set(_target_deps "@target_deps@")
foreach(_target_dep ${_target_deps})
list(GET _target_dep 0 pkg)
list(GET _target_dep 1 version)
if (NOT ${pkg}_FOUND)
find_dependency(${pkg} ${version}
PATHS "${CMAKE_CURRENT_LIST_DIR}/.." ${QT_EXAMPLES_CMAKE_PREFIX_PATH} NO_DEFAULT_PATH
)
endif()
if (NOT ${pkg}_FOUND)
set(@target@_FOUND FALSE)
return()
endif()
endforeach()

131
cmake/QtPlugins.cmake.in Normal file
View File

@ -0,0 +1,131 @@
include_guard(DIRECTORY)
@QT_MODULE_PLUGIN_INCLUDES@
if(NOT @BUILD_SHARED_LIBS@)
set(_module_target "@INSTALL_CMAKE_NAMESPACE@::@QT_MODULE@")
# Properties can't be set on aliased targets, so make sure to unalias the target. This is needed
# when Qt examples are built as part of the Qt build itself.
get_target_property(_aliased_target ${_module_target} ALIASED_TARGET)
if(_aliased_target)
set(_module_target ${_aliased_target})
endif()
unset(_aliased_target)
set(_default_plugins_are_enabled "$<NOT:$<STREQUAL:$<GENEX_EVAL:$<TARGET_PROPERTY:QT_DEFAULT_PLUGINS>>,0>>")
# Make sure to boolify the result of the expression, in case if the returned property value
# is empty.
set(_default_plugins_are_enabled_wrapped "$<BOOL:${_default_plugins_are_enabled}>")
set(_manual_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS>>")
set(_no_plugins_genex "$<GENEX_EVAL:$<TARGET_PROPERTY:QT_NO_PLUGINS>>")
# In super builds the rules below pollute the dependency rule for the
# plugin target when it's being build, causing cyclic dependencies.
# to overcome this, we check if the current target where this rule evaluates
# has a QT_BUILD_PROJECT_NAME equal to the current PROJECT_NAME.
# If so we disable the injection of plugin link rules to avoid cyclic
# dependencies.
if (@QT_SUPERBUILD@)
set(_build_allow_plugin_link_rules_genex "$<NOT:$<STREQUAL:$<TARGET_PROPERTY:QT_BUILD_PROJECT_NAME>,@PROJECT_NAME@>>")
else()
set(_build_allow_plugin_link_rules_genex 1)
endif()
# The code in here uses the properties defined in qt_import_plugins (Qt6CoreMacros.cmake)
foreach(target @qt_plugins@)
set(_plugin_target "@INSTALL_CMAKE_NAMESPACE@::${target}")
set(_plugin_target_versionless "Qt::${target}")
get_target_property(_classname "${_plugin_target}" QT_PLUGIN_CLASS_NAME)
if(NOT _classname)
message("Warning: plugin ${_plugin_target} has no class name, skipping.")
continue()
endif()
get_target_property(_plugin_type "${_plugin_target}" QT_PLUGIN_TYPE)
if(NOT _plugin_type)
message("Warning: plugin ${_plugin_target} has no type ('${_plugin_type}'), skipping.")
continue()
endif()
list(APPEND "QT_ALL_PLUGINS_FOUND_BY_FIND_PACKAGE_${_plugin_type}" "${target}")
set(_plugin_is_default "$<TARGET_PROPERTY:${_plugin_target},QT_DEFAULT_PLUGIN>")
# INCLUDE
set(_plugin_is_whitelisted "$<IN_LIST:${_plugin_target},${_manual_plugins_genex}>")
set(_plugin_versionless_is_whitelisted
"$<IN_LIST:${_plugin_target_versionless},${_manual_plugins_genex}>")
# Note: qt_import_plugins sets the QT_PLUGINS_${_plugin_type} to "-"
# when excluding it with EXCLUDE_BY_TYPE,
# which ensures that no plug-in will be supported unless explicitly re-added afterwards.
string(CONCAT _plugin_is_not_blacklisted
"$<AND:"
"$<NOT:" # EXCLUDE
"$<IN_LIST:${_plugin_target},${_no_plugins_genex}>"
">,"
"$<NOT:"
"$<IN_LIST:${_plugin_target_versionless},${_no_plugins_genex}>"
">,"
# Excludes both plugins targeted by EXCLUDE_BY_TYPE and not included in
# INCLUDE_BY_TYPE.
"$<STREQUAL:,$<GENEX_EVAL:$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>>>"
">"
)
# Support INCLUDE_BY_TYPE
string(CONCAT _plugin_is_in_type_whitelist
"$<IN_LIST:"
"${_plugin_target},"
"$<GENEX_EVAL:"
"$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
">"
">"
)
string(CONCAT _plugin_versionless_is_in_type_whitelist
"$<IN_LIST:"
"${_plugin_target_versionless},"
"$<GENEX_EVAL:"
"$<TARGET_PROPERTY:QT_PLUGINS_${_plugin_type}>"
">"
">"
)
# Complete condition that defines whether a static plugin is linked
string(CONCAT _plugin_condition
"$<BOOL:$<AND:"
"${_build_allow_plugin_link_rules_genex},"
"$<OR:"
"${_plugin_is_whitelisted},"
"${_plugin_versionless_is_whitelisted},"
"${_plugin_is_in_type_whitelist},"
"${_plugin_versionless_is_in_type_whitelist},"
"$<AND:"
"${_default_plugins_are_enabled_wrapped},"
"${_plugin_is_default},"
"${_plugin_is_not_blacklisted}"
">"
">"
">>"
)
# If this condition is true, we link against the plug-in
set(_plugin_genex "$<${_plugin_condition}:${_plugin_target}>")
target_link_libraries(${_module_target} INTERFACE "${_plugin_genex}")
set(_generated_qt_plugin_file_name
"${CMAKE_CURRENT_BINARY_DIR}/qt_@QT_MODULE@_${target}.cpp")
set(_generated_qt_plugin_file_name_template "${_generated_qt_plugin_file_name}.in")
set(_generated_qt_plugin_file_content "#include <QtPlugin>\nQ_IMPORT_PLUGIN(${_classname})")
# Generate a source file to import that plug-in. Has to be done with configure_file,
# because file(GENERATE) and target_sources has issues with scopes.
file(WRITE "${_generated_qt_plugin_file_name_template}"
"${_generated_qt_plugin_file_content}")
configure_file("${_generated_qt_plugin_file_name_template}"
"${_generated_qt_plugin_file_name}")
target_sources(${_module_target} INTERFACE
"$<${_plugin_condition}:${_generated_qt_plugin_file_name}>")
endforeach()
endif()

405
cmake/QtPostProcess.cmake Normal file
View File

@ -0,0 +1,405 @@
function(qt_internal_write_depends_file target)
set(module Qt${target})
set(outfile "${QT_BUILD_DIR}/include/${module}/${module}Depends")
message("Generate ${outfile}...")
set(contents "/* This file was generated by cmake with the info from ${module} target. */\n")
string(APPEND contents "#ifdef __cplusplus /* create empty PCH in C mode */\n")
foreach (m ${ARGN})
string(APPEND contents "# include <Qt${m}/Qt${m}>\n")
endforeach()
string(APPEND contents "#endif\n")
file(GENERATE OUTPUT "${outfile}" CONTENT "${contents}")
endfunction()
macro(qt_collect_third_party_deps target)
set(_target_is_static OFF)
get_target_property(_target_type ${target} TYPE)
if (${_target_type} STREQUAL "STATIC_LIBRARY")
set(_target_is_static ON)
endif()
unset(_target_type)
# If we are doing a non-static Qt build, we only want to propagate public dependencies.
# If we are doing a static Qt build, we need to propagate all dependencies.
set(depends_var "public_depends")
if(_target_is_static)
set(depends_var "depends")
endif()
unset(_target_is_static)
foreach(dep ${${depends_var}})
# Gather third party packages that should be found when using the Qt module.
# Also handle nolink target dependencies.
string(REGEX REPLACE "_nolink$" "" base_dep "${dep}")
if(NOT base_dep STREQUAL dep)
# Resets target name like Vulkan_nolink to Vulkan, because we need to call
# find_package(Vulkan).
set(dep ${base_dep})
endif()
if(TARGET ${dep})
list(FIND third_party_deps_seen ${dep} dep_seen)
get_target_property(package_name ${dep} INTERFACE_QT_PACKAGE_NAME)
if(dep_seen EQUAL -1 AND package_name)
list(APPEND third_party_deps_seen ${dep})
get_target_property(package_version ${dep} INTERFACE_QT_PACKAGE_VERSION)
if(NOT package_version)
set(package_version "")
endif()
get_target_property(package_components ${dep} INTERFACE_QT_PACKAGE_COMPONENTS)
if(NOT package_components)
set(package_components "")
endif()
list(APPEND third_party_deps
"${package_name}\;${package_version}\;${package_components}")
endif()
endif()
endforeach()
endmacro()
function(qt_internal_create_module_depends_file target)
get_target_property(target_type "${target}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
set(arg_HEADER_MODULE ON)
else()
set(arg_HEADER_MODULE OFF)
endif()
if(NOT arg_HEADER_MODULE)
get_target_property(depends "${target}" LINK_LIBRARIES)
endif()
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
# Used for collecting Qt module dependencies that should be find_package()'d in
# ModuleDependencies.cmake.
get_target_property(target_deps "${target}" _qt_target_deps)
set(target_deps_seen "")
if(NOT arg_HEADER_MODULE)
get_target_property(extra_depends "${target}" QT_EXTRA_PACKAGE_DEPENDENCIES)
endif()
if(NOT extra_depends STREQUAL "${extra_depends}-NOTFOUND")
list(APPEND target_deps "${extra_depends}")
endif()
# Used for assembling the content of an include/Module/ModuleDepends.h header.
set(qtdeps "")
# Used for collecting third party dependencies that should be find_package()'d in
# ModuleDependencies.cmake.
set(third_party_deps "")
set(third_party_deps_seen "")
# Used for collecting Qt tool dependencies that should be find_package()'d in
# ModuleToolsDependencies.cmake.
set(tool_deps "")
set(tool_deps_seen "")
# Used for collecting Qt tool dependencies that should be find_package()'d in
# ModuleDependencies.cmake.
set(main_module_tool_deps "")
qt_internal_get_qt_all_known_modules(known_modules)
set(all_depends ${depends} ${public_depends})
foreach (dep ${all_depends})
# Normalize module by stripping leading "Qt::" and trailing "Private"
if (dep MATCHES "Qt::(.*)")
set(dep "${CMAKE_MATCH_1}")
endif()
if (dep MATCHES "(.*)Private")
set(dep "${CMAKE_MATCH_1}")
endif()
list(FIND known_modules "${dep}" _pos)
if (_pos GREATER -1)
list(APPEND qtdeps "${dep}")
# Make the ModuleTool package depend on dep's ModuleTool package.
list(FIND tool_deps_seen ${dep} dep_seen)
if(dep_seen EQUAL -1 AND ${dep} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS)
list(APPEND tool_deps_seen ${dep})
list(APPEND tool_deps
"${INSTALL_CMAKE_NAMESPACE}${dep}Tools\;${PROJECT_VERSION}")
endif()
endif()
endforeach()
qt_collect_third_party_deps(${target})
# Add dependency to the main ModuleTool package to ModuleDependencies file.
if(${target} IN_LIST QT_KNOWN_MODULES_WITH_TOOLS)
set(main_module_tool_deps
"${INSTALL_CMAKE_NAMESPACE}${target}Tools\;${PROJECT_VERSION}")
endif()
# Dirty hack because https://gitlab.kitware.com/cmake/cmake/issues/19200
foreach(dep ${target_deps})
if(dep)
list(FIND target_deps_seen "${dep}" dep_seen)
if(dep_seen EQUAL -1)
list(LENGTH dep len)
if(NOT (len EQUAL 2))
message(FATAL_ERROR "List '${dep}' should look like QtFoo;version")
endif()
list(GET dep 0 dep_name)
list(GET dep 1 dep_ver)
list(APPEND target_deps_seen "${dep_name}\;${dep_ver}")
endif()
endif()
endforeach()
set(target_deps "${target_deps_seen}")
if (DEFINED qtdeps)
list(REMOVE_DUPLICATES qtdeps)
endif()
get_target_property(hasModuleHeaders "${target}" INTERFACE_MODULE_HAS_HEADERS)
if (${hasModuleHeaders})
qt_internal_write_depends_file("${target}" ${qtdeps})
endif()
if(third_party_deps OR main_module_tool_deps OR target_deps)
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}")
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
# Configure and install ModuleDependencies file.
configure_file(
"${QT_CMAKE_DIR}/QtModuleDependencies.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake"
@ONLY
)
qt_install(FILES
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${target}Dependencies.cmake"
DESTINATION "${config_install_dir}"
COMPONENT Devel
)
endif()
if(tool_deps)
# The value of the property will be used by qt_export_tools.
set_property(TARGET "${target}" PROPERTY _qt_tools_package_deps "${tool_deps}")
endif()
endfunction()
function(qt_internal_create_plugin_depends_file target)
get_target_property(qt_module "${target}" QT_MODULE)
get_target_property(depends "${target}" LINK_LIBRARIES)
get_target_property(public_depends "${target}" INTERFACE_LINK_LIBRARIES)
get_target_property(target_deps "${target}" _qt_target_deps)
set(target_deps_seen "")
qt_collect_third_party_deps(${target})
# Dirty hack because https://gitlab.kitware.com/cmake/cmake/issues/19200
foreach(dep ${target_deps})
if(dep)
list(FIND target_deps_seen "${dep}" dep_seen)
if(dep_seen EQUAL -1)
list(LENGTH dep len)
if(NOT (len EQUAL 2))
message(FATAL_ERROR "List '${dep}' should look like QtFoo;version")
endif()
list(GET dep 0 dep_name)
list(GET dep 1 dep_ver)
list(APPEND target_deps_seen "${dep_name}\;${dep_ver}")
endif()
endif()
endforeach()
set(target_deps "${target_deps_seen}")
if(third_party_deps OR target_deps)
# Setup build and install paths
if(qt_module)
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${qt_module}")
else()
set(path_suffix "${INSTALL_CMAKE_NAMESPACE}${target}")
endif()
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${path_suffix})
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${path_suffix})
# Configure and install ModuleDependencies file.
configure_file(
"${QT_CMAKE_DIR}/QtPluginDependencies.cmake.in"
"${config_build_dir}/${target}Dependencies.cmake"
@ONLY
)
qt_install(FILES
"${config_build_dir}/${target}Dependencies.cmake"
DESTINATION "${config_install_dir}"
COMPONENT Devel
)
endif()
endfunction()
# Create Depends.cmake & Depends.h files for all modules and plug-ins.
function(qt_internal_create_depends_files)
qt_internal_get_qt_repo_known_modules(repo_known_modules)
message("Generating ModuleDepends files and CMake ModuleDependencies files for ${repo_known_modules}...")
foreach (target ${repo_known_modules})
qt_internal_create_module_depends_file(${target})
endforeach()
message("Generating CMake PluginDependencies files for ${QT_KNOWN_PLUGINS}...")
foreach (target ${QT_KNOWN_PLUGINS})
qt_internal_create_plugin_depends_file(${target})
endforeach()
endfunction()
# This function creates the Qt<Module>Plugins.cmake used to list all
# the plug-in target files.
function(qt_internal_create_plugins_files)
# The plugins cmake configuration is only needed for static builds. Dynamic builds don't need
# the application to link against plugins at build time.
if(QT_BUILD_SHARED_LIBS)
return()
endif()
qt_internal_get_qt_repo_known_modules(repo_known_modules)
message("Generating Plugins files for ${repo_known_modules}...")
foreach (QT_MODULE ${repo_known_modules})
get_target_property(target_type "${QT_MODULE}" TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
# No plugins are provided by a header only module.
continue()
endif()
qt_path_join(config_build_dir ${QT_CONFIG_BUILD_DIR} ${INSTALL_CMAKE_NAMESPACE}${QT_MODULE})
qt_path_join(config_install_dir ${QT_CONFIG_INSTALL_DIR} ${INSTALL_CMAKE_NAMESPACE}${QT_MODULE})
set(QT_MODULE_PLUGIN_INCLUDES "")
get_target_property(qt_plugins "${QT_MODULE}" QT_PLUGINS)
if(qt_plugins)
foreach (pluginTarget ${qt_plugins})
set(QT_MODULE_PLUGIN_INCLUDES "${QT_MODULE_PLUGIN_INCLUDES}include(\"\${CMAKE_CURRENT_LIST_DIR}/${pluginTarget}Config.cmake\")\n")
endforeach()
configure_file(
"${QT_CMAKE_DIR}/QtPlugins.cmake.in"
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${QT_MODULE}Plugins.cmake"
@ONLY
)
qt_install(FILES
"${config_build_dir}/${INSTALL_CMAKE_NAMESPACE}${QT_MODULE}Plugins.cmake"
DESTINATION "${config_install_dir}"
COMPONENT Devel
)
endif()
endforeach()
endfunction()
function(qt_generate_build_internals_extra_cmake_code)
if(PROJECT_NAME STREQUAL "QtBase")
foreach(var IN LISTS QT_BASE_CONFIGURE_TESTS_VARS_TO_EXPORT)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS "set(${var} \"${${var}}\" CACHE INTERNAL \"\")\n")
endforeach()
set(QT_SOURCE_TREE "${QtBase_SOURCE_DIR}")
qt_path_join(extra_file_path
${QT_CONFIG_BUILD_DIR}
${INSTALL_CMAKE_NAMESPACE}BuildInternals/QtBuildInternalsExtra.cmake)
if(CMAKE_BUILD_TYPE)
# Need to force set, because CMake itself initializes a value for CMAKE_BUILD_TYPE
# at the start of project configuration (with an empty value),
# so we need to force override it.
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(CMAKE_BUILD_TYPE \"${CMAKE_BUILD_TYPE}\" CACHE STRING \"Choose the type of build.\" FORCE)\n")
endif()
if(CMAKE_CONFIGURATION_TYPES)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(CMAKE_CONFIGURATION_TYPES \"${CMAKE_CONFIGURATION_TYPES}\")\n")
endif()
if(CMAKE_TRY_COMPILE_CONFIGURATION)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(CMAKE_TRY_COMPILE_CONFIGURATION \"${CMAKE_TRY_COMPILE_CONFIGURATION}\")\n")
endif()
if(QT_MULTI_CONFIG_FIRST_CONFIG)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(QT_MULTI_CONFIG_FIRST_CONFIG \"${QT_MULTI_CONFIG_FIRST_CONFIG}\")\n")
endif()
if(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE \"${CMAKE_NINJA_MULTI_CROSS_CONFIG_ENABLE}\")\n")
endif()
if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
string(APPEND QT_EXTRA_BUILD_INTERNALS_VARS
"set(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE \"${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}\")\n")
endif()
configure_file(
"${CMAKE_CURRENT_LIST_DIR}/QtBuildInternalsExtra.cmake.in"
"${extra_file_path}"
@ONLY
)
endif()
endfunction()
# For every Qt module check if there any android dependencies that require
# processing.
function(qt_modules_process_android_dependencies)
qt_internal_get_qt_repo_known_modules(repo_known_modules)
foreach (target ${repo_known_modules})
qt_android_dependencies(${target})
endforeach()
endfunction()
function(qt_create_tools_config_files)
# Create packages like Qt6CoreTools/Qt6CoreToolsConfig.cmake.
foreach(module_name ${QT_KNOWN_MODULES_WITH_TOOLS})
qt_export_tools("${module_name}")
endforeach()
endfunction()
function(qt_internal_create_config_file_for_standalone_tests)
set(standalone_tests_config_dir "StandaloneTests")
qt_path_join(config_build_dir
${QT_CONFIG_BUILD_DIR}
"${INSTALL_CMAKE_NAMESPACE}BuildInternals" "${standalone_tests_config_dir}")
qt_path_join(config_install_dir
${QT_CONFIG_INSTALL_DIR}
"${INSTALL_CMAKE_NAMESPACE}BuildInternals" "${standalone_tests_config_dir}")
list(JOIN QT_REPO_KNOWN_MODULES " " QT_REPO_KNOWN_MODULES_STRING)
string(STRIP "${QT_REPO_KNOWN_MODULES_STRING}" QT_REPO_KNOWN_MODULES_STRING)
# Skip generating and installing file if no modules were built. This make sure not to install
# anything when build qtx11extras on macOS for example.
if(NOT QT_REPO_KNOWN_MODULES_STRING)
return()
endif()
# Ceate a Config file that calls find_package on the modules that were built as part
# of the current repo. This is used for standalone tests.
configure_file(
"${QT_CMAKE_DIR}/QtStandaloneTestsConfig.cmake.in"
"${config_build_dir}/${PROJECT_NAME}TestsConfig.cmake"
@ONLY
)
qt_install(FILES
"${config_build_dir}/${PROJECT_NAME}TestsConfig.cmake"
DESTINATION "${config_install_dir}"
COMPONENT Devel
)
endfunction()
qt_internal_create_depends_files()
qt_generate_build_internals_extra_cmake_code()
qt_internal_create_plugins_files()
qt_internal_create_config_file_for_standalone_tests()
# Needs to run after qt_internal_create_depends_files.
qt_create_tools_config_files()
if (ANDROID)
qt_modules_process_android_dependencies()
endif()

107
cmake/QtProperties.cmake Normal file
View File

@ -0,0 +1,107 @@
define_property(TARGET
PROPERTY
QT_PLUGINS
BRIEF_DOCS
"List of Qt plug-ins associated with a given Qt module."
FULL_DOCS
"This is a property on Qt modules.
For instance, sqlite;odbc for Sql"
)
define_property(TARGET
PROPERTY
MODULE_PLUGIN_TYPES
BRIEF_DOCS
"List of plugin categories associated to the Qt module"
FULL_DOCS
"This is a property on Qt modules.
For instance, sqldrivers for Sql."
)
define_property(TARGET
PROPERTY
QT_PLUGIN_CLASS_NAME
BRIEF_DOCS
"Class name of the Qt plug-in"
FULL_DOCS
"This is a property on Qt plug-ins.
For instance, QICOPlugin for the qico plug-in"
)
define_property(TARGET
PROPERTY
QT_PLUGIN_TYPE
BRIEF_DOCS
"Type of the Qt plug-in"
FULL_DOCS
"This is a property on Qt plug-ins.
For example, the value of the QT_PLUGIN_TYPE property on the qico plugin is \"imageformats\""
)
define_property(TARGET
PROPERTY
QT_MODULE
BRIEF_DOCS
"Qt module associated with a plug-in."
FULL_DOCS
"This is a property on Qt plug-ins.
For instance, Sql for qsqlite"
)
define_property(TARGET
PROPERTY
QT_DEFAULT_PLUGIN
BRIEF_DOCS
"Indicates whether a plug-in is added by default."
FULL_DOCS
"This is a property on Qt plug-ins.
It is mainly used to indicate if a plug-in should be added
to the default set of plug-ins when building a static app -
for instance, which QPA should be linked."
)
define_property(GLOBAL
PROPERTY
QT_KNOWN_PLUGINS
BRIEF_DOCS
""
FULL_DOCS
""
)
define_property(TARGET
PROPERTY
QT_QML_MODULE_TARGET_PATH
BRIEF_DOCS
"Specifies the target path for a qml module"
FULL_DOCS
"Specifies the target path for a qml module"
)
define_property(TARGET
PROPERTY
QT_QML_MODULE_URI
BRIEF_DOCS
"Specifies the URI for a qml module"
FULL_DOCS
"Specifies the URI for a qml module"
)
define_property(TARGET
PROPERTY
QT_RESOURCE_PREFIX
BRIEF_DOCS
"Specifies the default Qt resource prefix."
FULL_DOCS
"When using qt_add_resource() without a PREFIX, then prefix of this target property
will be used."
)
define_property(TARGET
PROPERTY
QT_QML_MODULE_VERSION
BRIEF_DOCS
"Specifies the qml module's version."
FULL_DOCS
"Specifies the qml module's version."
)

313
cmake/QtResource.cmake.in Normal file
View File

@ -0,0 +1,313 @@
#
# All things resource related
#
function(__qt_get_relative_resource_path_for_file output_alias file)
get_property(alias SOURCE ${file} PROPERTY QT_RESOURCE_ALIAS)
if (NOT alias)
set(alias "${file}")
endif()
set(${output_alias} ${alias} PARENT_SCOPE)
endfunction()
function(__qt_propagate_generated_resource target resource_name generated_source_code output_generated_target)
get_target_property(type ${target} TYPE)
if(type STREQUAL STATIC_LIBRARY)
set(resource_target "${target}_resources_${resourceName}")
add_library("${resource_target}" OBJECT "${generated_source_code}")
# Use TARGET_NAME genex to map to the correct prefixed target name when it is exported
# via qt_install(EXPORT), so that the consumers of the target can find the object library
# as well.
target_link_libraries(${target} INTERFACE
"$<TARGET_OBJECTS:$<TARGET_NAME:${resource_target}>>")
set(${output_generated_target} "${resource_target}" PARENT_SCOPE)
else()
set(${output_generated_target} "" PARENT_SCOPE)
target_sources(${target} PRIVATE ${generated_source_code})
endif()
endfunction()
# Inspect all files passed to a call to qt_add_resource. If there are any
# files present, invoke the quick compiler and return the remaining resource
# files that have not been processed in OUTPUT_REMAINING_RESOURCES as well as the new
# name for the resource in OUTPUT_RESOURCE_NAME.
function(__qt_quick_compiler_process_resources target resource_name)
cmake_parse_arguments(arg
"" "PREFIX;OUTPUT_REMAINING_RESOURCES;OUTPUT_RESOURCE_NAME;OUTPUT_GENERATED_TARGET" "FILES" ${ARGN}
)
set(qml_files)
set(resource_files)
set(retained_files)
# scan for qml files
foreach(file IN LISTS arg_FILES)
# check whether this resource should not be processed by the qt quick
# compiler
get_source_file_property(skip_compiler_check ${file} QT_SKIP_QUICKCOMPILER)
get_source_file_property(retain_compiler_check ${file} QT_RETAIN_QUICKCOMPILER)
if (skip_compiler_check)
list(APPEND resource_files ${file})
continue()
endif()
if (${file} MATCHES "\.js$"
OR ${file} MATCHES "\.mjs$"
OR ${file} MATCHES "\.qml$")
list(APPEND qml_files ${file})
if (retain_compiler_check)
list(APPEND retained_files ${file})
list(APPEND resource_files ${file})
endif()
else()
list(APPEND resource_files ${file})
endif()
endforeach()
if (NOT TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
message(WARNING "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE: Qml files were detected but the qmlcachgen target is not defined. Consider adding QmlTools to your find_package command.")
endif()
set(retained_resource_paths)
if (TARGET @QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen AND qml_files)
# Enable qt quick compiler support
set(qml_resource_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/${resource_name}.qrc")
if (resource_files)
set(chained_resource_name "${resource_name}_qmlcache")
endif()
foreach(file IN LISTS qml_files)
get_filename_component(file_absolute ${file} ABSOLUTE)
file(RELATIVE_PATH file_relative ${CMAKE_CURRENT_SOURCE_DIR} ${file_absolute})
__qt_get_relative_resource_path_for_file(file_resource_path ${file})
if (arg_PREFIX STREQUAL "/")
# TO_CMAKE_PATH does not clean up cases such as //Foo
set(file_resource_path "/${file_resource_path}")
else()
set(file_resource_path "${arg_PREFIX}/${file_resource_path}")
endif()
if (file IN_LIST retained_files)
list(APPEND retained_resource_paths ${file_resource_path})
endif()
file(TO_CMAKE_PATH ${file_resource_path} file_resource_path)
list(APPEND file_resource_paths ${file_resource_path})
string(REGEX REPLACE "\.js$" "_js" compiled_file ${file_relative})
string(REGEX REPLACE "\.mjs$" "_mjs" compiled_file ${compiled_file})
string(REGEX REPLACE "\.qml$" "_qml" compiled_file ${compiled_file})
string(REGEX REPLACE "[\$#\?]+" "_" compiled_file ${compiled_file})
set(compiled_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/${compiled_file}.cpp")
get_filename_component(out_dir ${compiled_file} DIRECTORY)
if(NOT EXISTS ${out_dir})
file(MAKE_DIRECTORY ${out_dir})
endif()
add_custom_command(
OUTPUT ${compiled_file}
DEPENDS ${file_absolute}
${QT_TOOL_PATH_SETUP_COMMAND}
COMMAND
@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
--resource-path ${file_resource_path}
-o ${compiled_file}
${file_absolute}
)
target_sources(${target} PRIVATE ${compiled_file})
endforeach()
set(qmlcache_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qml_loader_file_list.rsp")
file(GENERATE
OUTPUT ${qmlcache_loader_list}
CONTENT "$<JOIN:${file_resource_paths},\n>"
)
set(qmlcache_loader_file "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/qmlcache_loader.cpp")
set(resource_name_arg "${resource_name}.qrc")
if (chained_resource_name)
set(resource_name_arg "${resource_name_arg}=${chained_resource_name}")
endif()
if (retained_resource_paths)
set(retained_loader_list "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qmlcache/${resource_name}/retained_file_list.rsp")
file(GENERATE
OUTPUT ${retained_loader_list}
CONTENT "$<JOIN:${retained_resource_paths},\n>"
)
set(retained_args "--retain" "@${retained_loader_list}")
endif()
add_custom_command(
OUTPUT ${qmlcache_loader_file}
DEPENDS ${qmlcache_loader_list}
${QT_TOOL_PATH_SETUP_COMMAND}
COMMAND
@QT_CMAKE_EXPORT_NAMESPACE@::qmlcachegen
${retained_args}
--resource-name "${resource_name_arg}"
-o ${qmlcache_loader_file}
"@${qmlcache_loader_list}"
)
__qt_propagate_generated_resource(${target}
${resource_name}
${qmlcache_loader_file}
output_target)
set(${arg_OUTPUT_GENERATED_TARGET} "${output_target}" PARENT_SCOPE)
if (resource_files)
set(resource_name ${chained_resource_name})
endif()
# The generated qmlcache_loader source file uses private headers of Qml, so make sure
# if the object library was created, it depends on the Qml target. If there's no target,
# that means the target is a shared library and the sources are directly added to the target
# via target_sources, so add dependency in that case as well.
set(chosen_target "target") # shared library case
if(output_target)
set(chosen_target "output_target") # static library case.
endif()
target_link_libraries(${${chosen_target}} PRIVATE @QT_CMAKE_EXPORT_NAMESPACE@::Qml)
else()
set(resource_files ${arg_FILES})
endif()
set(${arg_OUTPUT_REMAINING_RESOURCES} ${resource_files} PARENT_SCOPE)
set(${arg_OUTPUT_RESOURCE_NAME} ${resource_name} PARENT_SCOPE)
endfunction()
#
# Process resources via file path instead of QRC files. Behind the
# scnenes, it will generate a qrc file and apply post processing steps
# when applicable. (e.g.: QtQuickCompiler)
#
# The QRC Prefix is set via the PREFIX parameter.
#
# Alias settings for files need to be set via the QT_RESOURCE_ALIAS property
# via the set_soure_files_properties() command.
#
# When using this command with static libraries, one or more special targets
# will be generated. Should you wish to perform additional processing on these
# targets pass a value to the OUTPUT_TARGETS parameter.
#
function(QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE target resourceName)
cmake_parse_arguments(rcc "" "PREFIX;LANG;BASE;OUTPUT_TARGETS" "FILES;OPTIONS" ${ARGN})
string(REPLACE "/" "_" resourceName ${resourceName})
string(REPLACE "." "_" resourceName ${resourceName})
set(output_targets "")
# Apply base to all files
if (rcc_BASE)
foreach(file IN LISTS rcc_FILES)
set(resource_file "${rcc_BASE}/${file}")
__qt_get_relative_resource_path_for_file(alias ${resource_file})
# Handle case where resources were generated from a directory
# different than the one where the main .pro file resides.
# Unless otherwise specified, we should use the original file path
# as alias.
if (alias STREQUAL resource_file)
set_source_files_properties(${resource_file} PROPERTIES QT_RESOURCE_ALIAS ${file})
endif()
file(TO_CMAKE_PATH ${resource_file} resource_file)
list(APPEND resource_files ${resource_file})
endforeach()
else()
set(resource_files ${rcc_FILES})
endif()
if(NOT rcc_PREFIX)
get_target_property(rcc_PREFIX ${target} QT_RESOURCE_PREFIX)
if (NOT rcc_PREFIX)
message(FATAL_ERROR "QT@PROJECT_VERSION_MAJOR@_PROCESS_RESOURCE() was called without a PREFIX and the target does not provide QT_RESOURCE_PREFIX. Please either add a PREFIX or make the target ${target} provide a default.")
endif()
endif()
# Apply quick compiler pass
__qt_quick_compiler_process_resources(${target} ${resourceName}
FILES ${resource_files}
PREFIX ${rcc_PREFIX}
OUTPUT_REMAINING_RESOURCES resources
OUTPUT_RESOURCE_NAME newResourceName
OUTPUT_GENERATED_TARGET output_target_quick
)
if (NOT resources)
if (rcc_OUTPUT_TARGETS)
set(${rcc_OUTPUT_TARGETS} "${output_target_quick}" PARENT_SCOPE)
endif()
return()
endif()
list(APPEND output_targets ${output_target_quick})
set(generatedResourceFile "${CMAKE_CURRENT_BINARY_DIR}/.rcc/generated_${newResourceName}.qrc")
set(generatedSourceCode "${CMAKE_CURRENT_BINARY_DIR}/.rcc/qrc_${newResourceName}.cpp")
# Generate .qrc file:
# <RCC><qresource ...>
set(qrcContents "<RCC>\n <qresource")
if (rcc_PREFIX)
string(APPEND qrcContents " prefix=\"${rcc_PREFIX}\"")
endif()
if (rcc_LANG)
string(APPEND qrcContents " lang=\"${rcc_LANG}\"")
endif()
string(APPEND qrcContents ">\n")
set(resource_dependencies)
foreach(file IN LISTS resources)
__qt_get_relative_resource_path_for_file(file_resource_path ${file})
if (NOT IS_ABSOLUTE ${file})
set(file "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
endif()
### FIXME: escape file paths to be XML conform
# <file ...>...</file>
string(APPEND qrcContents " <file alias=\"${file_resource_path}\">")
string(APPEND qrcContents "${file}</file>\n")
list(APPEND files "${file}")
get_source_file_property(target_dependency ${file} QT_RESOURCE_TARGET_DEPENDENCY)
if (NOT target_dependency)
list(APPEND resource_dependencies ${file})
else()
if (NOT TARGET ${target_dependency})
message(FATAL_ERROR "Target dependency on resource file ${file} is not a cmake target.")
endif()
list(APPEND resource_dependencies ${target_dependency})
endif()
endforeach()
# </qresource></RCC>
string(APPEND qrcContents " </qresource>\n</RCC>\n")
file(GENERATE OUTPUT "${generatedResourceFile}" CONTENT "${qrcContents}")
set(rccArgs --name "${newResourceName}"
--output "${generatedSourceCode}" "${generatedResourceFile}")
if(rcc_OPTIONS)
list(APPEND rccArgs ${rcc_OPTIONS})
endif()
# Process .qrc file:
add_custom_command(OUTPUT "${generatedSourceCode}"
COMMAND "@QT_CMAKE_EXPORT_NAMESPACE@::rcc"
ARGS ${rccArgs}
DEPENDS ${resource_dependencies} ${generatedResourceFile}
COMMENT "RCC ${newResourceName}"
VERBATIM)
get_target_property(type "${target}" TYPE)
# Only do this if newResourceName is the same as resourceName, since
# the resource will be chainloaded by the qt quickcompiler
# qml cache loader
if(newResourceName STREQUAL resourceName)
__qt_propagate_generated_resource(${target} ${resourceName} "${generatedSourceCode}" output_target)
list(APPEND output_targets ${output_target})
else()
target_sources(${target} PRIVATE "${generatedSourceCode}")
endif()
if (rcc_OUTPUT_TARGETS)
set(${rcc_OUTPUT_TARGETS} "${output_targets}" PARENT_SCOPE)
endif()
endfunction()

176
cmake/QtSetup.cmake Normal file
View File

@ -0,0 +1,176 @@
## Set a default build type if none was specified
# Set the QT_IS_BUILDING_QT variable so we can verify whether we are building
# Qt from source
set(QT_BUILDING_QT TRUE CACHE
TYPE STRING "When this is present and set to true, it signals that we are building Qt from source.")
set(_default_build_type "Release")
if(EXISTS "${CMAKE_SOURCE_DIR}/.git")
set(_default_build_type "Debug")
endif()
# Reset content of extra build internal vars for each inclusion of QtSetup.
unset(QT_EXTRA_BUILD_INTERNALS_VARS)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${_default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${_default_build_type}" CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE
PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo") # Set the possible values for cmake-gui.
elseif(CMAKE_CONFIGURATION_TYPES)
message(STATUS "Building for multiple configurations: ${CMAKE_CONFIGURATION_TYPES}.")
message(STATUS "Main configuration is: ${QT_MULTI_CONFIG_FIRST_CONFIG}.")
if(CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE)
message(STATUS
"Default build configuration set to '${CMAKE_NINJA_MULTI_DEFAULT_BUILD_TYPE}'.")
endif()
endif()
# Appends a 'debug postfix' to library targets (not executables)
# e.g. lib/libQt6DBus_debug.5.12.0.dylib
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
elseif(APPLE)
set(CMAKE_DEBUG_POSTFIX "_debug")
endif()
## Position independent code:
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Do not relink dependent libraries when no header has changed:
set(CMAKE_LINK_DEPENDS_NO_SHARED ON)
# Default to hidden visibility for symbols:
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN 1)
# Detect non-prefix builds, either when the install prefix is set to the binary dir
# or when enabling developer builds and no prefix is specified.
# This detection only happens when building qtbase, and later is propagated via the generated
# QtBuildInternalsExtra.cmake file.
if (PROJECT_NAME STREQUAL "QtBase" AND NOT QT_BUILD_STANDALONE_TESTS)
if((CMAKE_INSTALL_PREFIX STREQUAL CMAKE_BINARY_DIR) OR
(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND FEATURE_developer_build))
set(__qt_will_install_value OFF)
# Handle non-prefix builds by setting the CMake install prefix to point to qtbase's build
# dir.
# While building another repo (like qtsvg), the CMAKE_INSTALL_PREFIX or CMAKE_PREFIX_PATH
# (either work) should be set on the command line to point to the qtbase build dir.
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR} CACHE PATH
"Install path prefix, prepended onto install directories." FORCE)
else()
set(__qt_will_install_value ON)
endif()
set(QT_WILL_INSTALL ${__qt_will_install_value} CACHE BOOL
"Boolean indicating if doing a Qt prefix build (vs non-prefix build)." FORCE)
unset(__qt_will_install_value)
endif()
# Specify the QT_SOURCE_TREE only when building qtbase. Needed by some tests when the tests are
# built as part of the project, and not standalone. For standalone tests, the value is set in
# QtBuildInternalsExtra.cmake.
if(PROJECT_NAME STREQUAL "QtBase")
set(QT_SOURCE_TREE "${QtBase_SOURCE_DIR}" CACHE PATH
"A path to the source tree of the previously configured QtBase project." FORCE)
endif()
if(FEATURE_developer_build)
if(DEFINED QT_CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_EXPORT_COMPILE_COMMANDS ${QT_CMAKE_EXPORT_COMPILE_COMMANDS})
else()
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
endif()
set(QT_BUILD_TESTING ON)
set(__build_benchmarks ON)
# Tests are not built by default with qmake for iOS and friends, and thus the overall build
# tends to fail. Disable them by default when targeting uikit.
if(APPLE_UIKIT)
set(QT_BUILD_TESTING OFF)
endif()
# Disable benchmarks for single configuration generators which do not build
# with release configuration.
if (CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE STREQUAL Release)
set(__build_benchmarks OFF)
endif()
else()
set(QT_BUILD_TESTING OFF)
set(__build_benchmarks OFF)
endif()
## Set up testing
option(BUILD_TESTING "Build the testing tree." ${QT_BUILD_TESTING})
if(QT_BUILD_STANDALONE_TESTS)
set(QT_BUILD_TESTING ON)
# BuildInternals might have set it to OFF on initial configuration. So force it to ON when
# building standalone tests.
set(BUILD_TESTING ON CACHE BOOL "Build the testing tree." FORCE)
# Also force the tests to be built as part of the default build target.
set(QT_NO_MAKE_TESTS OFF CACHE BOOL
"Should examples be built as part of the default 'all' target." FORCE)
endif()
option(QT_NO_MAKE_TESTS "Should tests be built as part of the default 'all' target." OFF)
include(CTest)
enable_testing()
# Set up building of examples.
set(QT_BUILD_EXAMPLES ON)
# Examples are not built by default with qmake for iOS and friends, and thus the overall build
# tends to fail. Disable them by default when targeting uikit.
if(APPLE_UIKIT)
set(QT_BUILD_EXAMPLES OFF)
endif()
option(BUILD_EXAMPLES "Build Qt examples" ${QT_BUILD_EXAMPLES})
option(QT_NO_MAKE_EXAMPLES "Should examples be built as part of the default 'all' target." OFF)
# Build Benchmarks
option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks})
## Android platform settings
if(ANDROID)
include(QtPlatformAndroid)
endif()
## qt_add_module and co.:
include(QtBuild)
## Qt Feature support:
include(QtFeature)
## Compiler optimization flags:
include(QtCompilerOptimization)
## Compiler flags:
include(QtCompilerFlags)
## Set up non-prefix build:
qt_set_up_nonprefix_build()
qt_set_language_standards()
## Find host tools (if non native):
set(QT_HOST_PATH "" CACHE PATH "Installed Qt host directory path, used for cross compiling.")
if (CMAKE_CROSSCOMPILING AND NOT IS_DIRECTORY ${QT_HOST_PATH})
message(FATAL_ERROR "You need to set QT_HOST_PATH to cross compile Qt.")
endif()
## Enable support for sanitizers:
include(${CMAKE_CURRENT_LIST_DIR}/3rdparty/extra-cmake-modules/modules/ECMEnableSanitizers.cmake)
option(QT_USE_CCACHE "Enable the use of ccache")
if(QT_USE_CCACHE)
find_program(CCACHE_PROGRAM ccache)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
set(CMAKE_OBJC_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
endif()

View File

@ -0,0 +1,2 @@
find_package(@INSTALL_CMAKE_NAMESPACE@ @PROJECT_VERSION@
REQUIRED COMPONENTS @QT_REPO_KNOWN_MODULES_STRING@)

View File

@ -0,0 +1,35 @@
@PACKAGE_INIT@
get_filename_component(_qt_tools_cmake_dir "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
if (NOT @INSTALL_CMAKE_NAMESPACE@Tools_FIND_COMPONENTS)
set(@INSTALL_CMAKE_NAMESPACE@Tools_NOT_FOUND_MESSAGE
"The Qt tools package requires at least one component.")
set(@INSTALL_CMAKE_NAMESPACE@Tools_FOUND False)
return()
endif()
foreach(module ${@INSTALL_CMAKE_NAMESPACE@Tools_FIND_COMPONENTS})
find_package(@INSTALL_CMAKE_NAMESPACE@${module}Tools
${_@INSTALL_CMAKE_NAMESPACE@Tools_FIND_PARTS_QUIET}
${_@INSTALL_CMAKE_NAMESPACE@Tools_FIND_PARTS_REQUIRED}
PATHS ${_qt_tools_cmake_dir} NO_DEFAULT_PATH
)
if (NOT @INSTALL_CMAKE_NAMESPACE@${module}Tools_FOUND)
string(CONFIGURE ${_qt5_module_location_template} _expected_module_location @ONLY)
if (@INSTALL_CMAKE_NAMESPACE@_FIND_REQUIRED_${module})
set(_Qt_NOTFOUND_MESSAGE
"${_Qt_NOTFOUND_MESSAGE}Failed to find Qt component \"${module}\" config file.")
elseif(NOT Qt_FIND_QUIETLY)
message(WARNING "Failed to find Qt component \"${module}\" config file.")
endif()
unset(_expected_module_location)
endif()
endforeach()
if (_Qt_NOTFOUND_MESSAGE)
set(@INSTALL_CMAKE_NAMESPACE@Tools_NOT_FOUND_MESSAGE "${_Qt_NOTFOUND_MESSAGE}")
set(@INSTALL_CMAKE_NAMESPACE@Tools_FOUND False)
endif()

308
cmake/README.md Normal file
View File

@ -0,0 +1,308 @@
# Status
Initial port is on-going. Some modules of QtBase are ported, incl. some of the platform modules.
Many libraries, tests and examples are still missing.
Basic functionality is there (moc, uic, etc.), but documentation, translations, etc. are missing.
NOTE: YOU NEED CMAKE 3.15 or later.
# Intro
The CMake update offers an opportunity to revisit some topics that came up during the last few
years.
* The Qt build system does not support building host tools during a cross-compilation run. You need
to build a Qt for your host machine first and then use the platform tools from that version. The
decision to do this was reached independent of cmake: This does save resources on build machines
as the host tools will only get built once.
* 3rd-party dependencies are no longer built as part of Qt. zlib, libpng, etc. from src/3rdparty
need to be supplied from the outside to the build now. You may find apt-get/brew/etc. useful for
this. Otherwise you may consider using vcpkg as in the next section. The decision to remove 3rd
party dependencies from Qt repositories was reached independent of the decision to use cmake, we
just use the opportunity to implement this decision.
* There is less need for bootstrapping. Only moc and rcc (plus the lesser known tracegen and
qfloat16-tables) are linking against the bootstrap Qt library. Everything else can link against
the full QtCore. This will include qmake, which is currently missing from a cmake build. This will
change: Qmake is supported as a build system for applications *using* Qt going forward and will
not go away anytime soon.
* For the time being we try to keep qmake working so that we do not interfere too much with ongoing
development.
# Building against VCPKG on Windows
You may use vcpkg to install dependencies needed to build QtBase.
* ```git clone -b qt https://github.com/tronical/vcpkg```
* Run ```bootstrap-vcpkg.bat``` or ```bootstrap-vcpkg.sh```
* Set the ``VCPKG_DEFAULT_TRIPLET`` environment variable to ``qt-x64-windows-static`` or
``qt-x86-windows-static``
* Set the ``VCPKG_ROOT`` environment variable to the path where you cloned vcpkg
* Build Qt dependencies: ``vcpkg install @qt-packages-windows.txt``
* When running cmake in qtbase, support for vcpkg will be picked up automatically when the
VCPKG_ROOT/VCPKG_DEFAULT_TRIPLET environment variable is set.
# Building against homebrew on macOS
You may use brew to install dependencies needed to build QtBase.
* Install homebrew:
```/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"```
* Build Qt dependencies: ``brew install pcre2 harfbuzz freetype``
* Install cmake: ``brew install cmake``
* When running cmake in qtbase, pass ``-DCMAKE_PREFIX_PATH=/usr/local``
# Building
The basic way of building with cmake is as follows:
```
cd {build directory}
cmake -DCMAKE_INSTALL_PREFIX=/path/where/to/install {path to source directory}
cmake --build .
cmake --install .
```
You need one build directory per Qt module. The build directory can be a sub-directory inside the
module ``qtbase/build`` or an independent directory ``qtbase_build``. The installation prefix is
chosen when running cmake by passing ``-DCMAKE_INSTALL_PREFIX``. To build more than one Qt module,
make sure to pass the same install prefix.
``cmake --build`` and ``cmake --install`` are simple wrappers around the basic build tool that CMake
generated a build system for. It works with any supported build backend supported by cmake, but you
can also use the backend build tool directly, e.g. by running ``make``.
CMake has a ninja backend that works quite well and is noticeably faster than make, so you may want
to use that:
```
cd {build directory}
cmake -GNinja -DCMAKE_INSTALL_PREFIX=/path/where/to/install {path to source directory}
cmake --build .
cmake --install .
```
You can look into the generated ``build.ninja`` file if you're curious and you can also build
targets directory such as ``ninja lib/libQt6Core.so``.
Make sure to remove CMakeCache.txt if you forgot to set the CMAKE_INSTALL_PREFIX on the first
configuration, otherwise a second re-configuration will not pick up the new install prefix.
You can use ``cmake-gui {path to build directory}`` or ``ccmake {path to build directory}`` to
configure the values of individual cmake variables or Qt features. After changing a value, you need
to choose the *configure* step (usually several times:-/), followed by the *generate* step (to
generate makefiles/ninja files).
## Developer Build
When working on Qt itself, it can be tedious to wait for the install step. In that case you want to
use the developer build option, to get as many auto tests enabled and no longer be required to make
install:
```
cd {build directory}
cmake -GNinja -DCMAKE_INSTALL_PREFIX=/path/to/qtbase_build -DFEATURE_developer_build=ON {path to source directory}
cmake --build .
# do NOT make install
```
## Specifying configure.json features on the command line
QMake defines most features in configure.json files, like -developer-build or -no-opengl.
In CMake land, we currently generate configure.cmake files from the configure.json files into
the source directory next to them using the helper script
``path_to_qtbase_source/util/cmake/configurejson2cmake.py``. They are checked into the repository.
If the feature in configure.json has the name "dlopen", you can specify whether to enable or disable that
feature in CMake with a -D flag on the CMake command line. So for example -DFEATURE_dlopen=ON or
-DFEATURE_sql_mysql=OFF. At the moment, if you change a FEATURE flag's value, you have to remove the
CMakeCache.txt file and reconfigure with CMake. And even then you might stumble on some issues when
reusing an existing build, because of an automoc bug in upstream CMake.
## Ninja reconfiguration bug
If you use the Ninja generator, there's a bug that after the first CMake configuration, if you run
ninja, it will do the reconfiguration step again. This is quite annoying and time consuming.
There is an open pull request that fixes the issue at
https://github.com/ninja-build/ninja/pull/1527. You can build your own Ninja executable until the
request is merged.
```
cd {some directory}
git clone https://github.com/ninja-build/ninja.git
cd ninja && mkdir build && cd build
git remote add fix git@github.com:mathstuf/ninja.git && git fetch --all
git cherry-pick 29a565f18e01ce83ca14801f4684cd2acaf00d4c
../configure.py --bootstrap
cp ninja /usr/local/bin/ninja
```
## Building with CCache
You can pass ``-DQT_USE_CCACHE=ON`` to make the build system look for ``ccache`` in your ``PATH``
and prepend it to all C/C++/Objective-C compiler calls. At the moment this is only supported for the
Ninja and the Makefile generators.
## Cross Compiling
Compiling for a target architecture that's different than the host requires one build of Qt for the
host. This "host build" is needed because the process of building Qt involves the compilation of
intermediate code generator tools, that in turn are called to produce source code that needs to be
compiled into the final libraries. These tools are built using Qt itself and they need to run on the
machine you're building on, regardless of the architecure you are targeting.
Build Qt regularly for your host system and install it into a directory of your choice using the
``CMAKE_INSTALL_PREFIX`` variable. You are free to disable the build of tests and examples by
passing ``-DBUILD_EXAMPLES=OFF`` and ``-DBUILD_TESTING=OFF``.
With this installation of Qt in place, which contains all tools needed, we can proceed to create a
new build of Qt that is cross-compiled to the target architecture of choice. You may proceed by
setting up your environment. The CMake wiki has further information how to do that at
<https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling>
Yocto based device SDKs come with an environment setup script that needs to be sourced in your shell
and takes care of setting up environment variables and a cmake alias with a toolchain file, so that
you can call cmake as you always do.
In order to make sure that Qt picks up the code generator tools from the host build, you need to
pass an extra parameter to cmake:
```
-DQT_HOST_PATH=/path/to/your/host_build
```
The specified path needs to point to a directory that contains an installed host build of Qt.
### Cross Compiling for Android
In order to cross-compile Qt to Android, you need a host build (see instructions above) and an
Android build. In addition, it is necessary to install the Android NDK as well as vcpkg. Vcpkg is
needed to supply third-party libraries that Qt requires but that are not part of the Android NDK.
Vcpkg for Android can be set up using the following steps:
* ```git clone -b qt https://github.com/tronical/vcpkg```
* Run ```bootstrap-vcpkg.bat``` or ```bootstrap-vcpkg.sh```
* Set the ``VCPKG_DEFAULT_TRIPLET`` environment variable to one of the following values:
* ``arm-android`` (armeabi-v7a)
* ``arm64-android`` (arm64v8)
* ``x86-android`` (x86)
* ``x64-android`` (x86_64)
* Set the ``VCPKG_ROOT`` environment variable to the path where you cloned vcpkg
* Set the ``ANDROID_NDK_HOME`` environment variable to the path where you have installed the Android NDK.
* Set the ``ANDROID_SDK_HOME`` environment variable to the path where you have installed the Android SDK.
* Build Qt dependencies: ``vcpkg install @qt-packages-android.txt``
When running cmake in qtbase, pass
``-DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake -DQT_HOST_PATH=/path/to/your/host/build -DANDROID_SDK_ROOT=$ANDROID_SDK_HOME -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH``
If you don't supply the configuration argument ``-DANDROID_ABI=...``, it will default to
``armeabi-v7a``. To target other architectures, use one of the following values:
* arm64: ``-DANDROID_ABI=arm64-v8``
* x86: ``-DANDROID_ABI=x86``
* x86_64: ``-DANDROID_ABI=x86_64``
By default we set the android API level to 21. Should you need to change this supply the following
configuration argument to the above CMake call: ``-DANDROID_NATIVE_API_LEVEL=${API_LEVEL}``
### Cross compiling for iOS
In order to cross-compile Qt to iOS, you need a host macOS build.
In addition, it is necessary to install a custom version of vcpkg. Vcpkg is
needed to supply third-party libraries that Qt requires, but that are not part of the iOS SDK.
Vcpkg for iOS can be set up using the following steps:
* ```git clone -b qt https://github.com/alcroito/vcpkg```
* Run ```bootstrap-vcpkg.sh```
* Set the ``VCPKG_DEFAULT_TRIPLET`` environment variable to one of the following values:
* ``x64-ios`` (simulator x86_64)
* ``x86-ios`` (simulator i386)
* ``arm64-ios`` (device arm64)
* ``arm-ios`` (device armv7)
* ``fat-ios`` (simulator_and_device x86_64 and arm64* - special considedrations)
* Set the ``VCPKG_ROOT`` environment variable to the path where you cloned vcpkg
* Build Qt dependencies: ``vcpkg install @qt-packages-ios.txt``
When running cmake in qtbase, pass
``-DCMAKE_SYSTEM_NAME=iOS -DQT_HOST_PATH=/path/to/your/host/build -DCMAKE_INSTALL_PREFIX=$INSTALL_PATH``
If you don't supply the configuration argument ``-DQT_UIKIT_SDK=...``, it will default to
``iphonesimulator``. To target another SDK / device type, use one of the following values:
* iphonesimulator: ``-DQT_UIKIT_SDK=iphonesimulator``
* iphoneos: ``-DQT_UIKIT_SDK=iphoneos``
* simulator_and_device: ``-DQT_FORCE_SIMULATOR_AND_DEVICE=ON -DQT_UIKIT_SDK=``
Depending on what value you pass to ``-DQT_UIKIT_SDK=`` a list of target architectures is chosen
by default:
* iphonesimulator: ``x86_64``
* iphoneos: ``arm64``
* simulator_and_device: ``arm64;x86_64``
You can try choosing a different list of architectures by passing
``-DCMAKE_OSX_ARCHITECTURES=x86_64;i386``.
Note that if you choose different architectures compared to the default ones, the build might fail.
Only do it if you know what you are doing.
#### simulator_and_device special considerations
To do a simulator_and_device build, a custom version of CMake is required in addition to the vcpkg
fork. The merge request can be found here:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3617
After you build your own copy of CMake using this merge request, you need to use it for both
vcpkg and Qt.
Note that vcpkg prefers its own version of CMake when building packages.
Make sure to put your custom built CMake in PATH, and force vcpkg to use this CMake by running
``export VCPKG_FORCE_SYSTEM_BINARIES=1`` in your shell.
# Debugging CMake files
CMake allows specifying the ``--trace`` and ``--trace-expand`` options, which work like
``qmake -d -d``: As the cmake code is evaluated, the values of parameters and variables is shown.
This can be a lot of output, so you may want to redirect it to a file.
# Porting Help
We have some python scripts to help with the conversion from qmake to cmake. These scripts can be
found in ``utils/cmake``.
## configurejson2cmake.py
This script converts all ``configure.json`` in the Qt repository to ``configure.cmake`` files for
use with CMake. We want to generate configure.cmake files for the foreseeable future, so if you need
to tweak the generated configure.cmake files, please tweak the generation script instead.
``configurejson2cmake.py`` is run like this: ``util/cmake/configurejson2cmake.py .`` in the
top-level source directory of a Qt repository.
## pro2cmake.py
``pro2cmake.py`` generates a skeleton CMakeLists.txt file from a .pro-file. You will need to polish
the resulting CMakeLists.txt file, but e.g. the list of files, etc. should be extracted for you.
``pro2cmake.py`` is run like this: ``path_to_qtbase_source/util/cmake/pro2cmake.py some.pro``.
## run_pro2cmake.py
`` A small helper script to run pro2cmake.py on all .pro-files in a directory. Very useful to e.g.
convert all the unit tests for a Qt module over to cmake;-)
``run_pro2cmake.py`` is run like this: ``path_to_qtbase_source/util/cmake/run_pro2cmake.py some_dir``.
## How to convert certain constructs
| qmake | CMake |
| ------ | ------ |
| ``qtHaveModule(foo)`` | ``if(TARGET Qt::foo)`` |
| ``qtConfig(foo)`` | ``if (QT_FEATURE_foo)`` |

View File

@ -0,0 +1,20 @@
list(APPEND CMAKE_PREFIX_PATH "@CMAKE_INSTALL_PREFIX@")
list(APPEND CMAKE_FIND_ROOT_PATH "@CMAKE_INSTALL_PREFIX@")
@init_platform@
@init_qt_host_path@
@init_original_toolchain_file@
@init_vcpkg@
if(qt_chainload_toolchain_file)
include("${qt_chainload_toolchain_file}")
unset(qt_chainload_toolchain_file)
endif()
if(QT_HOST_PATH)
list(APPEND CMAKE_PREFIX_PATH "${QT_HOST_PATH}")
list(APPEND CMAKE_FIND_ROOT_PATH "${QT_HOST_PATH}")
endif()

View File

@ -0,0 +1,48 @@
# These macros are inspired by ECM:
# a macro for tests that have a simple format where the name matches the
# directory and project
# The following macros will produce tests that generate the build
# system for the test project, build it and then run its tests.
macro(add_cmake_test_generate_build_run_variant name base command)
string(REPLACE "." "/" src_dir "${base}")
string(REPLACE "." "/" build_dir "${name}")
string(REGEX REPLACE "[^.]*\\." "" proj "${name}")
add_test(NAME "cmake_${name}"
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/${src_dir}"
"${CMAKE_CURRENT_BINARY_DIR}/${build_dir}"
--build-two-config
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-project ${proj}
${${name}_EXTRA_OPTIONS}
--test-command ${command} ${ARGN})
endmacro()
macro(add_cmake_test_generate_build_run name)
add_cmake_test_generate_build_run_variant("${name}" "${name}" ${ARGN})
endmacro()
# The following macros will produce tests that just run cmake
# to generate the build system for the test project.
macro(add_cmake_test_generate_variant name base)
string(REPLACE "." "/" src_dir "${base}")
string(REPLACE "." "/" build_dir "${name}")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${build_dir}")
add_test(NAME "cmake_${name}"
COMMAND "${CMAKE_COMMAND}" "-G${CMAKE_GENERATOR}"
"-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}"
${${name}_EXTRA_OPTIONS}
"${CMAKE_CURRENT_SOURCE_DIR}/${src_dir}"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${build_dir}")
endmacro()
macro(add_cmake_test_generate name)
add_cmake_test_generate_variant("${name}" "${name}")
endmacro()
add_cmake_test_generate(features)
add_cmake_test_generate(qt_make_output_file)

0
cmake/tests/empty.cpp Normal file
View File

View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 3.12.0)
project(FeaturesTest
VERSION 1.0.0
DESCRIPTION "QtFeature test"
HOMEPAGE_URL "https://qt.io/"
LANGUAGES CXX C
)
## Add some paths to check for cmake modules:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../;${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/extra-cmake-modules/find-modules;${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/kwin")
## Qt specific setup common for all modules:
include(QtSetup)
## Library to hold global features:
add_library(GlobalConfig INTERFACE)
qt_feature_module_begin(LIBRARY GlobalConfig
PUBLIC_FILE src/corelib/global/qconfig.h
PRIVATE_FILE src/corelib/global/qconfig_p.h
)
include("${CMAKE_CURRENT_SOURCE_DIR}/configure.cmake")
qt_feature_module_end(GlobalConfig)
assert(QT_FEATURE_top_a STREQUAL "ON")
assert(QT_FEATURE_top_b STREQUAL "OFF")
assert(QT_FEATURE_top_enabled STREQUAL "ON")
assert(QT_FEATURE_top_disabled STREQUAL "OFF")
assert(QT_FEATURE_top_disabled_enabled STREQUAL "OFF")
assert(QT_FEATURE_top_not_emitted STREQUAL "OFF")
## Enable feature summary at the end of the configure run:
include(FeatureSummary)
add_subdirectory(src)
## Delayed actions on some of the Qt targets:
include(QtPostProcess)
## Print a feature summary:
feature_summary(WHAT PACKAGES_FOUND PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES)

View File

@ -0,0 +1,35 @@
#### Features
# This belongs into gui, but the license check needs it here already.
qt_feature("top_a" PRIVATE
LABEL "top_a"
CONDITION ON
)
qt_feature("top_b" PUBLIC PRIVATE
LABEL "top_b"
AUTODETECT OFF
)
qt_feature_definition("top_a" "top_defa")
qt_feature("top_enabled" PRIVATE
LABEL "top_enabled"
ENABLE ON
)
qt_feature("top_disabled" PRIVATE
LABEL "top_enabled"
DISABLE ON
)
qt_feature("top_disabled_enabled" PRIVATE
LABEL "top_enabled_enabled"
DISABLE ON
ENABLE ON
)
qt_feature("top_not_emitted" PRIVATE
LABEL "top_not_emitted"
EMIT_IF OFF
)
qt_extra_definition("top_extra" "PUBLIC_FOO" PUBLIC)

View File

@ -0,0 +1,7 @@
## Features from parent scope were inherited:
assert(QT_FEATURE_top_a STREQUAL "ON")
assert(QT_FEATURE_top_b STREQUAL "OFF")
assert(QT_FEATURE_top_enabled STREQUAL "ON")
assert(QT_FEATURE_top_disabled STREQUAL "OFF")
assert(QT_FEATURE_top_disabled_enabled STREQUAL "OFF")
assert(QT_FEATURE_top_not_emitted STREQUAL "OFF")

1
cmake/tests/main.cpp Normal file
View File

@ -0,0 +1 @@
int main(int argc, char** argv) { return 0; }

View File

@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.12.0)
project(QtMakeOutputFileTest
VERSION 1.0.0
DESCRIPTION "qt_make_output_file test"
HOMEPAGE_URL "https://qt.io/"
LANGUAGES CXX C
)
## Add some paths to check for cmake modules:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../;${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/extra-cmake-modules/find-modules;${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/kwin")
include(QtBuild)
qt_make_output_file("foo.cpp" "" ".mapped" "/tmp/foo" "/tmp/bar" outfile)
assert(outfile STREQUAL "/tmp/bar/foo.mapped")
qt_make_output_file("../foo.cpp" "prefix_" ".cpp" "/tmp/foo" "/tmp/bar" outfile)
assert(outfile STREQUAL "/tmp/bar/__/prefix_foo.cpp")
qt_make_output_file("/tmp/bar/foo.cpp" "prefix_" ".cpp" "/tmp/foo" "/tmp/bar" outfile)
assert(outfile STREQUAL "/tmp/bar/prefix_foo.cpp")

54
cmake/tests/test.cmake Normal file
View File

@ -0,0 +1,54 @@
# FAKE moc-ing:
set(QT_MOCSCANNER /usr/bin/true)
# Fake mocscanner run.
# The files passed in after MOC will be reported to be in need of moc-ing,
# but will not be built.
# The files passed in after MOC_AND_BUILD will be reported to be in need
# of moc-ing and should also be built by the target.
function(fake_moc_results)
cmake_parse_arguments(arg "" "" "MOC;MOC_AND_BUILD" ${ARGN})
string(REPLACE ";" "\n" arg_MOC "${arg_MOC}")
string(REPLACE ";" "\n" arg_MOC_AND_BUILD "${arg_MOC_AND_BUILD}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/moc_files_included.txt" "${arg_MOC}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/moc_files_to_build.txt" "${arg_MOC_AND_BUILD}")
endfunction()
# Test whether a target has a file listed in its sources.
# Tests with the BUILD flag set will require this file to be built,
# while those without will require the file to not be built by
# the target.
function(test_source_file target file)
cmake_parse_arguments(arg "BUILD" "" "" ${ARGN})
get_target_property(sources "${target}" SOURCES)
list(FIND sources "${file}" source_pos)
assert(NOT source_pos STREQUAL "-1")
get_source_file_property(prop "${file}" HEADER_FILE_ONLY)
if (arg_BUILD)
assert(NOT prop)
else()
assert(prop)
endif()
endfunction()
# Test whether or not a target uses a header path
# The test passes when the path is in the list of include directories.
# Passing 'UNKNOWN' to this function reverses the test result.
function(test_include_directory target path)
cmake_parse_arguments(arg "UNKNOWN" "" "" ${ARGN})
get_target_property(includes "${target}" INCLUDE_DIRECTORIES)
list(FIND includes "${path}" include_pos)
if(arg_UNKNOWN)
assert(include_pos STREQUAL "-1")
else()
assert(NOT include_pos STREQUAL "-1")
endif()
endfunction()
# Add Core and Qt::Core libraries:
add_library(Core SHARED "${CMAKE_CURRENT_LIST_DIR}/empty.cpp")
add_library(Qt::Core ALIAS Core)

View File

@ -0,0 +1,24 @@
type: Group
instructions:
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} {{.InstallDir}}\\bin\\qt-cmake {{.Env.COIN_CMAKE_ARGS}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to call cmake. Contact Liang then.
enable_if:
condition: property
property: host.os
equals_value: Windows
- type: ExecuteCommand
command: "{{.InstallDir}}/bin/qt-cmake {{.Env.COIN_CMAKE_ARGS}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to call cmake. Contact Liang then.
disable_if:
condition: property
property: host.os
equals_value: Windows

View File

@ -0,0 +1,29 @@
type: Group
instructions:
- type: ChangeDirectory
directory: "{{.SourceDir}}"
- type: MakeDirectory
directory: "standalone_tests"
- type: SetBuildDirectory
directory: "{{.SourceDir}}/standalone_tests"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: EnvironmentVariable
variableName: COIN_CMAKE_ARGS
variableValue: "-DQT_BUILD_STANDALONE_TESTS=ON -S {{.SourceDir}} -B ."
- !include "{{qt/qtbase}}/call_cmake.yaml"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --build . --parallel"
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to build sources. In the current state bug can be everywhere. Contact Liang first.
- type: UploadTestArtifact
transferType: UploadModuleTestsArtifact
archiveDirectory: "{{.BuildDir}}"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200
disable_if:
condition: property
property: configureArgs
contains_value: "-DBUILD_SHARED_LIBS=OFF"

View File

@ -0,0 +1,58 @@
type: Group
instructions:
- type: MakeDirectory
directory: .git
- type: MakeDirectory
directory: build
- type: ChangeDirectory
directory: "{{.BuildDir}}/build"
- type: MakeDirectory
directory: host
- type: MakeDirectory
directory: target
- type: SetBuildDirectory
directory: "{{.SourceDir}}/build/host"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake {{.Env.CONFIGURE_ARGS}} -DCMAKE_INSTALL_PREFIX:PATH={{.InstallDir}}/host -DBUILD_TESTING=OFF {{.SourceDir}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to call cmake. Contact Liang then.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --build . --parallel"
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to build sources. In the current state bug can be everywhere. Contact Liang first.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package.
- type: SetBuildDirectory
directory: "{{.SourceDir}}/build/target"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake {{.Env.TARGET_CONFIGURE_ARGS}} -DQT_HOST_PATH={{.InstallDir}}/host -DCMAKE_INSTALL_PREFIX:PATH={{.InstallDir}}/target -DBUILD_TESTING=OFF {{.SourceDir}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to call cmake. Contact Liang then.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --build . --parallel"
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to build sources. In the current state bug can be everywhere. Contact Liang first.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package.

View File

@ -0,0 +1,46 @@
type: Group
instructions:
- type: MakeDirectory
directory: .git
- type: SetBuildDirectory
directory: "{{.SourceDir}}"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: EnvironmentVariable
variableName: COIN_CMAKE_ARGS
variableValue: "-DBUILD_TESTING=OFF {{.SourceDir}}"
- !include "{{qt/qtbase}}/call_cmake.yaml"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --build . --parallel"
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to build sources. In the current state bug can be everywhere. Contact Liang first.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package.
- type: EnvironmentVariable
variableName: DESTDIR
variableValue: "{{.InstallRoot}}"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package for archiving.
- type: SignPackage
enable_if:
condition: property
property: host.os
equals_value: Windows
directory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200
- type: UploadArtifact
archiveDirectory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
transferType: UploadModuleBuildArtifact
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200

View File

@ -0,0 +1,49 @@
type: Group
instructions:
- type: MakeDirectory
directory: .git
- type: SetBuildDirectory
directory: "{{.SourceDir}}"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake {{.Env.CONFIGURE_ARGS}} -DCMAKE_INSTALL_PREFIX:PATH={{.InstallDir}} -DBUILD_TESTING=OFF {{.SourceDir}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to call cmake. Contact Liang then.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --build . --parallel"
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to build sources. In the current state bug can be everywhere. Contact Liang first.
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package.
- type: EnvironmentVariable
variableName: DESTDIR
variableValue: "{{.InstallRoot}}"
- type: ExecuteCommand
command: "{{.Env.ENV_PREFIX}} cmake --install ."
maxTimeInSeconds: 6000
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install package for archiving.
- type: SignPackage
enable_if:
condition: property
property: host.os
equals_value: Windows
directory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200
- type: UploadArtifact
archiveDirectory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
transferType: UploadModuleBuildArtifact
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200

View File

@ -0,0 +1,26 @@
type: Group
instructions:
- type: ChangeDirectory
directory: "{{.SourceDir}}"
- type: MakeDirectory
directory: "standalone_tests"
- type: InstallTestBinaryArchive
relativeStoragePath: "{{.Env.MODULE_ARTIFACTS_RELATIVE_STORAGE_PATH}}/tests.tar.gz"
directory: "{{.SourceDir}}/standalone_tests"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200
userMessageOnFailure: >
Failed to install tests archive.
- type: ChangeDirectory
directory: "{{.SourceDir}}/standalone_tests"
- type: ExecuteCommand
command: "ctest -V --rerun-failed"
ignoreExitCode: true
maxTimeInSeconds: 7200
maxTimeBetweenOutput: 900
userMessageOnFailure: >
Failed to run tests.
disable_if:
condition: property
property: configureArgs
contains_value: "-DBUILD_SHARED_LIBS=OFF"

View File

@ -0,0 +1,202 @@
# Prepares environment for building Qt module. It sets all important environment variables in particular
# configures the right compiler and cmake generator
type: Group
instructions:
# Set default cmake generator, it may be overwritten later
- type: EnvironmentVariable
variableName: CMAKE_GENERATOR
variableValue: Ninja
# Export ICC specific env. variables
- type: Group
instructions:
- type: EnvironmentVariable
variableName: LD_LIBRARY_PATH
variableValue: "{{.Env.ICC64_18_LDLP}}"
- type: PrependToEnvironmentVariable
variableName: PATH
variableValue: "{{.Env.ICC64_18_PATH}}"
enable_if:
condition: property
property: host.compiler
equals_value: ICC_18
# Set CMAKE_C[XX]_COMPILER otherwise cmake may prioritize a wrong compiler
- type: Group
instructions:
- type: PrependToEnvironmentVariable
variableName: CONFIGURE_ARGS
variableValue: "-DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc "
enable_if:
condition: property
property: host.compiler
contains_value: ICC
- type: PrependToEnvironmentVariable
variableName: CONFIGURE_ARGS
variableValue: "-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ "
enable_if:
condition: property
property: host.compiler
contains_value: GCC
- type: PrependToEnvironmentVariable
variableName: CONFIGURE_ARGS
variableValue: "-DCMAKE_C_COMPILER=cl.exe -DCMAKE_CXX_COMPILER=cl.exe "
enable_if:
condition: property
property: host.compiler
contains_value: MSVC
- type: PrependToEnvironmentVariable
variableName: CONFIGURE_ARGS
variableValue: "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ "
enable_if:
condition: property
property: host.compiler
contains_value: Clang
# Export TARGET_ARCHITECTURE and WINDOWS_SDK_VERSION for MSVC cross compilation
- type: Group
enable_if:
condition: property
property: host.os
equals_value: Windows
instructions:
- type: EnvironmentVariable
variableName: TARGET_ARCHITECTURE
variableValue: amd64 # TODO add something like "{{toLower .Config host.arch}}"
disable_if:
condition: property
property: host.arch
not_equals_property: target.arch
- type: EnvironmentVariable
variableName: TARGET_ARCHITECTURE
variableValue: amd64_x86
enable_if:
condition: and
conditions:
- condition: property
property: target.arch
equals_property: X86
- condition: property
property: host.arch
equals_property: X86_64
- type: EnvironmentVariable
# HACK. Overwrite TARGET_ARCHITECTURE as we do not use standard MSVC cross
# compilation targets here. The target architecture will be detected by Qt.
variableName: TARGET_ARCHITECTURE
variableValue: x86
enable_if:
condition: property
property: target.os
in_values: ["WINRT", "WINPHONE", "WINCE"]
- type: EnvironmentVariable
variableName: WINDOWS_SDK_VERSION
variableValue: "10.0.14393.0"
enable_if:
condition: property
property: target.os
equals_value: WINRT
- type: EnvironmentVariable
variableName: WINDOWS_SDK_VERSION
variableValue: ""
disable_if:
condition: property
property: host.os
equals_value: WINRT # TODO set windows sdk version for desktop windows as well
# MSVC is installed in somehow arbitrary places. To reduce amount of combinations we need to make a variable.
# This seems inverted, but on 64 bit hosts VS is installed into the x86 path, otherwise the regular one
# TODO cleanup, that step could be removed if we have same installation paths or we read the path from registry
# or we use compiler specific generator (probably superior solution as it allows to get rid of ENV_PREFIX).
- type: Group
enable_if:
condition: property
property: host.os
equals_value: Windows
instructions:
# Try to pick one of many coexistent MSVC installation to use
# TODO cleanup, that could be much simpler if all tools are installed to similar paths, so it would
# be enough to substitute compiler name.
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%VS90COMNTOOLS%\\vsvars32.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2008
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%VS100COMNTOOLS%\\vsvars32.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2010
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio 11.0\\VC\\vcvarsall.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2012
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2013
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2015
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio\\2017\\Professional\\VC\\Auxiliary\\Build\\vcvarsall.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2017
- type: EnvironmentVariable
variableName: VC_SCRIPT
variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio\\2019\\Professional\\VC\\Auxiliary\\Build\\vcvarsall.bat"
enable_if:
condition: property
property: host.compiler
equals_value: MSVC2019
# With MSVC we need setup the environment before every subprocess call, the group below creates a script that
# does it. It is enough to prepand it to every call (it is safe to add it even on other OSes)
- type: Group
instructions:
- type: WriteFile
fileContents: "call \"{{.Env.VC_SCRIPT}}\" {{.Env.TARGET_ARCHITECTURE}} {{.Env.WINDOWS_SDK_VERSION}}\r\ncmd /c %*"
filename: c:\\users\\qt\\prefix.bat
fileMode: 420
maxTimeInSeconds: 20
maxTimeBetweenOutput: 20
enable_if:
condition: property
property: host.os
equals_value: Windows
- type: EnvironmentVariable
variableName: ENV_PREFIX
variableValue: "c:\\users\\qt\\prefix.bat"
enable_if:
condition: property
property: host.os
equals_value: Windows
- type: EnvironmentVariable
variableName: ENV_PREFIX
variableValue: ""
disable_if:
condition: property
property: host.os
equals_value: Windows

40
coin/module_config.yaml Normal file
View File

@ -0,0 +1,40 @@
version: 2
accept_configuration:
condition: property
property: features
not_contains_value: Disable
instructions:
Build:
- !include "{{qt/qtbase}}/prepare_building_env.yaml"
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_qtbase_build_instructions.yaml"
- !include "{{qt/qtbase}}/cmake_build_and_upload_test_artifacts.yaml"
enable_if:
condition: property
property: host.os
equals_property: target.os
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_cross_compilation.yaml"
disable_if:
condition: property
property: host.os
equals_property: target.os
Test:
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_regular_test_instructions.yaml"
enable_if:
condition: property
property: host.os
equals_property: target.os
- type: EnvironmentVariable
variableName: Dummy
variableValue: dummy
disable_if:
condition: property
property: host.os
equals_property: target.os

View File

@ -0,0 +1,6 @@
cmake_minimum_required(VERSION 3.15.0)
project(arch LANGUAGES CXX)
add_executable(architecture_test)
set_property(TARGET architecture_test PROPERTY MACOSX_BUNDLE FALSE)
target_sources(architecture_test PRIVATE arch.cpp)

View File

@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.14.0)
project(x86_simd LANGUAGES CXX)
include(../../cmake/QtPlatformSupport.cmake)
include(../../cmake/QtCompilerOptimization.cmake)
# FIXME: Make the this project handle a list of SIMD entries.
# FIXME: Make this project handle appending of the cflags (similar to the qmake project).
# This is needed for the x86SimdAlways configure test (
# aka we test to see if setting no SIMD (-msse2) cflags at all, will result in their implicit
# addition by the compiler).
string(TOUPPER "${SIMD}" upper_simd)
if(NOT DEFINED "QT_CFLAGS_${upper_simd}")
# Don't use CMake error() because a configure error also fails the try_compile() call.
# Instead use a compile flag that doesn't exist to force a compiler error.
set(QT_CFLAGS_${upper_simd} "--qt-cflags-not-found")
endif()
add_executable("SimdTest${SIMD}")
target_sources("SimdTest${SIMD}" PRIVATE main.cpp)
target_compile_options("SimdTest${SIMD}" PRIVATE ${QT_CFLAGS_${upper_simd}})
target_compile_definitions("SimdTest${SIMD}" PRIVATE QT_COMPILER_SUPPORTS_${upper_simd})

Some files were not shown because too many files have changed in this diff Show More