24 Commits

Author SHA1 Message Date
52169e98a5 Create README.md 2023-12-04 20:09:24 +01:00
cc07a7df8b Merge pull request #6 from crystalidea/6.6.1
6.6.1
2023-12-04 20:06:40 +01:00
d32a416512 6.6.1 works 2023-12-04 20:06:20 +01:00
8490fae44c 6.6.1 original 2023-12-04 18:42:35 +01:00
9bf343ceed Update README.md 2023-12-01 12:42:17 +01:00
c5ebb342ac Update README.md 2023-11-27 08:17:33 +01:00
b136018dc3 Update README.md 2023-11-19 21:20:42 +01:00
e246b58a73 Update README.md 2023-11-19 21:19:57 +01:00
58b7094ab8 Update README.md 2023-11-19 21:18:54 +01:00
db6500c186 remove tests 2023-11-17 12:00:54 +01:00
c52a8888af Update README.md 2023-11-02 21:25:23 +01:00
330da82961 Update README.md 2023-11-02 21:04:33 +01:00
6966cfe30f Update README.md 2023-11-02 21:03:10 +01:00
0e93ccbc9c Merge branch 'master' of https://github.com/crystalidea/qt6windows7 2023-11-02 20:57:24 +01:00
18a0664193 don't use github automated tests 2023-11-02 20:57:09 +01:00
551e626412 Update README.md 2023-11-02 20:56:20 +01:00
830f14f0d9 Update README.md 2023-11-02 20:55:18 +01:00
2c121a6f62 Merge pull request #2 from crystalidea/6.6.0
6.6.0
2023-11-02 20:47:57 +01:00
a8ff2e3e8b 6.6.0 - windows 7 compatibility works 2023-11-02 20:47:38 +01:00
5cf9645728 current work with 6.6.0 (not working at the moment, problem with platform plugin) 2023-11-02 15:30:17 +01:00
f877a73214 Update README.md 2023-11-02 15:19:10 +01:00
92f83d3ae6 Create README.md 2023-11-02 15:18:41 +01:00
5d8194efa7 qt 6.6.0 clean 2023-11-01 22:23:55 +01:00
7b5ada15e7 Merge pull request #1 from crystalidea/6.5.3
qt 6.5.3 with win7 support
2023-11-01 22:18:27 +01:00
12386 changed files with 81169 additions and 2372625 deletions

View File

@ -5,10 +5,9 @@
# (directly by qtbase) we actually add the extra definitions
if (NOT DEFINED QT_SUPERBUILD OR DEFINED QT_REPO_MODULE_VERSION)
set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_LEAN_HEADERS=1")
list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1")
endif()
set(QT_REPO_MODULE_VERSION "6.5.3")
set(QT_REPO_MODULE_VERSION "6.6.1")
set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1")
set(QT_COPYRIGHT_YEAR "2023")
@ -17,12 +16,14 @@ set(QT_COPYRIGHT "Copyright (C) ${QT_COPYRIGHT_YEAR} The Qt Company Ltd and othe
# Minimum requirement for building Qt
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED "3.16")
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_STATIC "3.21")
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_APPLE "3.21")
# Minimum requirement for consuming Qt in a user project.
# This might be different in the future, e.g. be lower than the requirement for
# building Qt.
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED "3.16")
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC "3.21")
set(QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_APPLE "3.21")
# Policy settings for commands defined by qtbase. These will also be injected
# into the top level policy scope of each Qt module when building Qt so that

View File

@ -1,154 +0,0 @@
# Smoke builds
#
# The goal of this workflow is to finish as fast as possible. Therefore some
# choices have been made:
# - no optimizations
# - link to system-provided libraries instead of building
# bundled 3rd party libraries
# - ccache
name: Smoke build
on: push
env:
BRANCH: dev
BRANCH_REF: refs/heads/dev
defaults:
run:
shell: bash
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- name: ubuntu-20.04
os: ubuntu-20.04
# NOTE: system libmd4c is not detected
deps: libgl-dev libglu-dev 'libxcb*-dev' libx11-xcb-dev libxkbcommon-x11-dev libpcre2-dev libz-dev libfreetype6-dev libpng-dev libjpeg-dev libsqlite3-dev libharfbuzz-dev libb2-dev libdouble-conversion-dev libmd4c-dev
tools: ninja-build ccache
install_cmd: sudo apt-get -y install
configure_flags: -xcb -system-sqlite -system-pcre -system-zlib -system-freetype -system-libpng -system-libjpeg -system-harfbuzz -system-libb2 -system-doubleconversion -system-libmd4c
- name: ubuntu-18.04
os: ubuntu-18.04
# NOTE: system libb2 is not detected because version < 0.98.1 lacks pkg-config module
# NOTE: system libharfbuzz is not detected because system has old version
deps: libgl-dev libglu-dev 'libxcb*-dev' libx11-xcb-dev libxkbcommon-x11-dev libpcre2-dev libz-dev libfreetype6-dev libpng-dev libjpeg-dev libsqlite3-dev libharfbuzz-dev libb2-dev libdouble-conversion-dev
tools: ninja-build ccache gcc-10
install_cmd: sudo apt-get -y install
configure_flags: -xcb -system-sqlite -system-pcre -system-zlib -system-freetype -system-libpng -system-libjpeg -system-harfbuzz -system-libb2 -system-doubleconversion
- name: macos-10.15
os: macos-10.15
deps: jpeg sqlite libpng pcre2 harfbuzz freetype libb2 double-conversion
tools: ninja ccache pkg-config
install_cmd: HOMEBREW_NO_INSTALL_CLEANUP=1 brew install
# Specifically on macOS pkg_config has to be manually turned on otherwise libraries under /usr/local are not detected.
configure_flags: -pkg-config -system-sqlite -system-pcre -system-zlib -system-freetype -system-libpng -system-libjpeg -system-harfbuzz -system-libb2 -system-doubleconversion
- name: windows-2019
os: windows-2019
install_cmd: choco install
install_cmd_postfix: --yes --no-progress
# Chocolatey sqlite package does not come with headers, so we build with bundled sqlite.
#deps: sqlite
# ccache installed separately later in order to force version
tools: ninja
# We don't want the system headers / libraries from Strawberry Perl while compiling with MinGW 8.1.0
configure_flags: -qt-sqlite -qt-pcre -qt-zlib -qt-freetype -qt-libpng -qt-libjpeg -qt-harfbuzz -no-feature-sql-psql -no-feature-sql-mysql -no-feature-sql-odbc
runs-on: ${{ matrix.os }}
steps:
- name: prepare Linux
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100
- name: prepare macOS
if: runner.os == 'macOS'
run: echo noop
- name: prepare Windows
if: runner.os == 'Windows'
# Header pthread.h from postgres is included and creates issues.
# Also library zlib.lib is linked instead of the system one.
run: |
rm -rf "C:/Program Files/PostgreSQL/"
choco install ccache --version 3.7.12 --yes --no-progress --not-silent --verbose --debug
- uses: actions/checkout@v2
with:
path: source
- name: restore ccache
id: ccache
uses: actions/cache@v2
with:
path: ${{ runner.temp }}/ccache
# "github.run_id" is unique, which causes the cache to always get
# saved at the end of a successful run.
key: ccache-${{ matrix.os }}-${{ github.ref }}-${{ github.run_id }}
# As the unique "key" above will never be found in the cache when the
# job starts, we need these broader "restore-keys" in order to match
# and restore the most recent cache.
restore-keys: |
ccache-${{ matrix.os }}-${{ github.ref }}-
ccache-${{ matrix.os }}-${{ env.BRANCH_REF }}-
ccache-${{ matrix.os }}-refs/heads/dev-
ccache-${{ matrix.os }}-
- name: install build dependencies
run: ${{ matrix.install_cmd }} ${{ matrix.deps }} ${{ matrix.install_cmd_postfix }}
if: matrix.deps != ''
- name: install compiler tools
run: ${{ matrix.install_cmd }} ${{ matrix.tools }} ${{ matrix.install_cmd_postfix }}
- name: configure ccache
run: |
ccache --set-config sloppiness=file_macro,time_macros
ccache --set-config cache_dir='${{ runner.temp }}'/ccache
ccache --set-config compression=true
ccache --set-config max_size=1G
- name: print versions and environment
run: |
gcc --version | head -1
cmake --version | head -1
echo Ninja `ninja --version`
{ ninja --help || true ; } 2>&1 | grep "run N jobs in parallel"
ccache --version | head -1
ccache --show-config || echo 'Old ccache version does not support --show-config'
echo Environment:
printenv
- name: make build directory
run: mkdir build
- name: configure
working-directory: build
run: "../source/configure -opensource -confirm-license -ccache -no-pch
-debug -nomake tests -nomake examples
-prefix '${{ runner.temp }}'/install_dir
${{ matrix.configure_flags }}"
- name: ninja
working-directory: build
run: ninja
- name: various stats
# Print ccache utilization statistics, then reset them.
run: |
ccache -s
ccache -x 2>/dev/null || true
ccache -z
- name: print logfiles and other info in case of failure
if: ${{ failure() }}
run: |
echo ==== CMakeOutput.log ====
cat build/CMakeFiles/CMakeOutput.log
echo
echo ==== CMakeError.log ====
cat build/CMakeFiles/CMakeError.log
echo ==== CMakeCache.txt ====
cat build/CMakeCache.txt

View File

@ -1 +1 @@
QT_PACKAGEDATE_STR=2023-09-25
QT_PACKAGEDATE_STR=2023-11-21

2
.tag
View File

@ -1 +1 @@
372eaedc5b8c771c46acc4c96e91bbade4ca3624
e2cbce919ccefcae2b18f90257d67bc6e24c3c94

View File

@ -1,8 +1,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# special case skip regeneration
# Need an explicit call at the top level. This is the absolute minimum version
# needed to configure the project with any combination of enabled features.
# The call to qt_build_repo_begin() will upgrade policies further.

11
README.md Normal file
View File

@ -0,0 +1,11 @@
This is Qt 6.6.1 backport that runs on Windows 7 (what?). The repository is the qtbase module source code with all required modifications already applied.
Approach is based on this [forum thread](https://forum.qt.io/topic/133002/qt-creator-6-0-1-and-qt-6-2-2-running-on-windows-7/60) but better: many improvements amongst important fallbacks to default Qt 6 behaviour when running on newer Windows.
You basically need to compile Qt yourself (we use the [compile_win](https://github.com/crystalidea/qt-build-tools/tree/master/6.6.0) script).
The only issue noticed is that scalled UI is somewhat too big for 125% scalling option set in Windows 7. Something should be tweaked with dpi settings probably.
Qt 6.6 designer running on Windows 7:
![image](https://github.com/crystalidea/qt6windows7/assets/2600624/4c5ad13f-db6e-4684-8184-9615e4e55461)

View File

@ -0,0 +1,18 @@
@echo off
:: The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
set script_dir_path=%~dp0
:: Try to use original cmake, otherwise to make it relocatable, use any cmake found in PATH.
set cmake_path=@CMAKE_COMMAND@
if not exist "%cmake_path%" set cmake_path=cmake
if NOT "%~2" == "" goto :showhelp
if NOT "%~1" == "" (set PROJECT_DIR=%~1) else (set PROJECT_DIR=%cd%)
"%cmake_path%" -DPROJECT_DIR="%PROJECT_DIR%" -P "%script_dir_path%\@__GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir@\QtInitProject.cmake"
exit /b %errorlevel%
:showhelp
echo Usage
echo. qt-cmake-create <path/to/project>
exit /b 1

29
bin/qt-cmake-create.in Normal file
View File

@ -0,0 +1,29 @@
#!/bin/sh
HELP_MESSAGE="Usage
qt-cmake-create <path/to/project>"
# The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
script_dir_path=`dirname $0`
script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`
# Try to use original cmake, otherwise to make it relocatable, use any cmake found in PATH.
original_cmake_path="@CMAKE_COMMAND@"
cmake_path=$original_cmake_path
if ! test -f "$cmake_path"; then
cmake_path="cmake"
fi
if [ "$#" -gt 1 ]; then
echo "Invalid number of arguments"
echo "$HELP_MESSAGE"
exit 1
fi
if [ "$#" -gt 0 ]; then
PROJECT_DIR=$1
else
PROJECT_DIR=$PWD
fi
exec "$cmake_path" -DPROJECT_DIR="$PROJECT_DIR" -P \
"$script_dir_path/@__GlobalConfig_relative_path_from_bin_dir_to_cmake_config_dir@/QtInitProject.cmake"

View File

@ -5,13 +5,18 @@
# https://gitlab.kitware.com/cmake/cmake/-/issues/20713
# https://gitlab.kitware.com/cmake/cmake/-/issues/21475
set(configs "@__qt_configured_configs@")
set(should_skip_strip "@__qt_skip_strip_installed_artifacts@")
if(NOT QT_BUILD_DIR)
message(FATAL_ERROR "No QT_BUILD_DIR value provided to qt-cmake-private-install.")
endif()
unset(strip_arg)
if ("x@MSVC@" STREQUAL "x")
set(strip_arg --strip)
if(should_skip_strip)
unset(strip_arg)
else()
set(strip_arg --strip)
endif()
foreach(config ${configs})
message(STATUS "Installing configuration: '${config}'")
set(args "${CMAKE_COMMAND}" --install ${QT_BUILD_DIR} --config "${config}" ${strip_arg})

99
cmake/FindMimer.cmake Normal file
View File

@ -0,0 +1,99 @@
# Copyright (C) 2022 The Qt Company Ltd.
# Copyright (C) 2022 Mimer Information Technology
# SPDX-License-Identifier: BSD-3-Clause
# FindMimer
# ---------
# Try to locate the Mimer SQL client library
if(NOT DEFINED MimerSQL_ROOT)
if(DEFINED ENV{MIMERSQL_DEV_ROOT})
set(MimerSQL_ROOT "$ENV{MIMERSQL_DEV_ROOT}")
endif()
endif()
if(NOT DEFINED MimerSQL_ROOT)
find_package(PkgConfig QUIET)
endif()
if(PkgConfig_FOUND AND NOT DEFINED MimerSQL_ROOT)
pkg_check_modules(PC_Mimer QUIET mimcontrol)
set(MimerSQL_include_dir_hints "${PC_MimerSQL_INCLUDEDIR}")
set(MimerSQL_library_hints "${PC_MimerSQL_LIBDIR}")
else()
if(DEFINED MimerSQL_ROOT)
if(WIN32)
set(MimerSQL_include_dir_hints "${MimerSQL_ROOT}\\include")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MimerSQL_library_hints "${MimerSQL_ROOT}\\lib\\x86")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MimerSQL_library_hints "${MimerSQL_ROOT}\\lib\\amd64")
else()
set(MimerSQL_library_hints "")
endif()
else()
set(MimerSQL_include_dir_hints "${MimerSQL_ROOT}/include")
set(MimerSQL_library_hints "${MimerSQL_ROOT}/lib")
endif()
else()
if(WIN32)
set(MimerSQL_include_dir_hints "C:\\MimerSQLDev\\include")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MimerSQL_library_hints "C:\\MimerSQLDev\\lib\\x86")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MimerSQL_library_hints "C:\\MimerSQLDev\\lib\\amd64")
else()
set(MimerSQL_library_hints "")
endif()
elseif(APPLE AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin"
AND CMAKE_OSX_ARCHITECTURES MATCHES "^(x86_64|arm64|)$")
set(MimerSQL_library_hints "/usr/local/lib")
set(MimerSQL_include_dir_hints "/usr/local/include")
else()
set(MimerSQL_include_dir_hints "")
set(MimerSQL_library_hints "")
endif()
endif()
endif()
find_path(Mimer_INCLUDE_DIR
NAMES mimerapi.h
HINTS ${MimerSQL_include_dir_hints})
if(WIN32)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86|X86)$")
set(MIMER_LIBS_NAMES mimapi32)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(amd64|AMD64)$")
set(MIMER_LIBS_NAMES mimapi64)
endif()
else()
set(MIMER_LIBS_NAMES mimerapi)
endif()
find_library(Mimer_LIBRARIES
NAMES ${MIMER_LIBS_NAMES}
HINTS ${MimerSQL_library_hints})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Mimer
REQUIRED_VARS Mimer_LIBRARIES Mimer_INCLUDE_DIR)
# Now try to get the include and library path.
if(Mimer_FOUND)
set(Mimer_INCLUDE_DIRS ${Mimer_INCLUDE_DIR})
set(Mimer_LIBRARY_DIRS ${Mimer_LIBRARIES})
if (NOT TARGET MimerSQL::MimerSQL)
add_library(MimerSQL::MimerSQL UNKNOWN IMPORTED)
set_target_properties(MimerSQL::MimerSQL PROPERTIES
IMPORTED_LOCATION "${Mimer_LIBRARY_DIRS}"
INTERFACE_INCLUDE_DIRECTORIES "${Mimer_INCLUDE_DIRS}")
endif ()
endif()
mark_as_advanced(Mimer_INCLUDE_DIR Mimer_LIBRARIES)
include(FeatureSummary)
set_package_properties(MimerSQL PROPERTIES
URL "https://www.mimer.com"
DESCRIPTION "Mimer client library")

View File

@ -0,0 +1,53 @@
# Copyright (C) 2022 The Qt Company Ltd.
# Copyright (C) 2023 Intel Corpotation.
# SPDX-License-Identifier: BSD-3-Clause
# 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 WrapResolv::WrapResolv)
set(WrapResolv_FOUND ON)
return()
endif()
set(WrapResolv_FOUND OFF)
include(CheckCXXSourceCompiles)
include(CMakePushCheckState)
if(QNX)
find_library(LIBRESOLV socket)
else()
find_library(LIBRESOLV resolv)
endif()
cmake_push_check_state()
if(LIBRESOLV)
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBRESOLV}")
endif()
check_cxx_source_compiles("
#include <netinet/in.h>
#include <resolv.h>
int main(int, char **argv)
{
res_state statep;
int n = res_nmkquery(statep, 0, argv[1], 0, 0, NULL, 0, NULL, NULL, 0);
n = res_nsend(statep, NULL, 0, NULL, 0);
n = dn_expand(NULL, NULL, NULL, NULL, 0);
return n;
}
" HAVE_LIBRESOLV_FUNCTIONS)
cmake_pop_check_state()
if(HAVE_LIBRESOLV_FUNCTIONS)
set(WrapResolv_FOUND ON)
add_library(WrapResolv::WrapResolv INTERFACE IMPORTED)
if(LIBRESOLV)
target_link_libraries(WrapResolv::WrapResolv INTERFACE "${LIBRESOLV}")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(WrapResolv DEFAULT_MSG WrapResolv_FOUND)

View File

@ -21,17 +21,31 @@ if(LIBRT)
endif()
check_cxx_source_compiles("
#include <unistd.h>
#include <time.h>
#include <unistd.h>
int main(int, char **) {
timespec ts; clock_gettime(CLOCK_REALTIME, &ts);
}" HAVE_GETTIME)
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return 0;
}
" HAVE_GETTIME)
check_cxx_source_compiles("
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(int, char **) {
shm_open(\"test\", O_RDWR | O_CREAT | O_EXCL, 0666);
shm_unlink(\"test\");
return 0;
}
" HAVE_SHM_OPEN_SHM_UNLINK)
cmake_pop_check_state()
if(HAVE_GETTIME)
if(HAVE_GETTIME OR HAVE_SHM_OPEN_SHM_UNLINK)
set(WrapRt_FOUND ON)
add_library(WrapRt::WrapRt INTERFACE IMPORTED)
if (LIBRT)

View File

@ -48,6 +48,26 @@ if(Vulkan_INCLUDE_DIR)
target_include_directories(WrapVulkanHeaders::WrapVulkanHeaders INTERFACE
${__qt_molten_vk_homebrew_include_path})
endif()
# Check for homebrew vulkan-headers folder structure
# If instead of molten-vk folder, CMAKE_PREFIX_PATH points to Homebrew's
# vulkan-headers installation, then we will not be able to find molten-vk
# headers. If we assume that user has installed the molten-vk formula as
# well, then we might have a chance to pick it up like this.
if(Vulkan_INCLUDE_DIR MATCHES "/homebrew/Cellar/")
set(__qt_standalone_molten_vk_homebrew_include_path
"${Vulkan_INCLUDE_DIR}/../../../../opt/molten-vk/include")
else()
set(__qt_standalone_molten_vk_homebrew_include_path
"${Vulkan_INCLUDE_DIR}/../../molten-vk/include")
endif()
get_filename_component(
__qt_standalone_molten_vk_homebrew_include_path
"${__qt_standalone_molten_vk_homebrew_include_path}" ABSOLUTE)
if(EXISTS "${__qt_standalone_molten_vk_homebrew_include_path}")
target_include_directories(WrapVulkanHeaders::WrapVulkanHeaders INTERFACE
${__qt_standalone_molten_vk_homebrew_include_path})
endif()
endif()
endif()

View File

@ -28,10 +28,10 @@ include(FindPackageHandleStandardArgs)
if(TARGET zstd::libzstd_static OR TARGET zstd::libzstd_shared)
find_package_handle_standard_args(WrapZSTD
REQUIRED_VARS zstd_VERSION VERSION_VAR zstd_VERSION)
if(TARGET zstd::libzstd_static)
set(zstdtargetsuffix "_static")
else()
if(TARGET zstd::libzstd_shared)
set(zstdtargetsuffix "_shared")
else()
set(zstdtargetsuffix "_static")
endif()
if(NOT TARGET WrapZSTD::WrapZSTD)
add_library(WrapZSTD::WrapZSTD INTERFACE IMPORTED)

View File

@ -7,6 +7,7 @@
"compiler_target": "${CMAKE_CXX_COMPILER_TARGET}",
"compiler_version": "${CMAKE_CXX_COMPILER_VERSION}",
"cross_compiled": ${cross_compilation},
"target_system": "${CMAKE_SYSTEM_NAME}"
"target_system": "${CMAKE_SYSTEM_NAME}",
"architecture": "${TEST_architecture_arch}"
}
}

View File

@ -8,6 +8,9 @@
# Make sure to not run detection when building standalone tests, because the detection was already
# done when initially configuring qtbase.
# This needs to be here because QtAutoDetect loads before any other modules
option(QT_USE_VCPKG "Enable the use of vcpkg" ON)
function(qt_internal_ensure_static_qt_config)
if(NOT DEFINED BUILD_SHARED_LIBS)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build Qt statically or dynamically" FORCE)
@ -161,7 +164,7 @@ function(qt_auto_detect_android)
endfunction()
function(qt_auto_detect_vcpkg)
if(DEFINED ENV{VCPKG_ROOT})
if(QT_USE_VCPKG AND DEFINED ENV{VCPKG_ROOT})
set(vcpkg_toolchain_file "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
get_filename_component(vcpkg_toolchain_file "${vcpkg_toolchain_file}" ABSOLUTE)
@ -174,8 +177,8 @@ function(qt_auto_detect_vcpkg)
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 "")
if(DEFINED ENV{QT_VCPKG_TARGET_TRIPLET} AND NOT DEFINED VCPKG_TARGET_TRIPLET)
set(VCPKG_TARGET_TRIPLET "$ENV{QT_VCPKG_TARGET_TRIPLET}" CACHE STRING "")
message(STATUS "Using vcpkg triplet ${VCPKG_TARGET_TRIPLET}")
endif()
unset(vcpkg_toolchain_file)
@ -229,7 +232,9 @@ function(qt_auto_detect_ios)
endif()
set(CMAKE_OSX_ARCHITECTURES "${osx_architectures}" CACHE STRING "")
qt_internal_ensure_static_qt_config()
if(NOT DEFINED BUILD_SHARED_LIBS)
qt_internal_ensure_static_qt_config()
endif()
# Disable qt rpaths for iOS, just like mkspecs/common/uikit.conf does, due to those
# bundles not being able to use paths outside the app bundle. Not sure this is strictly
@ -239,7 +244,15 @@ function(qt_auto_detect_ios)
endfunction()
function(qt_auto_detect_cmake_config)
if(CMAKE_CONFIGURATION_TYPES)
# If CMAKE_CONFIGURATION_TYPES are not set for the multi-config generator use Release and
# Debug configurations by default, instead of those are proposed by the CMake internal logic.
get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(is_multi)
if(NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES Release Debug)
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" PARENT_SCOPE)
endif()
# Allow users to specify this option.
if(NOT QT_MULTI_CONFIG_FIRST_CONFIG)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
@ -263,7 +276,7 @@ function(qt_auto_detect_cmake_config)
endfunction()
function(qt_auto_detect_cyclic_toolchain)
if(CMAKE_TOOLCHAIN_FILE AND CMAKE_TOOLCHAIN_FILE MATCHES "/qt.toolchain.cmake$")
if(CMAKE_TOOLCHAIN_FILE AND CMAKE_TOOLCHAIN_FILE MATCHES "/qt\\.toolchain\\.cmake$")
message(FATAL_ERROR
"Woah there! You can't use the Qt generated qt.toolchain.cmake file to configure "
"qtbase, because that will create a toolchain file that includes itself!\n"
@ -476,6 +489,12 @@ function(qt_auto_detect_integrity)
endif()
endfunction()
# Save the build type before project() might set one.
# This allows us to determine if the user has set an explicit build type that we should use.
function(qt_auto_detect_cmake_build_type)
set(__qt_auto_detect_cmake_build_type_before_project_call "${CMAKE_BUILD_TYPE}" PARENT_SCOPE)
endfunction()
# Let CMake load our custom platform modules.
# CMake-provided platform modules take precedence.
if(NOT QT_AVOID_CUSTOM_PLATFORM_MODULES)
@ -495,3 +514,4 @@ qt_auto_detect_wasm()
qt_auto_detect_win32_arm()
qt_auto_detect_linux_x86()
qt_auto_detect_integrity()
qt_auto_detect_cmake_build_type()

View File

@ -216,6 +216,7 @@ qt_copy_or_install(FILES
cmake/QtAndroidHelpers.cmake
cmake/QtAppHelpers.cmake
cmake/QtAutogenHelpers.cmake
cmake/QtBaseTopLevelHelpers.cmake
cmake/QtBuild.cmake
cmake/QtBuildInformation.cmake
cmake/QtCMakeHelpers.cmake
@ -332,6 +333,7 @@ set(__public_cmake_helpers
cmake/QtCopyFileIfDifferent.cmake
cmake/QtFeature.cmake
cmake/QtFeatureCommon.cmake
cmake/QtInitProject.cmake
cmake/QtPublicAppleHelpers.cmake
cmake/QtPublicCMakeHelpers.cmake
cmake/QtPublicCMakeVersionHelpers.cmake
@ -395,17 +397,30 @@ if(QT_WILL_INSTALL)
)
endif()
if(MACOS)
qt_copy_or_install(FILES
cmake/macos/MacOSXBundleInfo.plist.in
DESTINATION "${__GlobalConfig_install_dir}/macos"
if(APPLE)
if(MACOS)
set(platform_shortname "macos")
elseif(IOS)
set(platform_shortname "ios")
endif()
qt_copy_or_install(FILES "cmake/${platform_shortname}/Info.plist.app.in"
DESTINATION "${__GlobalConfig_install_dir}/${platform_shortname}"
)
elseif(IOS)
qt_copy_or_install(FILES
cmake/ios/Info.plist.app.in
cmake/ios/LaunchScreen.storyboard
DESTINATION "${__GlobalConfig_install_dir}/ios"
# For examples built as part of prefix build before install
file(COPY "cmake/${platform_shortname}/Info.plist.app.in"
DESTINATION "${__GlobalConfig_build_dir}/${platform_shortname}"
)
if(IOS)
qt_copy_or_install(FILES "cmake/ios/LaunchScreen.storyboard"
DESTINATION "${__GlobalConfig_install_dir}/ios"
)
# For examples built as part of prefix build before install
file(COPY "cmake/ios/LaunchScreen.storyboard"
DESTINATION "${__GlobalConfig_build_dir}/ios"
)
endif()
elseif(WASM)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/wasm/wasmtestrunner/qt-wasmtestrunner.py"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-wasmtestrunner.py" @ONLY)

View File

@ -0,0 +1,81 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Depends on __qt6_qtbase_src_path being set in the top-level dir.
macro(qt_internal_top_level_setup_autodetect)
# Run platform auto-detection /before/ the first project() call and thus
# before the toolchain file is loaded.
# Don't run auto-detection when doing standalone tests. In that case, the detection
# results are taken from either QtBuildInternals or the qt.toolchain.cmake file.
if(NOT QT_BUILD_STANDALONE_TESTS)
set(__qt6_auto_detect_path "${__qt6_qtbase_src_path}/cmake/QtAutoDetect.cmake")
if(NOT EXISTS "${__qt6_auto_detect_path}")
message(FATAL_ERROR "Required file does not exist: '${__qt6_auto_detect_path}'")
endif()
include("${__qt6_auto_detect_path}")
endif()
endmacro()
macro(qt_internal_top_level_setup_after_project)
qt_internal_top_level_setup_testing()
endmacro()
macro(qt_internal_top_level_setup_testing)
# Required so we can call ctest from the root build directory
enable_testing()
endmacro()
# Depends on __qt6_qtbase_src_path being set in the top-level dir.
macro(qt_internal_top_level_setup_cmake_module_path)
if (NOT QT_BUILD_STANDALONE_TESTS)
set(__qt6_cmake_module_path "${__qt6_qtbase_src_path}/cmake")
if(NOT EXISTS "${__qt6_cmake_module_path}")
message(FATAL_ERROR "Required directory does not exist: '${__qt6_cmake_module_path}'")
endif()
list(APPEND CMAKE_MODULE_PATH "${__qt6_cmake_module_path}")
list(APPEND CMAKE_MODULE_PATH
"${__qt6_cmake_module_path}/3rdparty/extra-cmake-modules/find-modules")
list(APPEND CMAKE_MODULE_PATH "${__qt6_cmake_module_path}/3rdparty/kwin")
endif()
endmacro()
macro(qt_internal_top_level_before_build_submodules)
qt_internal_top_level_setup_no_create_targets()
endmacro()
macro(qt_internal_top_level_setup_no_create_targets)
# Also make sure the CMake config files do not recreate the already-existing targets
if (NOT QT_BUILD_STANDALONE_TESTS)
set(QT_NO_CREATE_TARGETS TRUE)
endif()
endmacro()
macro(qt_internal_top_level_end)
qt_internal_print_top_level_info()
# Depends on QtBuildInternalsConfig being included, which is the case whenver any repo is
# configured.
qt_internal_qt_configure_end()
endmacro()
function(qt_internal_print_top_level_info)
if(NOT QT_BUILD_STANDALONE_TESTS)
# Display a summary of everything
include(QtBuildInformation)
include(QtPlatformSupport)
qt_print_feature_summary()
qt_print_build_instructions()
endif()
endfunction()
macro(qt_internal_top_level_after_add_subdirectory)
if(module STREQUAL "qtbase")
if (NOT QT_BUILD_STANDALONE_TESTS)
list(APPEND CMAKE_PREFIX_PATH "${QtBase_BINARY_DIR}/${INSTALL_LIBDIR}/cmake")
list(APPEND CMAKE_FIND_ROOT_PATH "${QtBase_BINARY_DIR}")
endif()
endif()
endmacro()

View File

@ -281,7 +281,7 @@ qt_setup_tool_path_command()
# Platform define path, etc.
if(WIN32)
set(QT_DEFAULT_PLATFORM_DEFINITIONS WIN32 _ENABLE_EXTENDED_ALIGNED_STORAGE)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
if(QT_64BIT)
list(APPEND QT_DEFAULT_PLATFORM_DEFINITIONS WIN64 _WIN64)
endif()
@ -434,7 +434,7 @@ set(QT_TOP_LEVEL_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
# Prevent warnings about object files without any symbols. This is a common
# thing in Qt as we tend to build files unconditionally, and then use ifdefs
# to compile out parts that are not relevant.
if(CMAKE_HOST_APPLE AND APPLE)
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang")
foreach(lang ASM C CXX)
# We have to tell 'ar' to not run ranlib by itself, by passing the 'S' option
set(CMAKE_${lang}_ARCHIVE_CREATE "<CMAKE_AR> qcS <TARGET> <LINK_FLAGS> <OBJECTS>")
@ -577,11 +577,6 @@ endif()
_qt_internal_determine_if_host_info_package_needed(__qt_build_requires_host_info_package)
_qt_internal_find_host_info_package("${__qt_build_requires_host_info_package}")
# Create tool script wrapper if necessary.
# TODO: Remove once all direct usages of QT_TOOL_COMMAND_WRAPPER_PATH are replaced with function
# calls.
_qt_internal_generate_tool_command_wrapper()
# This sets up the poor man's scope finalizer mechanism.
# For newer CMake versions, we use cmake_language(DEFER CALL) instead.
if(CMAKE_VERSION VERSION_LESS "3.19.0")

View File

@ -39,6 +39,9 @@ function(qt_internal_read_repo_dependencies out_var repo_dir)
if(NOT dependency IN_LIST seen)
qt_internal_read_repo_dependencies(subdeps "${dependency_repo_dir}"
${seen} ${dependency})
if(dependency MATCHES "^tqtc-(.+)")
set(dependency "${CMAKE_MATCH_1}")
endif()
list(APPEND dependencies ${subdeps} ${dependency})
endif()
endif()
@ -105,6 +108,35 @@ endif()
# build.
include(QtPlatformSupport)
# Set FEATURE_${feature} if INPUT_${feature} is set in certain circumstances.
# Set FEATURE_${feature}_computed_from_input to TRUE or FALSE depending on whether the
# INPUT_${feature} value has overridden the FEATURE_${feature} variable.
#
# Needs to be in QtBuildInternalsConfig.cmake instead of QtFeature.cmake because it's used in
# qt_build_internals_disable_pkg_config_if_needed.
function(qt_internal_compute_feature_value_from_possible_input feature)
# If FEATURE_ is not defined try to use the INPUT_ variable to enable/disable feature.
# If FEATURE_ is defined and the configure script is being used (so
# QT_INTERNAL_CALLED_FROM_CONFIGURE is TRUE), ignore the FEATURE_ variable, and take into
# account the INPUT_ variable instead, because a command line argument takes priority over
# a pre-cached FEATURE_ variable.
if((NOT DEFINED FEATURE_${feature} OR QT_INTERNAL_CALLED_FROM_CONFIGURE)
AND DEFINED INPUT_${feature}
AND NOT "${INPUT_${feature}}" STREQUAL "undefined"
AND NOT "${INPUT_${feature}}" STREQUAL "")
if(INPUT_${feature})
set(FEATURE_${feature} ON)
else()
set(FEATURE_${feature} OFF)
endif()
set(FEATURE_${feature} "${FEATURE_${feature}}" PARENT_SCOPE)
set(FEATURE_${feature}_computed_from_input TRUE PARENT_SCOPE)
else()
set(FEATURE_${feature}_computed_from_input FALSE PARENT_SCOPE)
endif()
endfunction()
function(qt_build_internals_disable_pkg_config_if_needed)
# pkg-config should not be used by default on Darwin and Windows platforms (and QNX), as defined
# in the qtbase/configure.json. Unfortunately by the time the feature is evaluated there are
@ -131,15 +163,7 @@ function(qt_build_internals_disable_pkg_config_if_needed)
endif()
# Features won't have been evaluated yet if this is the first run, have to evaluate this here
if ((NOT DEFINED "FEATURE_pkg_config") AND (DEFINED "INPUT_pkg_config")
AND (NOT "${INPUT_pkg_config}" STREQUAL "undefined")
AND (NOT "${INPUT_pkg_config}" STREQUAL ""))
if(INPUT_pkg_config)
set(FEATURE_pkg_config ON)
else()
set(FEATURE_pkg_config OFF)
endif()
endif()
qt_internal_compute_feature_value_from_possible_input(pkg_config)
# If user explicitly specified a value for the feature, honor it, even if it might break
# the build.
@ -296,7 +320,27 @@ function(qt_build_internals_add_toplevel_targets)
COMMENT "Building everything in ${qt_repo_targets_name}/${qt_repo_target_basename}")
add_dependencies("${qt_repo_target_name}" ${qt_repo_targets})
list(APPEND qt_repo_target_all "${qt_repo_target_name}")
# Create special dependency target for External Project examples excluding targets
# marked as skipped.
set(qt_repo_target_name
"${qt_repo_targets_name}_${qt_repo_target_basename}_for_examples")
add_custom_target("${qt_repo_target_name}")
set(unskipped_targets "")
foreach(target IN LISTS qt_repo_targets)
if(TARGET "${target}")
qt_internal_is_target_skipped_for_examples("${target}" is_skipped)
if(NOT is_skipped)
list(APPEND unskipped_targets "${target}")
endif()
endif()
endforeach()
if(unskipped_targets)
add_dependencies("${qt_repo_target_name}" ${unskipped_targets})
endif()
endif()
endforeach()
if (qt_repo_target_all)
# Note qt_repo_targets_name is different from qt_repo_target_name that is used above.
@ -570,9 +614,24 @@ macro(qt_build_repo_end)
set(QT_INTERNAL_FRESH_REQUESTED "FALSE" CACHE INTERNAL "")
endif()
if(NOT QT_SUPERBUILD)
qt_internal_qt_configure_end()
endif()
list(POP_BACK CMAKE_MESSAGE_CONTEXT)
endmacro()
# Function called either at the end of per-repo configuration, or at the end of configuration of
# a super build.
# At the moment it is called before examples are configured in a per-repo build. We might want
# to change that at some point if needed.
function(qt_internal_qt_configure_end)
# If Qt is configued via the configure script, remove the marker variable, so that any future
# reconfigurations that are done by calling cmake directly don't trigger configure specific
# logic.
unset(QT_INTERNAL_CALLED_FROM_CONFIGURE CACHE)
endfunction()
macro(qt_build_repo)
qt_build_repo_begin(${ARGN})
@ -856,7 +915,7 @@ macro(qt_examples_build_begin)
set(QT_EXAMPLE_DEPENDENCIES ${qt_repo_plugins_recursive} ${arg_DEPENDS})
if(TARGET ${qt_repo_targets_name}_src)
list(APPEND QT_EXAMPLE_DEPENDENCIES ${qt_repo_targets_name}_src)
list(APPEND QT_EXAMPLE_DEPENDENCIES ${qt_repo_targets_name}_src_for_examples)
endif()
if(TARGET ${qt_repo_targets_name}_tools)
@ -980,19 +1039,118 @@ set(CMAKE_INSTALL_PREFIX \"\${_qt_internal_examples_cmake_install_prefix_backup}
set(CMAKE_UNITY_BUILD ${QT_UNITY_BUILD})
endmacro()
# Allows building an example either as an ExternalProject or in-tree with the Qt build.
# Also allows installing the example sources.
function(qt_internal_add_example subdir)
if(NOT QT_IS_EXTERNAL_EXAMPLES_BUILD)
qt_internal_add_example_in_tree(${ARGV})
else()
qt_internal_add_example_external_project(${ARGV})
# Pre-compute unique example name based on the subdir, in case of target name clashes.
qt_internal_get_example_unique_name(unique_example_name "${subdir}")
# QT_INTERNAL_NO_CONFIGURE_EXAMPLES is not meant to be used by Qt builders, it's here for faster
# testing of the source installation code path for build system engineers.
if(NOT QT_INTERNAL_NO_CONFIGURE_EXAMPLES)
if(NOT QT_IS_EXTERNAL_EXAMPLES_BUILD)
qt_internal_add_example_in_tree("${subdir}")
else()
qt_internal_add_example_external_project("${subdir}"
NAME "${unique_example_name}")
endif()
endif()
if(QT_INSTALL_EXAMPLES_SOURCES)
string(TOLOWER ${PROJECT_NAME} project_name_lower)
qt_internal_install_example_sources("${subdir}"
NAME "${unique_example_name}"
REPO_NAME "${project_name_lower}")
endif()
endfunction()
# Gets the install prefix where an example should be installed.
# Used for computing the final installation path.
function(qt_internal_get_example_install_prefix out_var)
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(${out_var} "${qt_example_install_prefix}" PARENT_SCOPE)
endfunction()
# Gets the install prefix where an example's sources should be installed.
# Used for computing the final installation path.
function(qt_internal_get_examples_sources_install_prefix out_var)
# Allow customizing the installation path of the examples source specifically.
if(QT_INTERNAL_EXAMPLES_SOURCES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_SOURCES_INSTALL_PREFIX}")
else()
qt_internal_get_example_install_prefix(qt_example_install_prefix)
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(${out_var} "${qt_example_install_prefix}" PARENT_SCOPE)
endfunction()
# Gets the relative path of an example, relative to the current repo's examples source dir.
# QT_EXAMPLE_BASE_DIR is meant to be already set in a parent scope.
function(qt_internal_get_example_rel_path out_var subdir)
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
set(${out_var} "${example_rel_path}" PARENT_SCOPE)
endfunction()
# Gets the install path where an example should be installed.
function(qt_internal_get_example_install_path out_var subdir)
qt_internal_get_example_install_prefix(qt_example_install_prefix)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(example_install_path "${qt_example_install_prefix}/${example_rel_path}")
set(${out_var} "${example_install_path}" PARENT_SCOPE)
endfunction()
# Gets the install path where an example's sources should be installed.
function(qt_internal_get_examples_sources_install_path out_var subdir)
qt_internal_get_examples_sources_install_prefix(qt_example_install_prefix)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(example_install_path "${qt_example_install_prefix}/${example_rel_path}")
set(${out_var} "${example_install_path}" PARENT_SCOPE)
endfunction()
# Get the unique name of an example project based on its subdir or explicitly given name.
# Makes the name unique by appending a short sha1 hash of the relative path of the example
# if a target of the same name already exist.
function(qt_internal_get_example_unique_name out_var subdir)
qt_internal_get_example_rel_path(example_rel_path "${subdir}")
set(name "${subdir}")
# qtdeclarative has calls like qt_internal_add_example(imagine/automotive)
# so passing a nested subdirectory. Custom targets (and thus ExternalProjects) can't contain
# slashes, so extract the last part of the path to be used as a name.
if(name MATCHES "/")
string(REPLACE "/" ";" exploded_path "${name}")
list(POP_BACK exploded_path last_dir)
if(NOT last_dir)
message(FATAL_ERROR "Example subdirectory must have a name.")
else()
set(name "${last_dir}")
endif()
endif()
# Likely a clash with an example subdir ExternalProject custom target of the same name in a
# top-level build.
if(TARGET "${name}")
string(SHA1 rel_path_hash "${example_rel_path}")
string(SUBSTRING "${rel_path_hash}" 0 4 short_hash)
set(name "${name}-${short_hash}")
endif()
set(${out_var} "${name}" PARENT_SCOPE)
endfunction()
# Use old non-ExternalProject approach, aka build in-tree with the Qt build.
function(qt_internal_add_example_in_tree subdir)
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
# Unset the default CMAKE_INSTALL_PREFIX that's generated in
# ${CMAKE_CURRENT_BINARY_DIR}/cmake_install.cmake
# so we can override it with a different value in
@ -1006,15 +1164,8 @@ unset(CMAKE_INSTALL_PREFIX)
# Override the install prefix in the subdir cmake_install.cmake, so that
# relative install(TARGETS DESTINATION) calls in example projects install where we tell them to.
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(CMAKE_INSTALL_PREFIX "${qt_example_install_prefix}/${example_rel_path}")
qt_internal_get_example_install_path(example_install_path "${subdir}")
set(CMAKE_INSTALL_PREFIX "${example_install_path}")
# Make sure unclean example projects have their INSTALL_EXAMPLEDIR set to "."
# Won't have any effect on example projects that don't use INSTALL_EXAMPLEDIR.
@ -1024,7 +1175,7 @@ unset(CMAKE_INSTALL_PREFIX)
# TODO: Remove once all repositories use qt_internal_add_example instead of add_subdirectory.
set(QT_INTERNAL_SET_EXAMPLE_INSTALL_DIR_TO_DOT ON)
add_subdirectory(${subdir} ${ARGN})
add_subdirectory(${subdir})
endfunction()
function(qt_internal_add_example_external_project subdir)
@ -1034,33 +1185,6 @@ function(qt_internal_add_example_external_project subdir)
cmake_parse_arguments(PARSE_ARGV 1 arg "${options}" "${singleOpts}" "${multiOpts}")
file(RELATIVE_PATH example_rel_path
"${QT_EXAMPLE_BASE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${subdir}")
if(NOT arg_NAME)
set(arg_NAME "${subdir}")
# qtdeclarative has calls like qt_internal_add_example(imagine/automotive)
# so passing a nested subdirectory. Custom targets (and thus ExternalProjects) can't contain
# slashes, so extract the last part of the path to be used as a name.
if(arg_NAME MATCHES "/")
string(REPLACE "/" ";" exploded_path "${arg_NAME}")
list(POP_BACK exploded_path last_dir)
if(NOT last_dir)
message(FATAL_ERROR "Example subdirectory must have a name.")
else()
set(arg_NAME "${last_dir}")
endif()
endif()
endif()
# Likely a clash with an example subdir ExternalProject custom target of the same name.
if(TARGET "${arg_NAME}")
string(SHA1 rel_path_hash "${example_rel_path}")
string(SUBSTRING "${rel_path_hash}" 0 4 short_hash)
set(arg_NAME "${arg_NAME}-${short_hash}")
endif()
# TODO: Fix example builds when using Conan / install prefixes are different for each repo.
if(QT_SUPERBUILD OR QtBase_BINARY_DIR)
# When doing a top-level build or when building qtbase,
@ -1281,15 +1405,7 @@ function(qt_internal_add_example_external_project subdir)
# example_source_dir, use _qt_internal_override_example_install_dir_to_dot to ensure
# INSTALL_EXAMPLEDIR does not interfere.
# Allow customizing the installation path of the examples. Will be used in CI.
if(QT_INTERNAL_EXAMPLES_INSTALL_PREFIX)
set(qt_example_install_prefix "${QT_INTERNAL_EXAMPLES_INSTALL_PREFIX}")
else()
set(qt_example_install_prefix "${CMAKE_INSTALL_PREFIX}/${INSTALL_EXAMPLESDIR}")
endif()
file(TO_CMAKE_PATH "${qt_example_install_prefix}" qt_example_install_prefix)
set(example_install_prefix "${qt_example_install_prefix}/${example_rel_path}")
qt_internal_get_example_install_path(example_install_path "${subdir}")
set(ep_binary_dir "${CMAKE_CURRENT_BINARY_DIR}/${subdir}")
@ -1304,7 +1420,7 @@ function(qt_internal_add_example_external_project subdir)
PREFIX "${CMAKE_CURRENT_BINARY_DIR}/${subdir}-ep"
STAMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/${subdir}-ep/stamp"
BINARY_DIR "${ep_binary_dir}"
INSTALL_DIR "${example_install_prefix}"
INSTALL_DIR "${example_install_path}"
INSTALL_COMMAND ""
${build_command}
TEST_COMMAND ""
@ -1358,6 +1474,54 @@ execute_process(
endfunction()
function(qt_internal_install_example_sources subdir)
set(options "")
set(single_args NAME REPO_NAME)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 1 arg "${options}" "${single_args}" "${multi_args}")
qt_internal_get_examples_sources_install_path(example_install_path "${subdir}")
# The trailing slash is important to avoid duplicate nested directory names.
set(example_source_dir "${subdir}/")
# Allow controlling whether sources should be part of the default install target.
if(QT_INSTALL_EXAMPLES_SOURCES_BY_DEFAULT)
set(exclude_from_all "")
else()
set(exclude_from_all "EXCLUDE_FROM_ALL")
endif()
# Create an install component for all example sources. Can also be part of the default
# install target if EXCLUDE_FROM_ALL is not passed.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources"
USE_SOURCE_PERMISSIONS
${exclude_from_all}
)
# Also create a specific install component just for this repo's examples.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources_${arg_REPO_NAME}"
USE_SOURCE_PERMISSIONS
EXCLUDE_FROM_ALL
)
# Also create a specific install component just for the current example's sources.
install(
DIRECTORY "${example_source_dir}"
DESTINATION "${example_install_path}"
COMPONENT "examples_sources_${arg_NAME}"
USE_SOURCE_PERMISSIONS
EXCLUDE_FROM_ALL
)
endfunction()
if ("STANDALONE_TEST" IN_LIST Qt6BuildInternals_FIND_COMPONENTS)
include(${CMAKE_CURRENT_LIST_DIR}/QtStandaloneTestTemplateProject/Main.cmake)
if (NOT PROJECT_VERSION_MAJOR)

View File

@ -2,6 +2,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Includes QtSetup and friends for private CMake API.
set(QT_INTERNAL_IS_STANDALONE_TEST TRUE)
qt_internal_project_setup()
qt_build_internals_set_up_private_api()

View File

@ -103,6 +103,9 @@ set(QT_BUILD_EXAMPLES_AS_EXTERNAL "@QT_BUILD_EXAMPLES_AS_EXTERNAL@" CACHE BOOL
# Propagate usage of ccache.
set(QT_USE_CCACHE @QT_USE_CCACHE@ CACHE BOOL "Enable the use of ccache")
# Propagate usage of vcpkg, ON by default.
set(QT_USE_VCPKG @QT_USE_VCPKG@ CACHE BOOL "Enable the use of vcpkg")
# Propagate usage of unity build.
set(QT_UNITY_BUILD @QT_UNITY_BUILD@ CACHE BOOL "Enable unity (jumbo) build")
set(QT_UNITY_BUILD_BATCH_SIZE "@QT_UNITY_BUILD_BATCH_SIZE@" CACHE STRING "Unity build batch size")
@ -163,6 +166,7 @@ function(qt_internal_force_set_cmake_build_type_conditionally value)
AND NOT QT_NO_FORCE_SET_CMAKE_BUILD_TYPE
AND NOT __qt_internal_extras_is_multi_config)
set(CMAKE_BUILD_TYPE "${value}" CACHE STRING "Choose the type of build." FORCE)
set(__qt_build_internals_cmake_build_type "${value}" PARENT_SCOPE)
endif()
endfunction()

View File

@ -14,6 +14,8 @@ function(qt_internal_get_supported_min_cmake_version_for_building_qt out_var)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT}")
# We're building qtbase so the values come from .cmake.conf.
elseif(APPLE)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_APPLE}")
elseif(BUILD_SHARED_LIBS)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_BUILDING_QT_SHARED}")
else()
@ -30,7 +32,9 @@ function(qt_internal_get_supported_min_cmake_version_for_using_qt out_var)
"It should have been set by this point.")
endif()
if(BUILD_SHARED_LIBS)
if(APPLE)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_APPLE}")
elseif(BUILD_SHARED_LIBS)
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_SHARED}")
else()
set(supported_version "${QT_SUPPORTED_MIN_CMAKE_VERSION_FOR_USING_QT_STATIC}")

View File

@ -92,10 +92,10 @@ endif()
# Windows MSVC
if(MSVC)
set(QT_CFLAGS_OPTIMIZE "-O2")
set(QT_CFLAGS_OPTIMIZE "-O2 -Ob3") # -Ob3 was introduced in Visual Studio 2019 version 16.0
set(QT_CFLAGS_OPTIMIZE_DEBUG "-Od")
set(QT_CFLAGS_OPTIMIZE_SIZE "-O1")
set(QT_CFLAGS_OPTIMIZE_VALID_VALUES "/O2" "/O1" "/Od" "/Ob0" "/Ob1" "/Ob2" "/O0" "-O0")
set(QT_CFLAGS_OPTIMIZE_VALID_VALUES "/O2" "/O1" "/Od" "/Ob0" "/Ob1" "/Ob2" "/Ob3" "/O0" "-O0")
if(CLANG)
set(QT_CFLAGS_OPTIMIZE_FULL "/clang:-O3")

View File

@ -29,13 +29,12 @@ 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")
if(APPLE AND (NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin"))
# Add module directory to pick up custom Info.plist template for macOS
list(APPEND CMAKE_MODULE_PATH "${_qt_import_prefix}/macos")
elseif(APPLE AND CMAKE_SYSTEM_NAME STREQUAL "iOS")
# Add module directory to pick up custom Info.plist template for iOS
set(__qt_internal_cmake_ios_support_files_path "${_qt_import_prefix}/ios")
list(APPEND CMAKE_MODULE_PATH "${__qt_internal_cmake_ios_support_files_path}")
if(APPLE)
if(NOT CMAKE_SYSTEM_NAME OR CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/macos")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(__qt_internal_cmake_apple_support_files_path "${_qt_import_prefix}/ios")
endif()
endif()
# Public helpers available to all Qt packages.

View File

@ -148,7 +148,7 @@ function(qt_internal_add_executable name)
if(WASM)
# WASM unconditionally sets DISABLE_EXCEPTION_CATCHING=1
qt_internal_set_exceptions_flags("${name}" NO_EXCEPTIONS)
qt_internal_set_exceptions_flags("${name}" FALSE)
else()
qt_internal_set_exceptions_flags("${name}" ${arg_EXCEPTIONS})
endif()
@ -422,7 +422,8 @@ function(qt_internal_add_configure_time_executable target)
)
set(should_build_at_configure_time TRUE)
if(EXISTS "${target_binary_path}")
if(QT_INTERNAL_HAVE_CONFIGURE_TIME_${target} AND
EXISTS "${target_binary_path}" AND EXISTS "${timestamp_file}")
set(last_ts 0)
foreach(source IN LISTS sources)
file(TIMESTAMP "${source}" ts "%s")
@ -437,6 +438,37 @@ function(qt_internal_add_configure_time_executable target)
endif()
endif()
set(cmake_flags_arg "")
if(arg_CMAKE_FLAGS)
set(cmake_flags_arg CMAKE_FLAGS "${arg_CMAKE_FLAGS}")
endif()
qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
foreach(lang IN LISTS enabled_languages)
set(compiler_flags_var "CMAKE_${lang}_FLAGS")
list(APPEND cmake_flags_arg "-D${compiler_flags_var}:STRING=${${compiler_flags_var}}")
if(arg_CONFIG)
set(compiler_flags_var_config "${compiler_flags_var}${config_suffix}")
list(APPEND cmake_flags_arg
"-D${compiler_flags_var_config}:STRING=${${compiler_flags_var_config}}")
endif()
endforeach()
qt_internal_get_target_link_types_for_flag_manipulation(target_link_types)
foreach(linker_type IN LISTS target_link_types)
set(linker_flags_var "CMAKE_${linker_type}_LINKER_FLAGS")
list(APPEND cmake_flags_arg "-D${linker_flags_var}:STRING=${${linker_flags_var}}")
if(arg_CONFIG)
set(linker_flags_var_config "${linker_flags_var}${config_suffix}")
list(APPEND cmake_flags_arg
"-D${linker_flags_var_config}:STRING=${${linker_flags_var_config}}")
endif()
endforeach()
if(NOT "${QT_INTERNAL_CMAKE_FLAGS_CONFIGURE_TIME_TOOL_${target}}" STREQUAL "${cmake_flags_arg}")
set(should_build_at_configure_time TRUE)
endif()
if(should_build_at_configure_time)
foreach(arg IN LISTS multi_value_args)
string(TOLOWER "${arg}" template_arg_name)
@ -460,33 +492,11 @@ function(qt_internal_add_configure_time_executable target)
set(template "${arg_CMAKELISTS_TEMPLATE}")
endif()
set(cmake_flags_arg)
if(arg_CMAKE_FLAGS)
set(cmake_flags_arg CMAKE_FLAGS "${arg_CMAKE_FLAGS}")
endif()
configure_file("${template}" "${target_binary_dir}/CMakeLists.txt" @ONLY)
qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
foreach(lang IN LISTS enabled_languages)
set(compiler_flags_var "CMAKE_${lang}_FLAGS")
list(APPEND cmake_flags_arg "-D${compiler_flags_var}:STRING=${${compiler_flags_var}}")
if(arg_CONFIG)
set(compiler_flags_var_config "${compiler_flags_var}${config_suffix}")
list(APPEND cmake_flags_arg
"-D${compiler_flags_var_config}:STRING=${${compiler_flags_var_config}}")
endif()
endforeach()
qt_internal_get_target_link_types_for_flag_manipulation(target_link_types)
foreach(linker_type IN LISTS target_link_types)
set(linker_flags_var "CMAKE_${linker_type}_LINKER_FLAGS")
list(APPEND cmake_flags_arg "-D${linker_flags_var}:STRING=${${linker_flags_var}}")
if(arg_CONFIG)
set(linker_flags_var_config "${linker_flags_var}${config_suffix}")
list(APPEND cmake_flags_arg
"-D${linker_flags_var_config}:STRING=${${linker_flags_var_config}}")
endif()
endforeach()
if(EXISTS "${target_binary_dir}/CMakeCache.txt")
file(REMOVE "${target_binary_dir}/CMakeCache.txt")
endif()
try_compile(result
"${target_binary_dir}"
@ -496,7 +506,12 @@ function(qt_internal_add_configure_time_executable target)
OUTPUT_VARIABLE try_compile_output
)
set(QT_INTERNAL_CMAKE_FLAGS_CONFIGURE_TIME_TOOL_${target}
"${cmake_flags_arg}" CACHE INTERNAL "")
file(WRITE "${timestamp_file}" "")
set(QT_INTERNAL_HAVE_CONFIGURE_TIME_${target} ${result} CACHE INTERNAL
"Indicates that the configure-time target ${target} was built")
if(NOT result)
message(FATAL_ERROR "Unable to build ${target}: ${try_compile_output}")
endif()

View File

@ -177,15 +177,20 @@ function(qt_evaluate_config_expression resultVar)
set(${resultVar} ${result} PARENT_SCOPE)
endfunction()
function(_qt_internal_get_feature_condition_keywords out_var)
set(keywords "EQUAL" "LESS" "LESS_EQUAL" "GREATER" "GREATER_EQUAL" "STREQUAL" "STRLESS"
"STRLESS_EQUAL" "STRGREATER" "STRGREATER_EQUAL" "VERSION_EQUAL" "VERSION_LESS"
"VERSION_LESS_EQUAL" "VERSION_GREATER" "VERSION_GREATER_EQUAL" "MATCHES"
"EXISTS" "COMMAND" "DEFINED" "NOT" "AND" "OR" "TARGET" "EXISTS" "IN_LIST" "(" ")")
set(${out_var} "${keywords}" PARENT_SCOPE)
endfunction()
function(_qt_internal_dump_expression_values expression_dump expression)
set(dump "")
set(skipNext FALSE)
set(isTargetExpression FALSE)
set(keywords "EQUAL" "LESS" "LESS_EQUAL" "GREATER" "GREATER_EQUAL" "STREQUAL" "STRLESS"
"STRLESS_EQUAL" "STRGREATER" "STRGREATER_EQUAL" "VERSION_EQUAL" "VERSION_LESS"
"VERSION_LESS_EQUAL" "VERSION_GREATER" "VERSION_GREATER_EQUAL" "MATCHES"
"EXISTS" "COMMAND" "DEFINED" "NOT" "AND" "OR" "TARGET" "EXISTS" "IN_LIST" "(" ")")
_qt_internal_get_feature_condition_keywords(keywords)
list(LENGTH expression length)
math(EXPR length "${length}-1")
@ -239,19 +244,44 @@ endfunction()
# ${computed} is also stored when reconfiguring and the condition does not align with the user
# provided value.
#
function(qt_feature_check_and_save_user_provided_value resultVar feature condition computed label)
function(qt_feature_check_and_save_user_provided_value
resultVar feature condition condition_expression computed label)
if (DEFINED "FEATURE_${feature}")
# Revisit new user provided value
set(user_value "${FEATURE_${feature}}")
string(TOUPPER "${user_value}" result)
string(TOUPPER "${user_value}" user_value_upper)
set(result "${user_value_upper}")
# If the build is marked as dirty and the user_value doesn't meet the new condition,
# reset it to the computed one.
# If ${feature} depends on another dirty feature, reset the ${feature} value to
# ${computed}.
get_property(dirty_build GLOBAL PROPERTY _qt_dirty_build)
if(NOT condition AND result AND dirty_build)
set(result "${computed}")
message(WARNING "Reset FEATURE_${feature} value to ${result}, because it doesn't \
meet its condition after reconfiguration.")
if(dirty_build)
_qt_internal_feature_compute_feature_dependencies(deps "${feature}")
if(deps)
get_property(dirty_features GLOBAL PROPERTY _qt_dirty_features)
foreach(dirty_feature ${dirty_features})
if(dirty_feature IN_LIST deps AND NOT "${result}" STREQUAL "${computed}")
set(result "${computed}")
message(WARNING
"Auto-resetting 'FEATURE_${feature}' from '${user_value_upper}' to "
"'${computed}', "
"because the dependent feature '${dirty_feature}' was marked dirty.")
# Append ${feature} as a new dirty feature.
set_property(GLOBAL APPEND PROPERTY _qt_dirty_features "${feature}")
break()
endif()
endforeach()
endif()
# If the build is marked as dirty and the feature doesn't meet its condition,
# reset its value to the computed one, which is likely OFF.
if(NOT condition AND result)
set(result "${computed}")
message(WARNING "Resetting 'FEATURE_${feature}' from '${user_value_upper}' to "
"'${computed}' because it doesn't meet its condition after reconfiguration. "
"Condition expression is: '${condition_expression}'")
endif()
endif()
set(bool_values OFF NO FALSE N ON YES TRUE Y)
@ -299,6 +329,14 @@ condition:\n ${conditionString}\nCondition values dump:\n ${conditionDump}
set(QT_KNOWN_FEATURES "${QT_KNOWN_FEATURES}" CACHE INTERNAL "" FORCE)
endmacro()
macro(_qt_internal_parse_feature_definition feature)
cmake_parse_arguments(arg
"PRIVATE;PUBLIC"
"LABEL;PURPOSE;SECTION;"
"AUTODETECT;CONDITION;ENABLE;DISABLE;EMIT_IF"
${_QT_FEATURE_DEFINITION_${feature}})
endmacro()
# The build system stores 2 CMake cache variables for each feature, to allow detecting value changes
# during subsequent reconfigurations.
@ -334,9 +372,7 @@ function(qt_evaluate_feature 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}})
_qt_internal_parse_feature_definition("${feature}")
if("${arg_ENABLE}" STREQUAL "")
set(arg_ENABLE OFF)
@ -374,16 +410,7 @@ function(qt_evaluate_feature feature)
qt_evaluate_config_expression(emit_if ${arg_EMIT_IF})
endif()
# If FEATURE_ is not defined trying to use INPUT_ variable to enable/disable feature.
if ((NOT DEFINED "FEATURE_${feature}") AND (DEFINED "INPUT_${feature}")
AND (NOT "${INPUT_${feature}}" STREQUAL "undefined")
AND (NOT "${INPUT_${feature}}" STREQUAL ""))
if(INPUT_${feature})
set(FEATURE_${feature} ON)
else()
set(FEATURE_${feature} OFF)
endif()
endif()
qt_internal_compute_feature_value_from_possible_input("${feature}")
# Warn about a feature which is not emitted, but the user explicitly provided a value for it.
if(NOT emit_if AND DEFINED FEATURE_${feature})
@ -401,7 +428,8 @@ function(qt_evaluate_feature feature)
# Only save the user provided value if the feature was emitted.
if(emit_if)
qt_feature_check_and_save_user_provided_value(
saved_user_value "${feature}" "${condition}" "${computed}" "${arg_LABEL}")
saved_user_value
"${feature}" "${condition}" "${arg_CONDITION}" "${computed}" "${arg_LABEL}")
else()
# Make sure the feature internal value is OFF if not emitted.
set(saved_user_value OFF)
@ -414,6 +442,60 @@ function(qt_evaluate_feature feature)
set(QT_FEATURE_LABEL_${feature} "${arg_LABEL}" CACHE INTERNAL "")
endfunction()
# Collect feature names that ${feature} depends on, by inspecting the given expression.
function(_qt_internal_feature_extract_feature_dependencies_from_expression out_var expression)
list(LENGTH expression length)
math(EXPR length "${length}-1")
if(length LESS 0)
set(${out_var} "" PARENT_SCOPE)
return()
endif()
set(deps "")
foreach(memberIdx RANGE ${length})
list(GET expression ${memberIdx} member)
if(member MATCHES "^QT_FEATURE_(.+)")
list(APPEND deps "${CMAKE_MATCH_1}")
endif()
endforeach()
set(${out_var} "${deps}" PARENT_SCOPE)
endfunction()
# Collect feature names that ${feature} depends on, based on feature names that appear
# in the ${feature}'s condition expressions.
function(_qt_internal_feature_compute_feature_dependencies out_var feature)
# Only compute the deps once per feature.
get_property(deps_computed GLOBAL PROPERTY _qt_feature_deps_computed_${feature})
if(deps_computed)
get_property(deps GLOBAL PROPERTY _qt_feature_deps_${feature})
set(${out_var} "${deps}" PARENT_SCOPE)
return()
endif()
_qt_internal_parse_feature_definition("${feature}")
set(options_to_check AUTODETECT CONDITION ENABLE DISABLE EMIT_IF)
set(deps "")
# Go through each option that takes condition expressions and collect the feature names.
foreach(option ${options_to_check})
set(option_value "${arg_${option}}")
if(option_value)
_qt_internal_feature_extract_feature_dependencies_from_expression(
option_deps "${option_value}")
if(option_deps)
list(APPEND deps ${option_deps})
endif()
endif()
endforeach()
set_property(GLOBAL PROPERTY _qt_feature_deps_computed_${feature} TRUE)
set_property(GLOBAL PROPERTY _qt_feature_deps_${feature} "${deps}")
set(${out_var} "${deps}" PARENT_SCOPE)
endfunction()
function(qt_feature_config feature config_var_name)
qt_feature_normalize_name("${feature}" feature)
cmake_parse_arguments(PARSE_ARGV 2 arg
@ -786,6 +868,49 @@ function(qt_feature_copy_global_config_features_to_core target)
endif()
endfunction()
function(qt_internal_detect_dirty_features)
# We need to clean up QT_FEATURE_*, but only once per configuration cycle
get_property(qt_feature_clean GLOBAL PROPERTY _qt_feature_clean)
if(NOT qt_feature_clean AND NOT QT_NO_FEATURE_AUTO_RESET)
message(STATUS "Checking for feature set changes")
set_property(GLOBAL PROPERTY _qt_feature_clean TRUE)
foreach(feature ${QT_KNOWN_FEATURES})
qt_internal_compute_feature_value_from_possible_input("${feature}")
if(DEFINED "FEATURE_${feature}" AND
NOT "${QT_FEATURE_${feature}}" STREQUAL "${FEATURE_${feature}}")
message(" '${feature}' was changed from ${QT_FEATURE_${feature}} "
"to ${FEATURE_${feature}}")
set(dirty_build TRUE)
set_property(GLOBAL APPEND PROPERTY _qt_dirty_features "${feature}")
# If the user changed the value of the feature directly (e.g by editing
# CMakeCache.txt), and not via its associated INPUT variable, unset the INPUT cache
# variable before it is used in feature evaluation, to ensure a stale value doesn't
# influence other feature values, especially when QT_INTERNAL_CALLED_FROM_CONFIGURE
# is TRUE and the INPUT_foo variable is not passed.
# e.g. first configure -no-gui, then manually toggle FEATURE_gui to ON in
# CMakeCache.txt, then reconfigure (with the configure script) without -no-gui.
# Without this unset(), we'd have switched FEATURE_gui to OFF again.
if(NOT FEATURE_${feature}_computed_from_input)
unset("INPUT_${feature}" CACHE)
endif()
endif()
unset("QT_FEATURE_${feature}" CACHE)
endforeach()
set(QT_KNOWN_FEATURES "" CACHE INTERNAL "" FORCE)
if(dirty_build)
set_property(GLOBAL PROPERTY _qt_dirty_build TRUE)
message(WARNING
"Due to detected feature set changes, dependent features "
"will be re-computed automatically. This might cause a lot of files to be rebuilt. "
"To disable this behavior, configure with -DQT_NO_FEATURE_AUTO_RESET=ON")
endif()
endif()
endfunction()
function(qt_config_compile_test name)
if(DEFINED "TEST_${name}")
return()
@ -924,6 +1049,7 @@ function(qt_config_compile_test name)
# 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)
message(STATUS "Performing Test ${arg_LABEL} - Failed because ${library} not found")
set(HAVE_${name} FALSE)
break()
endif()

View File

@ -16,6 +16,15 @@ function(qt_find_package_promote_targets_to_global_scope target)
"qt_find_package_targets_dict" "promote_global")
endfunction()
# As an optimization when using -developer-build, qt_find_package records which
# packages were found during the initial configuration. Then on subsequent
# reconfigurations it skips looking for packages that were not found on the
# initial run.
# For the build system to pick up a newly added qt_find_package call, you need to:
# - Start with a clean build dir
# - Or remove the <builddir>/CMakeCache.txt file and configure from scratch
# - Or remove the QT_INTERNAL_PREVIOUSLY_FOUND_PACKAGES cache variable (by
# editing CMakeCache.txt) and reconfigure.
macro(qt_find_package)
# Get the target names we expect to be provided by the package.
set(find_package_options CONFIG NO_MODULE MODULE REQUIRED)

View File

@ -1,6 +1,23 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# Sets '${var}' to a genex that extracts the target's property.
# Sets 'have_${var}' to a genex that checks that the property has a
# non-empty value.
macro(qt_internal_genex_get_property var target property)
set(${var} "$<TARGET_PROPERTY:${target},${property}>")
set(have_${var} "$<BOOL:${${var}}>")
endmacro()
# Sets '${var}' to a genex that will join the given property values
# using '${glue}' and will surround the entire output with '${prefix}'
# and '${suffix}'.
macro(qt_internal_genex_get_joined_property var target property prefix suffix glue)
qt_internal_genex_get_property("${var}" "${target}" "${property}")
set(${var}
"$<${have_${var}}:${prefix}$<JOIN:${${var}},${glue}>${suffix}>")
endmacro()
# This function generates LD version script for the target and uses it in the target linker line.
# Function has two modes dependending on the specified arguments.
# Arguments:
@ -33,9 +50,21 @@ function(qt_internal_add_linker_version_script target)
endif()
string(APPEND contents "};\n")
set(current "Qt_${PROJECT_VERSION_MAJOR}")
string(APPEND contents "${current} { *; };\n")
string(APPEND contents "${current} {\n *;")
get_target_property(target_type ${target} TYPE)
if(NOT target_type STREQUAL "INTERFACE_LIBRARY")
set(genex_prefix "\n ")
set(genex_glue "$<SEMICOLON>\n ")
set(genex_suffix "$<SEMICOLON>")
qt_internal_genex_get_joined_property(
linker_exports "${target}" _qt_extra_linker_script_exports
"${genex_prefix}" "${genex_suffix}" "${genex_glue}"
)
string(APPEND contents "${linker_exports}")
endif()
string(APPEND contents "\n};\n")
get_target_property(type ${target} TYPE)
if(NOT target_type STREQUAL "INTERFACE_LIBRARY")
set(property_genex "$<TARGET_PROPERTY:${target},_qt_extra_linker_script_content>")
set(check_genex "$<BOOL:${property_genex}>")

View File

@ -4,6 +4,7 @@
macro(qt_find_apple_system_frameworks)
if(APPLE)
qt_internal_find_apple_system_framework(FWAppKit AppKit)
qt_internal_find_apple_system_framework(FWCFNetwork CFNetwork)
qt_internal_find_apple_system_framework(FWAssetsLibrary AssetsLibrary)
qt_internal_find_apple_system_framework(FWPhotos Photos)
qt_internal_find_apple_system_framework(FWAudioToolbox AudioToolbox)
@ -58,7 +59,7 @@ function(qt_internal_find_apple_system_framework out_var framework_name)
endif()
endfunction()
# Copy header files to QtXYZ.framework/Versions/A/Headers/
# Copy header files to the framework's Headers directory
# Use this function for header files that
# - are not added as source files to the target
# - are not marked as PUBLIC_HEADER
@ -71,7 +72,7 @@ function(qt_copy_framework_headers target)
set(options)
set(oneValueArgs)
set(multiValueArgs PUBLIC PRIVATE QPA)
set(multiValueArgs PUBLIC PRIVATE QPA RHI)
cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
qt_internal_get_framework_info(fw ${target})
@ -79,25 +80,43 @@ function(qt_copy_framework_headers target)
set(output_dir_PUBLIC "${output_dir}/${fw_versioned_header_dir}")
set(output_dir_PRIVATE "${output_dir}/${fw_private_module_header_dir}/private")
set(output_dir_QPA "${output_dir}/${fw_private_module_header_dir}/qpa")
set(output_dir_RHI "${output_dir}/${fw_private_module_header_dir}/rhi")
qt_internal_module_info(module "${target}")
set(out_files)
foreach(type IN ITEMS PUBLIC PRIVATE QPA)
set(out_files "")
set(in_files "")
set(copy_commands "")
foreach(type IN ITEMS PUBLIC PRIVATE QPA RHI)
set(in_files_${type} "")
set(fw_output_header_dir "${output_dir_${type}}")
foreach(hdr IN LISTS arg_${type})
get_filename_component(in_file_path ${hdr} ABSOLUTE)
get_filename_component(in_file_name ${hdr} NAME)
set(out_file_path "${fw_output_header_dir}/${in_file_name}")
add_custom_command(
OUTPUT ${out_file_path}
DEPENDS ${in_file_path}
COMMAND ${CMAKE_COMMAND} -E make_directory "${fw_output_header_dir}"
COMMAND ${CMAKE_COMMAND} -E copy "${in_file_path}" "${fw_output_header_dir}"
VERBATIM)
list(APPEND out_files ${out_file_path})
list(APPEND in_files_${type} "${in_file_path}")
endforeach()
if(in_files_${type})
list(APPEND copy_commands
COMMAND ${CMAKE_COMMAND} -E copy ${in_files_${type}} "${fw_output_header_dir}")
list(APPEND in_files ${in_files_${type}})
endif()
endforeach()
list(REMOVE_DUPLICATES out_files)
list(REMOVE_DUPLICATES in_files)
add_custom_command(
OUTPUT "${output_dir}/${fw_versioned_header_dir}" ${out_files}
DEPENDS ${in_files} ${target}_sync_headers
COMMAND
${CMAKE_COMMAND} -E copy_directory
"${module_build_interface_include_dir}/.syncqt_staging"
"${output_dir}/${fw_versioned_header_dir}"
${copy_commands}
VERBATIM
COMMENT "Copy the ${target} header files to the framework directory"
)
set_property(TARGET ${target} APPEND PROPERTY
QT_COPIED_FRAMEWORK_HEADERS "${out_files}")
endfunction()
@ -164,8 +183,13 @@ function(qt_internal_get_framework_info out_var target)
set(${out_var}_name "${module}")
set(${out_var}_dir "${${out_var}_name}.framework")
set(${out_var}_header_dir "${${out_var}_dir}/Headers")
set(${out_var}_versioned_header_dir "${${out_var}_dir}/Versions/${${out_var}_version}/Headers")
set(${out_var}_private_header_dir "${${out_var}_header_dir}/${${out_var}_bundle_version}")
if(UIKIT)
# iOS frameworks do not version their headers
set(${out_var}_versioned_header_dir "${${out_var}_header_dir}")
else()
set(${out_var}_versioned_header_dir "${${out_var}_dir}/Versions/${${out_var}_version}/Headers")
endif()
set(${out_var}_private_header_dir "${${out_var}_versioned_header_dir}/${${out_var}_bundle_version}")
set(${out_var}_private_module_header_dir "${${out_var}_private_header_dir}/${module}")
set(${out_var}_name "${${out_var}_name}" PARENT_SCOPE)

View File

@ -104,6 +104,7 @@ function(qt_internal_add_headersclean_target module_target module_headers)
set(hcleanFLAGS -Wall -Wextra -Werror -Woverloaded-virtual -Wshadow -Wundef -Wfloat-equal
-Wnon-virtual-dtor -Wpointer-arith -Wformat-security -Wno-long-long -Wno-variadic-macros
-fno-operator-names
-pedantic-errors)
if(QT_FEATURE_reduce_relocations AND UNIX)
@ -181,9 +182,7 @@ function(qt_internal_add_headersclean_target module_target module_headers)
)
set(input_header_path_type ABSOLUTE)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# -Za would enable strict standards behavior, but we can't add it because
# <windows.h> and <GL.h> violate the standards.
set(hcleanFLAGS -std:c++latest -Zc:__cplusplus -WX -W3)
set(hcleanFLAGS -std:c++latest -Zc:__cplusplus -WX -W3 -EHsc)
# Because we now add `-DNOMINMAX` to `PlatformCommonInternal`.
set(hcleanUDEFS -UNOMINMAX)

214
cmake/QtInitProject.cmake Normal file
View File

@ -0,0 +1,214 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
if(NOT PROJECT_DIR)
set(PROJECT_DIR "${CMAKE_SOURCE_DIR}")
endif()
get_filename_component(project_name "${PROJECT_DIR}" NAME)
get_filename_component(project_abs_dir "${PROJECT_DIR}" ABSOLUTE)
if(NOT IS_DIRECTORY "${project_abs_dir}")
message(FATAL_ERROR "Unable to scan ${project_abs_dir}. The directory doesn't exist.")
endif()
set(known_extensions "")
set(types "")
# The function allows extending the capabilities of this script and establishes simple relation
# chains between the file types.
# Option Arguments:
# EXPERIMENTAL
# Marks that the support of the following files is experimental and the required Qt modules
# are in Technical preview state.
# DEPRECATED
# Marks that the support of the following files will be discontinued soon and the required
# Qt modules are deprecated.
# One-value Arguments:
# TEMPLATE
# The CMake code template. Use the '@files@' string for the files substitution.
# Multi-value Arguments:
# EXTENSIONS
# List of the file extensions treated as this source 'type'.
# MODULES
# List of Qt modules required for these file types.
# DEPENDS
# The prerequisite source 'type' needed by this source 'type'
macro(handle_type type)
cmake_parse_arguments(arg
"EXPERIMENTAL;DEPRECATED"
"TEMPLATE"
"EXTENSIONS;MODULES;DEPENDS"
${ARGN}
)
if(NOT arg_EXTENSIONS)
message(FATAL_ERROR "Unexpected call handle_type of with no EXTENSIONS specified."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(unique_extensions_subset "${known_extensions}")
list(REMOVE_ITEM unique_extensions_subset ${arg_EXTENSIONS})
if(NOT "${known_extensions}" STREQUAL "${unique_extensions_subset}")
message(FATAL_ERROR "${type} contains duplicated extensions, this is not supported."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(${type}_file_extensions "${arg_EXTENSIONS}")
if(NOT arg_TEMPLATE)
message(FATAL_ERROR "Unexpected call handle_type of with no TEMPLATE specified."
" This is the Qt issue, please report a bug at https://bugreports.qt.io.")
endif()
set(${type}_template "${arg_TEMPLATE}")
if(arg_MODULES)
set(${type}_required_modules "${arg_MODULES}")
endif()
list(APPEND types ${type})
if(arg_EXPERIMENTAL)
set(${type}_is_experimental TRUE)
else()
set(${type}_is_experimental FALSE)
endif()
if(arg_DEPRECATED)
set(${type}_is_deprecated TRUE)
else()
set(${type}_is_deprecated FALSE)
endif()
if(arg_DEPENDS)
set(${type}_dependencies ${arg_DEPENDS})
endif()
endmacro()
handle_type(cpp EXTENSIONS .c .cc .cpp .cxx .h .hh .hxx .hpp MODULES Core TEMPLATE
"\n\nqt_add_executable(${project_name}
@files@
)"
)
handle_type(qml EXTENSIONS .qml .js .mjs MODULES Gui Qml Quick TEMPLATE
"\n\nqt_add_qml_module(${project_name}
URI ${project_name}
OUTPUT_DIRECTORY qml
VERSION 1.0
RESOURCE_PREFIX /qt/qml
QML_FILES
@files@
)"
)
handle_type(ui EXTENSIONS .ui MODULES Gui Widgets DEPENDS cpp TEMPLATE
"\n\ntarget_sources(${project_name}
PRIVATE
@files@
)"
)
handle_type(qrc EXTENSIONS .qrc DEPENDS cpp TEMPLATE
"\n\nqt_add_resources(${project_name}_resources @files@)
target_sources(${project_name}
PRIVATE
\\\${${project_name}_resources}
)"
)
handle_type(protobuf EXPERIMENTAL EXTENSIONS .proto MODULES Protobuf Grpc TEMPLATE
"\n\nqt_add_protobuf(${project_name}
GENERATE_PACKAGE_SUBFOLDERS
PROTO_FILES
@files@
)"
)
set(extra_packages "")
file(GLOB_RECURSE files RELATIVE "${project_abs_dir}" "${project_abs_dir}/*")
foreach(f IN LISTS files)
get_filename_component(file_extension "${f}" LAST_EXT)
string(TOLOWER "${file_extension}" file_extension)
foreach(type IN LISTS types)
if(file_extension IN_LIST ${type}_file_extensions)
list(APPEND ${type}_sources "${f}")
list(APPEND packages ${${type}_required_modules})
if(${type}_is_experimental)
message("We found files with the following extensions in your directory:"
" ${${type}_file_extensions}\n"
"Note that the modules ${${type}_required_modules} are"
" in the technical preview state.")
endif()
if(${type}_is_deprecated)
message("We found files with the following extensions in your directory:"
" ${${type}_file_extensions}\n"
"Note that the modules ${${type}_required_modules} are deprecated.")
endif()
break()
endif()
endforeach()
endforeach()
if(packages)
list(REMOVE_DUPLICATES packages)
list(JOIN packages " " packages_string)
list(JOIN packages "\n Qt::" deps_string)
set(deps_string "Qt::${deps_string}")
endif()
set(content
"cmake_minimum_required(VERSION 3.16)
project(${project_name} LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS ${packages_string})
qt_standard_project_setup()"
)
set(has_useful_sources FALSE)
foreach(type IN LISTS types)
if(${type}_sources)
set(skip FALSE)
foreach(dep IN LISTS ${type}_dependencies)
if(NOT ${dep}_sources)
set(skip TRUE)
message("Sources of type ${${type}_file_extensions} cannot live in the project"
" without ${${dep}_file_extensions} files. Skipping.")
break()
endif()
endforeach()
if(skip)
continue()
endif()
set(has_useful_sources TRUE)
string(REGEX MATCH "( +)@files@" unused "${${type}_template}")
list(JOIN ${type}_sources "\n${CMAKE_MATCH_1}" ${type}_sources)
string(REPLACE "@files@" "${${type}_sources}" ${type}_content
"${${type}_template}")
string(APPEND content "${${type}_content}")
endif()
endforeach()
string(APPEND content "\n\ntarget_link_libraries(${project_name}
PRIVATE
${deps_string}
)\n"
)
if(EXISTS "${project_abs_dir}/CMakeLists.txt")
message(FATAL_ERROR "Project is already initialized in current directory."
" Please remove CMakeLists.txt if you want to regenerate the project.")
endif()
if(NOT has_useful_sources)
message(FATAL_ERROR "Could not find any files to generate the project.")
endif()
file(WRITE "${project_abs_dir}/CMakeLists.txt" "${content}")
message("The project file is successfully generated. To build the project run:"
"\nmkdir build"
"\ncd build"
"\nqt-cmake ${project_abs_dir}"
"\ncmake --build ${project_abs_dir}"
)

View File

@ -156,6 +156,8 @@ qt_internal_add_target_aliases(PlatformToolInternal)
target_link_libraries(PlatformToolInternal INTERFACE PlatformAppInternal)
qt_internal_add_global_definition(QT_NO_JAVA_STYLE_ITERATORS)
qt_internal_add_global_definition(QT_NO_AS_CONST)
qt_internal_add_global_definition(QT_NO_QEXCHANGE)
qt_internal_add_global_definition(QT_NO_NARROWING_CONVERSIONS_IN_CONNECT)
qt_internal_add_global_definition(QT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH)

View File

@ -35,6 +35,15 @@ function(qt_process_qlalr consuming_target input_file_list flags)
return()
endif()
qt_internal_is_skipped_test(skipped ${consuming_target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${consuming_target})
if(in_batch)
_qt_internal_test_batch_target_name(consuming_target)
endif()
foreach(input_file ${input_file_list})
file(STRINGS ${input_file} input_file_lines)
qt_qlalr_find_option_in_list("${input_file_lines}" "^%parser(.+)" "parser")

View File

@ -27,6 +27,8 @@ endif()
if (NOT QT_NO_CREATE_TARGETS AND @INSTALL_CMAKE_NAMESPACE@@target@_FOUND)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@Targets.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@AdditionalTargetInfo.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@ExtraProperties.cmake"
OPTIONAL)
if(NOT QT_NO_CREATE_VERSIONLESS_TARGETS)
include("${CMAKE_CURRENT_LIST_DIR}/@INSTALL_CMAKE_NAMESPACE@@target@VersionlessTargets.cmake")
endif()

View File

@ -11,7 +11,8 @@ if(EXISTS ${HEADER_CHECK_EXCEPTIONS})
file(READ ${HEADER_CHECK_EXCEPTIONS} header_check_exception_list)
endif()
file(TO_CMAKE_PATH "${INPUT_HEADER_FILE}" header)
get_filename_component(header "${INPUT_HEADER_FILE}" REALPATH)
file(TO_CMAKE_PATH "${header}" header)
foreach(exception IN LISTS header_check_exception_list)
file(TO_CMAKE_PATH "${exception}" exception)
if(exception STREQUAL header)

View File

@ -30,6 +30,7 @@ macro(qt_internal_get_internal_add_module_keywords option_args single_args multi
EXTERNAL_HEADERS_DIR
PRIVATE_HEADER_FILTERS
QPA_HEADER_FILTERS
RHI_HEADER_FILTERS
HEADER_SYNC_SOURCE_DIRECTORY
${__default_target_info_args}
)
@ -114,6 +115,10 @@ endfunction()
# The regular expressions that filter QPA header files out of target sources.
# The value must use the following format 'regex1|regex2|regex3'.
#
# RHI_HEADER_FILTERS
# The regular expressions that filter RHI header files out of target sources.
# The value must use the following format 'regex1|regex2|regex3'.
#
# HEADER_SYNC_SOURCE_DIRECTORY
# The source directory for header sync procedure. Header files outside this directory will be
# ignored by syncqt. The specifying this directory allows to skip the parsing of the whole
@ -326,14 +331,24 @@ function(qt_internal_add_module target)
EXPORT_PROPERTIES "${export_properties}")
endif()
# FIXME: This workaround is needed because the deployment logic
# for iOS and WASM just copies/embeds the directly linked library,
# which will just be a versioned symlink to the actual library.
if((UIKIT OR WASM) AND BUILD_SHARED_LIBS)
set(version_args "")
else()
set(version_args
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR})
endif()
if(NOT arg_HEADER_MODULE)
set_target_properties(${target} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
RUNTIME_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_BINDIR}"
ARCHIVE_OUTPUT_DIRECTORY "${QT_BUILD_DIR}/${INSTALL_LIBDIR}"
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
)
${version_args}
)
qt_set_target_info_properties(${target} ${ARGN})
qt_handle_multi_config_output_dirs("${target}")
@ -436,6 +451,13 @@ function(qt_internal_add_module target)
set_target_properties(${target}
PROPERTIES _qt_module_qpa_headers_filter_regex "${qpa_filter_regex}")
set(rhi_filter_regex "")
if(arg_RHI_HEADER_FILTERS)
set(rhi_filter_regex "${arg_RHI_HEADER_FILTERS}")
endif()
set_target_properties(${target}
PROPERTIES _qt_module_rhi_headers_filter_regex "${rhi_filter_regex}")
set(private_filter_regex ".+_p(ch)?\\.h")
if(arg_PRIVATE_HEADER_FILTERS)
set(private_filter_regex "${private_filter_regex}|${arg_PRIVATE_HEADER_FILTERS}")
@ -793,6 +815,11 @@ set(QT_ALLOW_MISSING_TOOLS_PACKAGES TRUE)")
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}")
qt_internal_export_genex_properties(TARGETS ${target}
EXPORT_NAME_PREFIX ${INSTALL_CMAKE_NAMESPACE}${target}
CONFIG_INSTALL_DIR "${config_install_dir}"
)
### fixme: cmake is missing a built-in variable for this. We want to apply it only to modules and plugins
# that belong to Qt.
if(NOT arg_HEADER_MODULE)
@ -878,6 +905,7 @@ function(qt_finalize_module target)
PUBLIC ${module_headers_public} "${module_depends_header}"
PRIVATE ${module_headers_private}
QPA ${module_headers_qpa}
RHI ${module_headers_rhi}
)
qt_finalize_framework_headers_copy(${target})
@ -910,6 +938,7 @@ endfunction()
# * foo_versioned_inner_include_dir with the value "QtCore/6.2.0/QtCore"
# * foo_private_include_dir with the value "QtCore/6.2.0/QtCore/private"
# * foo_qpa_include_dir with the value "QtCore/6.2.0/QtCore/qpa"
# * foo_rhi_include_dir with the value "QtCore/6.2.0/QtCore/rhi"
# * foo_interface_name the interface name of the module stored in _qt_module_interface_name
# property, e.g. Core.
#
@ -932,6 +961,9 @@ endfunction()
# * foo_<build|install>_qpa_include_dir with
# qtbase_build_dir/include/QtCore/6.2.0/QtCore/qpa for build interface and
# include/QtCore/6.2.0/QtCore/qpa for install interface.
# * foo_<build|install>_rhi_include_dir with
# qtbase_build_dir/include/QtCore/6.2.0/QtCore/rhi for build interface and
# include/QtCore/6.2.0/QtCore/rhi for install interface.
# The following values are set by the function and might be useful in caller's scope:
# * repo_install_interface_include_dir contains path to the top-level repository include directory,
# e.g. qtbase_build_dir/include
@ -966,6 +998,8 @@ the different base name for the module info variables.")
"${${result}_versioned_inner_include_dir}/private")
set("${result}_qpa_include_dir"
"${${result}_versioned_inner_include_dir}/qpa")
set("${result}_rhi_include_dir"
"${${result}_versioned_inner_include_dir}/rhi")
# Module build interface directories
set(repo_build_interface_include_dir "${QT_BUILD_DIR}/include")
@ -979,6 +1013,8 @@ the different base name for the module info variables.")
"${repo_build_interface_include_dir}/${${result}_private_include_dir}")
set("${result}_build_interface_qpa_include_dir"
"${repo_build_interface_include_dir}/${${result}_qpa_include_dir}")
set("${result}_build_interface_rhi_include_dir"
"${repo_build_interface_include_dir}/${${result}_rhi_include_dir}")
# Module install interface directories
set(repo_install_interface_include_dir "${INSTALL_INCLUDEDIR}")
@ -992,6 +1028,8 @@ the different base name for the module info variables.")
"${repo_install_interface_include_dir}/${${result}_private_include_dir}")
set("${result}_install_interface_qpa_include_dir"
"${repo_install_interface_include_dir}/${${result}_qpa_include_dir}")
set("${result}_install_interface_rhi_include_dir"
"${repo_install_interface_include_dir}/${${result}_rhi_include_dir}")
set("${result}" "${module}" PARENT_SCOPE)
set("${result}_versioned" "${module_versioned}" PARENT_SCOPE)
@ -1005,6 +1043,7 @@ the different base name for the module info variables.")
"${${result}_versioned_inner_include_dir}" PARENT_SCOPE)
set("${result}_private_include_dir" "${${result}_private_include_dir}" PARENT_SCOPE)
set("${result}_qpa_include_dir" "${${result}_qpa_include_dir}" PARENT_SCOPE)
set("${result}_rhi_include_dir" "${${result}_rhi_include_dir}" PARENT_SCOPE)
set("${result}_interface_name" "${module_interface_name}" PARENT_SCOPE)
# Setting module build interface directories in parent scope
@ -1019,6 +1058,8 @@ the different base name for the module info variables.")
"${${result}_build_interface_private_include_dir}" PARENT_SCOPE)
set("${result}_build_interface_qpa_include_dir"
"${${result}_build_interface_qpa_include_dir}" PARENT_SCOPE)
set("${result}_build_interface_rhi_include_dir"
"${${result}_build_interface_rhi_include_dir}" PARENT_SCOPE)
# Setting module install interface directories in parent scope
set(repo_install_interface_include_dir "${repo_install_interface_include_dir}" PARENT_SCOPE)
@ -1032,6 +1073,8 @@ the different base name for the module info variables.")
"${${result}_install_interface_private_include_dir}" PARENT_SCOPE)
set("${result}_install_interface_qpa_include_dir"
"${${result}_install_interface_qpa_include_dir}" PARENT_SCOPE)
set("${result}_install_interface_rhi_include_dir"
"${${result}_install_interface_rhi_include_dir}" PARENT_SCOPE)
endfunction()
function(qt_internal_list_to_json_array out_var list_var)
@ -1075,6 +1118,10 @@ function(qt_describe_module target)
endif()
set(extra_build_information "")
if(NOT QT_NAMESPACE STREQUAL "")
string(APPEND extra_build_information "
\"namespace\": \"${QT_NAMESPACE}\",")
endif()
if(ANDROID)
string(APPEND extra_build_information "
\"android\": {
@ -1135,7 +1182,7 @@ endfunction()
function(qt_internal_install_module_headers target)
set(options)
set(one_value_args)
set(multi_value_args PUBLIC PRIVATE QPA)
set(multi_value_args PUBLIC PRIVATE QPA RHI)
cmake_parse_arguments(arg "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN})
qt_internal_module_info(module ${target})
@ -1160,6 +1207,7 @@ function(qt_internal_install_module_headers target)
PUBLIC ${arg_PUBLIC}
PRIVATE ${arg_PRIVATE}
QPA ${arg_QPA}
RHI ${arg_RHI}
)
else()
if(arg_PUBLIC)
@ -1173,6 +1221,9 @@ function(qt_internal_install_module_headers target)
if(arg_QPA)
qt_install(FILES ${arg_QPA} DESTINATION "${module_install_interface_qpa_include_dir}")
endif()
if(arg_RHI)
qt_install(FILES ${arg_RHI} DESTINATION "${module_install_interface_rhi_include_dir}")
endif()
endif()
endfunction()
@ -1180,6 +1231,7 @@ function(qt_internal_collect_module_headers out_var target)
set(${out_var}_public "")
set(${out_var}_private "")
set(${out_var}_qpa "")
set(${out_var}_rhi "")
set(${out_var}_all "")
qt_internal_get_target_sources(sources ${target})
@ -1200,6 +1252,7 @@ function(qt_internal_collect_module_headers out_var target)
get_target_property(public_filter ${target} _qt_module_public_headers_filter_regex)
get_target_property(private_filter ${target} _qt_module_private_headers_filter_regex)
get_target_property(qpa_filter ${target} _qt_module_qpa_headers_filter_regex)
get_target_property(rhi_filter ${target} _qt_module_rhi_headers_filter_regex)
set(condition_independent_headers_warning "")
foreach(file_path IN LISTS sources)
@ -1251,6 +1304,8 @@ function(qt_internal_collect_module_headers out_var target)
list(APPEND ${out_var}_all "${file_path}")
if(qpa_filter AND file_name MATCHES "${qpa_filter}")
list(APPEND ${out_var}_qpa "${file_path}")
elseif(rhi_filter AND file_name MATCHES "${rhi_filter}")
list(APPEND ${out_var}_rhi "${file_path}")
elseif(private_filter AND file_name MATCHES "${private_filter}")
list(APPEND ${out_var}_private "${file_path}")
elseif((NOT public_filter OR file_name MATCHES "${public_filter}")
@ -1274,7 +1329,7 @@ function(qt_internal_collect_module_headers out_var target)
endif()
set(header_types public private qpa)
set(header_types public private qpa rhi)
set(has_header_types_properties "")
foreach(header_type IN LISTS header_types)
get_target_property(current_propety_value ${target} _qt_module_has_${header_type}_headers)
@ -1296,5 +1351,6 @@ function(qt_internal_collect_module_headers out_var target)
_qt_module_has_public_headers
_qt_module_has_private_headers
_qt_module_has_qpa_headers
_qt_module_has_rhi_headers
)
endfunction()

View File

@ -12,7 +12,6 @@ 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?

View File

@ -148,6 +148,41 @@ while(NOT "${configure_args}" STREQUAL "")
endif()
endwhile()
# Read the specified manually generator value from CMake command line.
# The '-cmake-generator' argument has higher priority than CMake command line.
if(NOT generator)
set(is_next_arg_generator_name FALSE)
foreach(arg IN LISTS cmake_args)
if(is_next_arg_generator_name)
set(is_next_arg_generator_name FALSE)
if(NOT arg MATCHES "^-.*")
set(generator "${arg}")
set(auto_detect_generator FALSE)
endif()
elseif(arg MATCHES "^-G(.*)")
set(generator "${CMAKE_MATCH_1}")
if(generator)
set(auto_detect_generator FALSE)
else()
set(is_next_arg_generator_name TRUE)
endif()
endif()
endforeach()
endif()
# Attempt to detect the generator type, either single or multi-config
if("${generator}" STREQUAL "Xcode"
OR "${generator}" STREQUAL "Ninja Multi-Config"
OR "${generator}" MATCHES "^Visual Studio")
set(multi_config ON)
else()
set(multi_config OFF)
endif()
# Tell the build system we are configuring via the configure script so we can act on that.
# The cache variable is unset at the end of configuration.
push("-DQT_INTERNAL_CALLED_FROM_CONFIGURE:BOOL=TRUE")
if(FRESH_REQUESTED)
push("-DQT_INTERNAL_FRESH_REQUESTED:BOOL=TRUE")
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24")
@ -339,7 +374,9 @@ function(qtConfValidateValue opt val out_var)
endforeach()
set(${out_var} FALSE PARENT_SCOPE)
qtConfAddError("Invalid value '${val}' supplied to command line option '${opt}'.")
list(JOIN valid_values " " valid_values_str)
qtConfAddError("Invalid value '${val}' supplied to command line option '${opt}'."
"\nAllowed values: ${valid_values_str}\n")
endfunction()
function(qt_commandline_mapped_enum_value opt key out_var)
@ -826,6 +863,7 @@ translate_boolean_input(precompile_header BUILD_WITH_PCH)
translate_boolean_input(unity_build QT_UNITY_BUILD)
translate_string_input(unity_build_batch_size QT_UNITY_BUILD_BATCH_SIZE)
translate_boolean_input(ccache QT_USE_CCACHE)
translate_boolean_input(vcpkg QT_USE_VCPKG)
translate_boolean_input(shared BUILD_SHARED_LIBS)
translate_boolean_input(warnings_are_errors WARNINGS_ARE_ERRORS)
translate_string_input(qt_namespace QT_NAMESPACE)
@ -875,6 +913,7 @@ endif()
drop_input(make)
drop_input(nomake)
translate_boolean_input(install-examples-sources QT_INSTALL_EXAMPLES_SOURCES)
check_qt_build_parts(nomake)
check_qt_build_parts(make)
@ -896,9 +935,9 @@ if(INPUT_force_debug_info)
endif()
list(LENGTH build_configs nr_of_build_configs)
if(nr_of_build_configs EQUAL 1)
if(nr_of_build_configs EQUAL 1 AND NOT multi_config)
push("-DCMAKE_BUILD_TYPE=${build_configs}")
elseif(nr_of_build_configs GREATER 1)
elseif(nr_of_build_configs GREATER 1 OR multi_config)
set(multi_config ON)
string(REPLACE ";" "[[;]]" escaped_build_configs "${build_configs}")
# We must not use the push macro here to avoid variable expansion.
@ -983,6 +1022,14 @@ endforeach()
push("${MODULE_ROOT}")
if(INPUT_sysroot)
qtConfAddWarning("The -sysroot option is deprecated and no longer has any effect. "
"It is recommended to use a toolchain file instead, i.e., "
"-DCMAKE_TOOLCHAIN_FILE=<filename>. "
"Alternatively, you may use -DCMAKE_SYSROOT option "
"to pass the sysroot to CMake.\n")
endif()
# Restore the escaped semicolons in arguments that are lists
list(TRANSFORM cmake_args REPLACE "\\[\\[;\\]\\]" "\\\\;")

View File

@ -27,7 +27,7 @@ function(_qt_internal_handle_ios_launch_screen target)
if(NOT launch_screen AND NOT QT_NO_SET_DEFAULT_IOS_LAUNCH_SCREEN)
set(is_default_launch_screen TRUE)
set(launch_screen
"${__qt_internal_cmake_ios_support_files_path}/LaunchScreen.storyboard")
"${__qt_internal_cmake_apple_support_files_path}/LaunchScreen.storyboard")
endif()
# Check that the launch screen exists.
@ -554,15 +554,13 @@ function(_qt_internal_set_xcode_bitcode_enablement target)
"NO")
endfunction()
function(_qt_internal_generate_ios_info_plist target)
function(_qt_internal_copy_info_plist target)
# If the project already specifies a custom file, we don't override it.
get_target_property(existing_plist "${target}" MACOSX_BUNDLE_INFO_PLIST)
if(existing_plist)
return()
get_target_property(info_plist_in "${target}" MACOSX_BUNDLE_INFO_PLIST)
if(NOT info_plist_in)
set(info_plist_in "${__qt_internal_cmake_apple_support_files_path}/Info.plist.app.in")
endif()
set(info_plist_in "${__qt_internal_cmake_ios_support_files_path}/Info.plist.app.in")
string(MAKE_C_IDENTIFIER "${target}" target_identifier)
set(info_plist_out_dir
"${CMAKE_CURRENT_BINARY_DIR}/.qt/info_plist/${target_identifier}")
@ -592,6 +590,62 @@ function(_qt_internal_generate_ios_info_plist target)
set_target_properties("${target}" PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${info_plist_out}")
endfunction()
function(_qt_internal_plist_buddy plist_file)
cmake_parse_arguments(PARSE_ARGV 1 arg
"" "OUTPUT_VARIABLE;ERROR_VARIABLE" "COMMANDS")
foreach(command ${arg_COMMANDS})
execute_process(COMMAND "/usr/libexec/PlistBuddy"
-c "${command}" "${plist_file}"
OUTPUT_VARIABLE plist_buddy_output
ERROR_VARIABLE plist_buddy_error)
string(STRIP "${plist_buddy_output}" plist_buddy_output)
if(arg_OUTPUT_VARIABLE)
list(APPEND ${arg_OUTPUT_VARIABLE} ${plist_buddy_output})
set(${arg_OUTPUT_VARIABLE} ${${arg_OUTPUT_VARIABLE}} PARENT_SCOPE)
endif()
if(arg_ERROR_VARIABLE)
list(APPEND ${arg_ERROR_VARIABLE} ${plist_buddy_error})
set(${arg_ERROR_VARIABLE} ${${arg_ERROR_VARIABLE}} PARENT_SCOPE)
endif()
if(plist_buddy_error)
return()
endif()
endforeach()
endfunction()
function(_qt_internal_set_apple_localizations target)
if(QT_NO_SET_PLIST_LOCALIZATIONS)
return()
endif()
get_target_property(supported_languages "${target}" _qt_apple_supported_languages)
if("${supported_languages}" STREQUAL "supported_languages-NOTFOUND")
return()
endif()
get_target_property(plist_file "${target}" MACOSX_BUNDLE_INFO_PLIST)
if (NOT plist_file)
return()
endif()
_qt_internal_plist_buddy("${plist_file}"
COMMANDS "print CFBundleLocalizations"
OUTPUT_VARIABLE existing_localizations
)
if(existing_localizations)
return()
endif()
list(TRANSFORM supported_languages PREPEND
"Add CFBundleLocalizations: string ")
_qt_internal_plist_buddy("${plist_file}"
COMMANDS
"Add CFBundleLocalizations array"
${supported_languages}
"Delete CFBundleAllowMixedLocalizations"
)
endfunction()
function(_qt_internal_set_ios_simulator_arch target)
if(CMAKE_XCODE_ATTRIBUTE_ARCHS
OR QT_NO_SET_XCODE_ARCHS)
@ -621,6 +675,9 @@ endfunction()
function(_qt_internal_finalize_apple_app target)
# Shared between macOS and iOS apps
_qt_internal_copy_info_plist("${target}")
_qt_internal_set_apple_localizations("${target}")
# Only set the various properties if targeting the Xcode generator, otherwise the various
# Xcode tokens are embedded as-is instead of being dynamically evaluated.
# This affects things like the version number or application name as reported by Qt API.
@ -637,12 +694,12 @@ function(_qt_internal_finalize_apple_app target)
endfunction()
function(_qt_internal_finalize_ios_app target)
_qt_internal_finalize_apple_app("${target}")
# Must be called before we generate the Info.plist
_qt_internal_handle_ios_launch_screen("${target}")
_qt_internal_finalize_apple_app("${target}")
_qt_internal_set_xcode_targeted_device_family("${target}")
_qt_internal_set_xcode_bitcode_enablement("${target}")
_qt_internal_handle_ios_launch_screen("${target}")
_qt_internal_generate_ios_info_plist("${target}")
_qt_internal_set_ios_simulator_arch("${target}")
endfunction()

View File

@ -53,7 +53,7 @@ endfunction()
function(__qt_internal_get_emcc_recommended_version out_var)
# This version of Qt needs this version of emscripten.
set(QT_EMCC_RECOMMENDED_VERSION "3.1.25")
set(QT_EMCC_RECOMMENDED_VERSION "3.1.37")
set(${out_var} "${QT_EMCC_RECOMMENDED_VERSION}" PARENT_SCOPE)
endfunction()
@ -81,12 +81,16 @@ function(__qt_internal_get_qt_build_emsdk_version out_var)
endif()
if(EXISTS "${WASM_BUILD_DIR}/src/corelib/global/qconfig.h")
file(READ "${WASM_BUILD_DIR}/src/corelib/global/qconfig.h" ver)
else()
elseif(EXISTS "${WASM_BUILD_DIR}/include/QtCore/qconfig.h")
file(READ "${WASM_BUILD_DIR}/include/QtCore/qconfig.h" ver)
else()
message("qconfig.h not found, unable to determine Qt build Emscripten version")
endif()
if (ver)
string(REGEX MATCH "#define QT_EMCC_VERSION.\"[0-9]+\\.[0-9]+\\.[0-9]+\"" emOutput ${ver})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" build_emcc_version "${emOutput}")
set(${out_var} "${build_emcc_version}" PARENT_SCOPE)
endif()
string(REGEX MATCH "#define QT_EMCC_VERSION.\"[0-9]+\\.[0-9]+\\.[0-9]+\"" emOutput ${ver})
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" build_emcc_version "${emOutput}")
set(${out_var} "${build_emcc_version}" PARENT_SCOPE)
endfunction()
function(_qt_test_emscripten_version)

View File

@ -37,8 +37,6 @@ function(qt_generate_qconfig_cpp in_file out_file)
set(QT_SYS_CONF_DIR "${INSTALL_SYSCONFDIR}")
# Compute and set relocation prefixes.
# TODO: Clean this up, there's a bunch of unrealistic assumptions here.
# See qtConfOutput_preparePaths in qtbase/configure.pri.
if(WIN32)
set(lib_location_absolute_path
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_BINDIR}")
@ -213,6 +211,7 @@ function(qt_get_qmake_module_name result module)
string(REGEX REPLACE "^Qt6" "" module "${module}")
string(REGEX REPLACE "Private$" "_private" module "${module}")
string(REGEX REPLACE "Qpa$" "_qpa_lib_private" module "${module}")
string(REGEX REPLACE "Rhi$" "_rhi_lib_private" module "${module}")
string(TOLOWER "${module}" module)
set(${result} ${module} PARENT_SCOPE)
endfunction()

View File

@ -3,10 +3,14 @@
function(qt_internal_add_resource target resourceName)
if(NOT TARGET "${target}")
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT in_batch)
message(FATAL_ERROR "Trying to add resource to a non-existing target \"${target}\".")
endif()
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()

View File

@ -3,23 +3,25 @@
## 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 BOOL
# Set the QT_BUILDING_QT variable so we can verify whether we are building
# Qt from source.
# Make sure not to set it when building a standalone test, otherwise
# upon reconfiguration we get an error about qt_internal_add_test
# not being found due the if(NOT QT_BUILDING_QT) check we have
# in each standalone test.
if(NOT QT_INTERNAL_IS_STANDALONE_TEST)
set(QT_BUILDING_QT TRUE CACHE BOOL
"When this is present and set to true, it signals that we are building Qt from source.")
# Pre-calculate the developer_build feature if it's set by the user via INPUT_developer_build
if(NOT FEATURE_developer_build AND INPUT_developer_build
AND NOT "${INPUT_developer_build}" STREQUAL "undefined")
set(FEATURE_developer_build ON)
endif()
# Pre-calculate the developer_build feature if it's set by the user via the INPUT_developer_build
# variable when using the configure script. When not using configure, don't take the INPUT variable
# into account, so that users can toggle the feature directly in the cache or via IDE.
qt_internal_compute_feature_value_from_possible_input(developer_build)
# Pre-calculate the no_prefix feature if it's set by configure via INPUT_no_prefix.
# This needs to be done before qtbase/configure.cmake is processed.
if(NOT FEATURE_no_prefix AND INPUT_no_prefix
AND NOT "${INPUT_no_prefix}" STREQUAL "undefined")
set(FEATURE_no_prefix ON)
endif()
qt_internal_compute_feature_value_from_possible_input(no_prefix)
set(_default_build_type "Release")
if(FEATURE_developer_build)
@ -49,7 +51,20 @@ unset(QT_EXTRA_BUILD_INTERNALS_VARS)
# Save the global property in a variable to make it available to feature conditions.
get_property(QT_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
# Try to detect if an explicit CMAKE_BUILD_TYPE was set by the user.
# CMake sets CMAKE_BUILD_TYPE_INIT to Debug on most Windows platforms and doesn't set
# anything for UNIXes. CMake assigns CMAKE_BUILD_TYPE_INIT to CMAKE_BUILD_TYPE during
# first project() if CMAKE_BUILD_TYPE has no previous value.
# We use extra information about the state of CMAKE_BUILD_TYPE before the first
# project() call that's set in QtAutodetect.
# STREQUAL check needs to have expanded variables because an undefined var is not equal
# to an empty defined var.
# See also qt_internal_force_set_cmake_build_type_conditionally which is used
# to set the build type when building other repos or tests.
if("${CMAKE_BUILD_TYPE}" STREQUAL "${CMAKE_BUILD_TYPE_INIT}"
AND NOT __qt_auto_detect_cmake_build_type_before_project_call
AND NOT __qt_build_internals_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
@ -193,6 +208,8 @@ else()
set(QT_INTERNAL_CONFIGURE_FROM_IDE FALSE CACHE INTERNAL "Configuring Qt Project from IDE")
endif()
set(_qt_sync_headers_at_configure_time_default ${QT_INTERNAL_CONFIGURE_FROM_IDE})
if(FEATURE_developer_build)
if(DEFINED QT_CMAKE_EXPORT_COMPILE_COMMANDS)
set(CMAKE_EXPORT_COMPILE_COMMANDS ${QT_CMAKE_EXPORT_COMPILE_COMMANDS})
@ -213,11 +230,26 @@ if(FEATURE_developer_build)
if (CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL Debug)
set(__build_benchmarks OFF)
endif()
# Sync headers during the initial configuration of a -developer-build to facilitate code
# navigation for code editors that use an LSP-based code model.
set(_qt_sync_headers_at_configure_time_default TRUE)
else()
set(_qt_build_tests_default OFF)
set(__build_benchmarks OFF)
endif()
# Sync Qt header files at configure time
option(QT_SYNC_HEADERS_AT_CONFIGURE_TIME "Run syncqt at configure time already"
${_qt_sync_headers_at_configure_time_default})
unset(_qt_sync_headers_at_configure_time_default)
# In static Ninja Multi-Config builds the sync_headers dependencies(and other autogen dependencies
# are not added to '_autogen/timestamp' targets. See QTBUG-113974.
if(CMAKE_GENERATOR STREQUAL "Ninja Multi-Config" AND NOT QT_BUILD_SHARED_LIBS)
set(QT_SYNC_HEADERS_AT_CONFIGURE_TIME TRUE CACHE BOOL "" FORCE)
endif()
# Build Benchmarks
option(QT_BUILD_BENCHMARKS "Build Qt Benchmarks" ${__build_benchmarks})
if(QT_BUILD_BENCHMARKS)
@ -255,10 +287,10 @@ endif()
option(QT_BUILD_TESTS_BATCHED "Link all tests into a single binary." ${_qt_batch_tests})
if(QT_BUILD_TESTS AND QT_BUILD_TESTS_BATCHED AND CMAKE_VERSION VERSION_LESS "3.18")
if(QT_BUILD_TESTS AND QT_BUILD_TESTS_BATCHED AND CMAKE_VERSION VERSION_LESS "3.19")
message(FATAL_ERROR
"Test batching requires at least CMake 3.18, due to requiring per-source "
"TARGET_DIRECTORY assignments.")
"Test batching requires at least CMake 3.19, due to requiring per-source "
"TARGET_DIRECTORY assignments and DEFER calls.")
endif()
# QT_BUILD_TOOLS_WHEN_CROSSCOMPILING -> QT_FORCE_BUILD_TOOLS
@ -285,6 +317,9 @@ enable_testing()
option(QT_BUILD_EXAMPLES "Build Qt examples" OFF)
option(QT_BUILD_EXAMPLES_BY_DEFAULT "Should examples be built as part of the default 'all' target." ON)
option(QT_INSTALL_EXAMPLES_SOURCES "Install example sources" OFF)
option(QT_INSTALL_EXAMPLES_SOURCES_BY_DEFAULT
"Install example sources as part of the default 'install' target" ON)
# FIXME: Support prefix builds as well QTBUG-96232
if(QT_WILL_INSTALL)
@ -354,31 +389,11 @@ endif()
option(QT_ALLOW_SYMLINK_IN_PATHS "Allows symlinks in paths." OFF)
# We need to clean up QT_FEATURE_*, but only once per configuration cycle
get_property(qt_feature_clean GLOBAL PROPERTY _qt_feature_clean)
if(NOT qt_feature_clean)
message(STATUS "Check for feature set changes")
set_property(GLOBAL PROPERTY _qt_feature_clean TRUE)
foreach(feature ${QT_KNOWN_FEATURES})
if(DEFINED "FEATURE_${feature}" AND
NOT "${QT_FEATURE_${feature}}" STREQUAL "${FEATURE_${feature}}")
message(" '${feature}' is changed from ${QT_FEATURE_${feature}} \
to ${FEATURE_${feature}}")
set(dirty_build TRUE)
endif()
unset("QT_FEATURE_${feature}" CACHE)
endforeach()
set(QT_KNOWN_FEATURES "" CACHE INTERNAL "" FORCE)
if(dirty_build)
set_property(GLOBAL PROPERTY _qt_dirty_build TRUE)
message(WARNING "Re-configuring in existing build folder. \
Some features will be re-evaluated automatically.")
endif()
endif()
qt_internal_detect_dirty_features()
if(NOT QT_BUILD_EXAMPLES)
# Disable deployment setup to avoid warnings about missing patchelf with CMake < 3.21.
set(QT_SKIP_SETUP_DEPLOYMENT ON)
endif()
option(QT_ALLOW_DOWNLOAD "Allows files to be downloaded when building Qt." OFF)

View File

@ -2,4 +2,4 @@
# bypassing the Qt6 Config file, aka find_package(Qt6SpecificFoo) repated x times. But it's not
# critical.
find_package(@INSTALL_CMAKE_NAMESPACE@ @main_qt_package_version@
REQUIRED COMPONENTS @QT_REPO_KNOWN_MODULES_STRING@)
COMPONENTS @QT_REPO_KNOWN_MODULES_STRING@)

View File

@ -61,13 +61,6 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
set(is_framework FALSE)
if(NOT is_interface_lib)
get_target_property(is_framework ${target} FRAMEWORK)
if(is_framework)
qt_internal_get_framework_info(fw ${target})
get_target_property(fw_output_base_dir ${target} LIBRARY_OUTPUT_DIRECTORY)
set(framework_args "-framework"
"-frameworkIncludeDir" "${fw_output_base_dir}/${fw_versioned_header_dir}"
)
endif()
endif()
qt_internal_get_qt_all_known_modules(known_modules)
@ -79,6 +72,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
endif()
get_target_property(qpa_filter_regex ${target} _qt_module_qpa_headers_filter_regex)
get_target_property(rhi_filter_regex ${target} _qt_module_rhi_headers_filter_regex)
get_target_property(private_filter_regex ${target} _qt_module_private_headers_filter_regex)
# We need to use the real paths since otherwise it may lead to the invalid work of the
@ -96,6 +90,12 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
)
endif()
if(rhi_filter_regex)
set(rhi_filter_argument
-rhiHeadersFilter "${rhi_filter_regex}"
)
endif()
set(common_syncqt_arguments
-module "${module}"
-sourceDir "${source_dir_real}"
@ -104,8 +104,10 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
-includeDir "${module_build_interface_include_dir}"
-privateIncludeDir "${module_build_interface_private_include_dir}"
-qpaIncludeDir "${module_build_interface_qpa_include_dir}"
-rhiIncludeDir "${module_build_interface_rhi_include_dir}"
-generatedHeaders ${module_headers_generated}
${qpa_filter_argument}
${rhi_filter_argument}
${public_namespaces_filter}
${non_qt_module_argument}
${internal_module_argument}
@ -142,7 +144,6 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
-headers ${module_headers}
-stagingDir "${syncqt_staging_dir}"
-knownModules ${known_modules}
${framework_args}
${version_script_args}
)
list(JOIN syncqt_args "\n" syncqt_args_string)
@ -178,6 +179,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
${syncqt_args_rsp}
${module_headers}
${QT_CMAKE_EXPORT_NAMESPACE}::syncqt
"$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_internal_sync_headers_deps>>"
COMMENT
"Running syncqt.cpp for module: ${module}"
VERBATIM
@ -194,6 +196,8 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
${syncqt_outputs}
)
add_dependencies(sync_headers ${target}_sync_headers)
set_target_properties(${target}
PROPERTIES _qt_internal_sync_headers_target ${target}_sync_headers)
if(is_3rd_party_library)
add_dependencies(thirdparty_sync_headers ${target}_sync_headers)
@ -224,7 +228,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
endif()
add_dependencies(sync_all_public_headers ${target}_sync_all_public_headers)
if(NOT is_3rd_party_library AND NOT is_framework)
if(NOT is_3rd_party_library AND NOT is_framework AND module_headers)
# Install all the CaMeL style aliases of header files from the staging directory in one rule
qt_install(DIRECTORY "${syncqt_staging_dir}/"
DESTINATION "${module_install_interface_include_dir}"
@ -246,7 +250,7 @@ function(qt_internal_target_sync_headers target module_headers module_headers_ge
# Run sync Qt first time at configure step to make all header files available for the code model
# of IDEs.
get_property(synced_modules GLOBAL PROPERTY _qt_synced_modules)
if(NOT "${module}" IN_LIST synced_modules)
if(NOT "${module}" IN_LIST synced_modules AND QT_SYNC_HEADERS_AT_CONFIGURE_TIME)
message(STATUS "Running syncqt.cpp for module: ${module}")
get_target_property(syncqt_location ${QT_CMAKE_EXPORT_NAMESPACE}::syncqt LOCATION)
execute_process(

View File

@ -16,14 +16,20 @@
# Custom compilation flags.
# EXTRA_LINKER_SCRIPT_CONTENT
# Extra content that should be appended to a target linker script. Applicable for ld only.
# EXTRA_LINKER_SCRIPT_EXPORTS
# Extra content that should be added to export section of the linker script.
# NO_PCH_SOURCES
# Skip the specified source files by PRECOMPILE_HEADERS feature.
function(qt_internal_extend_target target)
if(NOT TARGET "${target}")
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT in_batch)
message(FATAL_ERROR "Trying to extend a non-existing target \"${target}\".")
endif()
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()
@ -47,6 +53,7 @@ function(qt_internal_extend_target target)
CONDITION
CONDITION_INDEPENDENT_SOURCES
COMPILE_FLAGS
EXTRA_LINKER_SCRIPT_EXPORTS
)
cmake_parse_arguments(PARSE_ARGV 1 arg
@ -109,6 +116,19 @@ function(qt_internal_extend_target target)
if(NOT base_lib STREQUAL lib)
qt_create_nolink_target("${base_lib}" ${target})
endif()
# Collect _sync_headers targets from libraries that the target depends on. This is
# heuristic way of building the dependency tree between the _sync_headers targets of
# different Qt modules.
if(TARGET "${lib}")
get_target_property(is_private ${lib} _qt_is_private_module)
if(is_private)
get_target_property(lib ${lib} _qt_public_module_target_name)
endif()
set(out_genex "$<TARGET_PROPERTY:${lib},_qt_internal_sync_headers_target>")
set_property(TARGET ${target}
APPEND PROPERTY _qt_internal_sync_headers_deps "${out_genex}")
endif()
endforeach()
# Set-up the target
@ -243,6 +263,10 @@ function(qt_internal_extend_target target)
set_target_properties(${target} PROPERTIES
_qt_extra_linker_script_content "${arg_EXTRA_LINKER_SCRIPT_CONTENT}")
endif()
if(arg_EXTRA_LINKER_SCRIPT_EXPORTS)
set_target_properties(${target} PROPERTIES
_qt_extra_linker_script_exports "${arg_EXTRA_LINKER_SCRIPT_EXPORTS}")
endif()
endfunction()
function(qt_is_imported_target target out_var)
@ -1018,6 +1042,24 @@ function(qt_internal_mark_as_internal_target target)
set_target_properties(${target} PROPERTIES _qt_is_internal_target TRUE)
endfunction()
# Marks a target with a property to skip it adding it as a dependency when building examples as
# ExternalProjects.
# Needed to create a ${repo}_src global target that examples can depend on in multi-config builds
# due to a bug in AUTOUIC.
#
# See QTBUG-110369.
function(qt_internal_skip_dependency_for_examples target)
set_target_properties(${target} PROPERTIES _qt_skip_dependency_for_examples TRUE)
endfunction()
function(qt_internal_is_target_skipped_for_examples target out_var)
get_property(is_skipped TARGET ${target} PROPERTY _qt_skip_dependency_for_examples)
if(NOT is_skipped)
set(is_skipped FALSE)
endif()
set(${out_var} "${is_skipped}" PARENT_SCOPE)
endfunction()
function(qt_internal_link_internal_platform_for_object_library target)
# We need to apply iOS bitcode flags to object libraries that are associated with internal
# modules or plugins (e.g. object libraries added by qt_internal_add_resource,
@ -1080,11 +1122,15 @@ endfunction()
# The function disables one or multiple internal global definitions that are defined by the
# qt_internal_add_global_definition function for a specific 'target'.
function(qt_internal_undefine_global_definition target)
if(NOT TARGET ${target})
qt_internal_is_in_test_batch(in_batch ${target})
if(NOT ${in_batch})
message(FATAL_ERROR "${target} is not a target.")
endif()
if(NOT TARGET "${target}")
message(FATAL_ERROR "${target} is not a target.")
endif()
qt_internal_is_skipped_test(skipped ${target})
if(skipped)
return()
endif()
qt_internal_is_in_test_batch(in_batch ${target})
if(in_batch)
_qt_internal_test_batch_target_name(target)
endif()
@ -1135,3 +1181,157 @@ function(qt_internal_get_target_sources_property out_var)
endif()
set(${out_var} "${${out_var}}" PARENT_SCOPE)
endfunction()
# This function collects target properties that contain generator expressions and needs to be
# exported. This function is needed since the CMake EXPORT_PROPERTIES property doesn't support
# properties that contain generator expressions.
# Usage: qt_internal_add_genex_properties_export(target properties...)
function(qt_internal_add_genex_properties_export target)
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
set(config_check_begin "")
set(config_check_end "")
if(is_multi_config)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
# The genex snippet is evaluated to '$<NOT:$<BOOL:$<CONFIG>>>' in the generated cmake file.
# The check is only applicable to the 'main' configuration. If user project doesn't use
# multi-config generator, then the check supposed to return true and the value from the
# 'main' configuration supposed to be used.
string(JOIN "" check_if_config_empty
"$<1:$><NOT:"
"$<1:$><BOOL:"
"$<1:$><CONFIG$<ANGLE-R>"
"$<ANGLE-R>"
"$<ANGLE-R>"
)
# The genex snippet is evaluated to '$<CONFIG:'Qt config type'>' in the generated cmake
# file and checks if the config that user uses matches the generated cmake file config.
string(JOIN "" check_user_config
"$<1:$><CONFIG:$<CONFIG>$<ANGLE-R>"
)
# The genex snippet is evaluated to '$<$<OR:$<CONFIG:'Qt config type'>>:'Property content'>
# for non-main Qt configs and to
# $<$<OR:$<CONFIG:'Qt config type'>,$<NOT:$<BOOL:$<CONFIG>>>>:'Property content'> for the
# main Qt config. This guard is required to choose the correct value of the property for the
# user project according to the user config type.
# All genexes need to be escaped properly to protect them from evaluation by the
# file(GENERATE call in the qt_internal_export_genex_properties function.
string(JOIN "" config_check_begin
"$<1:$><"
"$<1:$><OR:"
"${check_user_config}"
"$<$<CONFIG:${first_config_type}>:$<COMMA>${check_if_config_empty}>"
"$<ANGLE-R>:"
)
set(config_check_end "$<ANGLE-R>")
endif()
set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
foreach(property IN LISTS ARGN)
set(target_property_genex "$<TARGET_PROPERTY:${target_name},${property}>")
# All properties that contain lists need to be protected of processing by JOIN genex calls.
# So this escapes the semicolons for these list.
set(target_property_list_escape
"$<JOIN:$<GENEX_EVAL:${target_property_genex}>,\;>")
set(property_value
"\"${config_check_begin}${target_property_list_escape}${config_check_end}\"")
set_property(TARGET ${target} APPEND PROPERTY _qt_export_genex_properties_content
"${property} ${property_value}")
endforeach()
endfunction()
# This function executes generator expressions for the properties that are added by the
# qt_internal_add_genex_properties_export function and sets the calculated values to the
# corresponding properties in the generated ExtraProperties.cmake file. The file then needs to be
# included after the target creation routines in Config.cmake files. It also supports Multi-Config
# builds.
# Arguments:
# EXPORT_NAME_PREFIX:
# The portion of the file name before ExtraProperties.cmake
# CONFIG_INSTALL_DIR:
# Installation location for the file.
# TARGETS:
# The internal target names.
function(qt_internal_export_genex_properties)
set(option_args "")
set(single_args
EXPORT_NAME_PREFIX
CONFIG_INSTALL_DIR
)
set(multi_args TARGETS)
cmake_parse_arguments(arg "${option_args}" "${single_args}" "${multi_args}" ${ARGN})
if(NOT arg_EXPORT_NAME_PREFIX)
message(FATAL_ERROR "qt_internal_export_genex_properties: "
"Missing EXPORT_NAME_PREFIX argument.")
endif()
if(NOT arg_TARGETS)
message(FATAL_ERROR "qt_internal_export_genex_properties: "
"TARGETS argument must contain at least one target")
endif()
foreach(target IN LISTS arg_TARGETS)
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
set(output_file_base_name "${arg_EXPORT_NAME_PREFIX}ExtraProperties")
set(should_append "")
set(config_suffix "")
if(is_multi_config)
list(GET CMAKE_CONFIGURATION_TYPES 0 first_config_type)
set(config_suffix "$<$<NOT:$<CONFIG:${first_config_type}>>:-$<CONFIG>>")
# If the generated file belongs to the 'main' config type, we should set property
# but not append it.
string(JOIN "" should_append
"$<$<NOT:$<CONFIG:${first_config_type}>>: APPEND>")
endif()
set(file_name "${output_file_base_name}${config_suffix}.cmake")
qt_path_join(output_file "${arg_CONFIG_INSTALL_DIR}"
"${file_name}")
if(NOT IS_ABSOLUTE "${output_file}")
qt_path_join(output_file "${QT_BUILD_DIR}" "${output_file}")
endif()
set(target_name "${QT_CMAKE_EXPORT_NAMESPACE}::${target}")
string(JOIN "" set_property_begin "set_property(TARGET "
"${target_name}${should_append} PROPERTY "
)
set(set_property_end ")")
set(set_property_glue "${set_property_end}\n${set_property_begin}")
set(property_list
"$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_export_genex_properties_content>>")
string(JOIN "" set_property_content "${set_property_begin}"
"$<JOIN:${property_list},${set_property_glue}>"
"${set_property_end}")
if(is_multi_config)
set(config_includes "")
foreach(config IN LISTS CMAKE_CONFIGURATION_TYPES)
if(NOT first_config_type STREQUAL config)
set(include_file_name
"${output_file_base_name}-${config}.cmake")
list(APPEND config_includes
"include(\"\${CMAKE_CURRENT_LIST_DIR}/${include_file_name}\")")
endif()
endforeach()
list(JOIN config_includes "\n" config_includes_string)
set(config_includes_string
"\n$<$<CONFIG:${first_config_type}>:${config_includes_string}>")
endif()
file(GENERATE OUTPUT "${output_file}"
CONTENT "$<$<BOOL:${property_list}>:${set_property_content}${config_includes_string}>"
CONDITION "$<BOOL:${property_list}>"
)
endforeach()
qt_install(FILES "$<$<BOOL:${property_list}>:${output_file}>"
DESTINATION "${arg_CONFIG_INSTALL_DIR}"
COMPONENT Devel
)
endfunction()

View File

@ -247,6 +247,7 @@ function(qt_internal_add_test_to_batch batch_name name)
# Lazy-init the test batch
if(NOT TARGET ${target})
qt_internal_library_deprecation_level(deprecation_define)
qt_internal_add_executable(${target}
${exceptions_text}
${gui_text}
@ -254,11 +255,16 @@ function(qt_internal_add_test_to_batch batch_name name)
NO_INSTALL
OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build_dir"
SOURCES "${QT_CMAKE_DIR}/qbatchedtestrunner.in.cpp"
DEFINES QTEST_BATCH_TESTS
DEFINES QTEST_BATCH_TESTS ${deprecation_define}
INCLUDE_DIRECTORIES ${private_includes}
LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Core
${QT_CMAKE_EXPORT_NAMESPACE}::Test
${QT_CMAKE_EXPORT_NAMESPACE}::TestPrivate
# Add GUI by default so that the plugins link properly with non-standalone
# build of tests. Plugin handling is currently only done in
# qt_internal_add_executable if Gui is present. This should be reevaluated with
# multiple batches.
${QT_CMAKE_EXPORT_NAMESPACE}::Gui
)
set_property(TARGET ${target} PROPERTY _qt_has_exceptions ${arg_EXCEPTIONS})
@ -309,17 +315,12 @@ function(qt_internal_add_test_to_batch batch_name name)
list(PREPEND batched_test_list ${name})
set_property(GLOBAL PROPERTY _qt_batched_test_list_property ${batched_test_list})
qt_internal_library_deprecation_level(deprecation_define)
# Merge the current test with the rest of the batch
qt_internal_extend_target(${target}
INCLUDE_DIRECTORIES ${arg_INCLUDE_DIRECTORIES}
PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES}
LIBRARIES ${arg_LIBRARIES}
SOURCES ${arg_SOURCES}
DEFINES
${arg_DEFINES}
${deprecation_define}
COMPILE_OPTIONS ${arg_COMPILE_OPTIONS}
COMPILE_FLAGS ${arg_COMPILE_FLAGS}
LINK_OPTIONS ${arg_LINK_OPTIONS}
@ -336,7 +337,7 @@ function(qt_internal_add_test_to_batch batch_name name)
set_source_files_properties(${source}
TARGET_DIRECTORY ${target}
PROPERTIES COMPILE_DEFINITIONS
"BATCHED_TEST_NAME=\"${name}\"")
"BATCHED_TEST_NAME=\"${name}\";${arg_DEFINES}" )
endforeach()
set(${batch_name} ${target} PARENT_SCOPE)
@ -363,6 +364,34 @@ function(qt_internal_is_in_test_batch out name)
endif()
endfunction()
function(qt_internal_is_skipped_test out name)
get_target_property(is_skipped_test ${name} _qt_is_skipped_test)
set(${out} ${is_skipped_test} PARENT_SCOPE)
endfunction()
function(qt_internal_set_skipped_test name)
set_target_properties(${name} PROPERTIES _qt_is_skipped_test TRUE)
endfunction()
function(qt_internal_is_qtbase_test out)
get_filename_component(dir "${CMAKE_CURRENT_BINARY_DIR}" ABSOLUTE)
set(${out} FALSE PARENT_SCOPE)
while(TRUE)
get_filename_component(filename "${dir}" NAME)
if("${filename}" STREQUAL "qtbase")
set(${out} TRUE PARENT_SCOPE)
break()
endif()
set(prev_dir "${dir}")
get_filename_component(dir "${dir}" DIRECTORY)
if("${dir}" STREQUAL "${prev_dir}")
break()
endif()
endwhile()
endfunction()
function(qt_internal_get_batched_test_arguments out testname)
if(WASM)
# Add a query string to the runner document, so that the script therein
@ -403,6 +432,32 @@ function(qt_internal_add_test name)
_qt_internal_validate_all_args_are_parsed(arg)
_qt_internal_validate_no_unity_build(arg)
set(batch_current_test FALSE)
if(QT_BUILD_TESTS_BATCHED AND NOT arg_NO_BATCH AND NOT arg_QMLTEST AND NOT arg_MANUAL
AND ("${QT_STANDALONE_TEST_PATH}" STREQUAL ""
OR DEFINED ENV{QT_BATCH_STANDALONE_TESTS}))
set(batch_current_test TRUE)
endif()
if(batch_current_test OR (QT_BUILD_TESTS_BATCHED AND arg_QMLTEST))
if (QT_SUPERBUILD OR DEFINED ENV{TESTED_MODULE_COIN})
set(is_qtbase_test FALSE)
if(QT_SUPERBUILD)
qt_internal_is_qtbase_test(is_qtbase_test)
elseif($ENV{TESTED_MODULE_COIN} STREQUAL "qtbase")
set(is_qtbase_test TRUE)
endif()
if(NOT is_qtbase_test)
file(GENERATE OUTPUT "dummy${name}.cpp" CONTENT "int main() { return 0; }")
# Add a dummy target to tackle some potential problems
qt_internal_add_executable(${name} SOURCES "dummy${name}.cpp")
# Batched tests outside of qtbase are unsupported and skipped
qt_internal_set_skipped_test(${name})
return()
endif()
endif()
endif()
if (NOT arg_OUTPUT_DIRECTORY)
set(arg_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
@ -421,9 +476,8 @@ function(qt_internal_add_test name)
"removed in a future Qt version. Use the LIBRARIES option instead.")
endif()
if(NOT arg_NO_BATCH AND QT_BUILD_TESTS_BATCHED AND NOT arg_QMLTEST AND NOT arg_MANUAL)
if(batch_current_test)
qt_internal_add_test_to_batch(name ${name} ${ARGN})
set(setting_up_batched_test TRUE)
elseif(arg_SOURCES)
if(QT_BUILD_TESTS_BATCHED AND arg_QMLTEST)
message(WARNING "QML tests won't be batched - unsupported (yet)")
@ -499,7 +553,6 @@ function(qt_internal_add_test name)
qt_internal_extend_target("${name}" CONDITION ANDROID
LIBRARIES ${QT_CMAKE_EXPORT_NAMESPACE}::Gui
)
set(setting_up_batched_test FALSE)
set_target_properties(${name} PROPERTIES _qt_is_test_executable TRUE)
set_target_properties(${name} PROPERTIES _qt_is_manual_test ${arg_MANUAL})
endif()
@ -550,7 +603,7 @@ function(qt_internal_add_test name)
elseif(WASM)
# The test script expects an html file. In case of batched tests, the
# version specialized for running batches has to be supplied.
if(setting_up_batched_test)
if(batch_current_test)
get_target_property(batch_output_dir ${name} RUNTIME_OUTPUT_DIRECTORY)
set(test_executable "${batch_output_dir}/${name}.html")
else()
@ -562,11 +615,16 @@ function(qt_internal_add_test name)
list(APPEND extra_test_args "--silence_timeout=60")
# TODO: Add functionality to specify browser
list(APPEND extra_test_args "--browser=chrome")
list(APPEND extra_test_args "--browser_args=\"--password-store=basic\"")
list(APPEND extra_test_args "--kill_exit")
# We always want to enable asyncify for tests, as some of them use exec
# Tests may require asyncify if they use exec(). Enable asyncify for
# batched tests since this is the configuration used on the CI system.
# Optimize for size (-Os), since asyncify tends to make the resulting
# binary very large
target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
if(batch_current_test)
target_link_options("${name}" PRIVATE "SHELL:-s ASYNCIFY" "-Os")
endif()
# This tells cmake to run the tests with this script, since wasm files can't be
# executed directly
@ -588,9 +646,11 @@ function(qt_internal_add_test name)
endif()
if(NOT arg_MANUAL)
if(setting_up_batched_test)
if(batch_current_test)
qt_internal_get_batched_test_arguments(batched_test_args ${testname})
list(PREPEND extra_test_args ${batched_test_args})
elseif(WASM AND CMAKE_BUILD_TYPE STREQUAL "Debug")
list(PREPEND extra_test_args "qvisualoutput")
endif()
qt_internal_collect_command_environment(test_env_path test_env_plugin_path)
@ -661,10 +721,29 @@ function(qt_internal_add_test name)
foreach(testdata IN LISTS arg_TESTDATA)
list(APPEND builtin_files ${testdata})
endforeach()
foreach(file IN LISTS builtin_files)
set_source_files_properties(${file}
PROPERTIES QT_SKIP_QUICKCOMPILER TRUE
)
endforeach()
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
list(APPEND builtin_files ${blacklist_path})
if(batch_current_test)
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
get_target_property(blacklist_files ${name} _qt_blacklist_files)
if(NOT blacklist_files)
set_target_properties(${name} PROPERTIES _qt_blacklist_files "")
set(blacklist_files "")
cmake_language(EVAL CODE "cmake_language(DEFER DIRECTORY \"${CMAKE_SOURCE_DIR}\" CALL \"_qt_internal_finalize_batch\" \"${name}\") ")
endif()
list(PREPEND blacklist_files "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
set_target_properties(${name} PROPERTIES _qt_blacklist_files "${blacklist_files}")
endif()
else()
set(blacklist_path "BLACKLIST")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${blacklist_path}")
list(APPEND builtin_files ${blacklist_path})
endif()
endif()
list(REMOVE_DUPLICATES builtin_files)
@ -762,7 +841,8 @@ for this function. Will be ignored")
endif()
set(executable_name ${arg_NAME})
if(QT_BUILD_TESTS_BATCHED)
qt_internal_is_in_test_batch(is_in_batch ${executable_name})
if(is_in_batch)
_qt_internal_test_batch_target_name(executable_name)
endif()
add_test(NAME "${arg_NAME}" COMMAND "${CMAKE_COMMAND}" "-P" "${arg_OUTPUT_FILE}"
@ -828,8 +908,8 @@ function(qt_internal_add_test_helper name)
set(extra_args_to_pass)
if(NOT arg_OVERRIDE_OUTPUT_DIRECTORY)
if(QT_BUILD_TESTS_BATCHED)
_qt_internal_test_batch_target_name(test_batch_target_name)
_qt_internal_test_batch_target_name(test_batch_target_name)
if(QT_BUILD_TESTS_BATCHED AND TARGET ${test_batch_target_name})
get_target_property(
test_batch_output_dir ${test_batch_target_name} RUNTIME_OUTPUT_DIRECTORY)
set(extra_args_to_pass OUTPUT_DIRECTORY "${test_batch_output_dir}")

View File

@ -131,10 +131,12 @@ set(__qt_chainload_toolchain_file \"\${__qt_initially_configured_toolchain_file}
list(APPEND init_platform "
set(__qt_initial_c_compiler \"${CMAKE_C_COMPILER}\")
set(__qt_initial_cxx_compiler \"${CMAKE_CXX_COMPILER}\")
if(NOT DEFINED CMAKE_C_COMPILER AND EXISTS \"\${__qt_initial_c_compiler}\")
if(QT_USE_ORIGINAL_COMPILER AND NOT DEFINED CMAKE_C_COMPILER
AND EXISTS \"\${__qt_initial_c_compiler}\")
set(CMAKE_C_COMPILER \"\${__qt_initial_c_compiler}\" CACHE STRING \"\")
endif()
if(NOT DEFINED CMAKE_CXX_COMPILER AND EXISTS \"\${__qt_initial_cxx_compiler}\")
if(QT_USE_ORIGINAL_COMPILER AND NOT DEFINED CMAKE_CXX_COMPILER
AND EXISTS \"\${__qt_initial_cxx_compiler}\")
set(CMAKE_CXX_COMPILER \"\${__qt_initial_cxx_compiler}\" CACHE STRING \"\")
endif()")
endif()

View File

@ -8,7 +8,8 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
target_link_options("${wasmTarget}" INTERFACE
"SHELL:-s MAX_WEBGL_VERSION=2"
"SHELL:-s FETCH=1"
"SHELL:-s WASM_BIGINT=1")
"SHELL:-s WASM_BIGINT=1"
"SHELL:-s STACK_SIZE=5MB")
target_link_libraries("${wasmTarget}" INTERFACE embind)
@ -93,17 +94,25 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
# plugins are SIDE_MODULE
target_compile_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:" -s SIDE_MODULE=1>)
target_link_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,MODULE_LIBRARY>:" -s SIDE_MODULE=1>)
set(side_modules
MODULE_LIBRARY SHARED_LIBRARY)
set(enable_side_module_if_needed
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,${side_modules}>:SHELL:-s SIDE_MODULE=1>")
set(enable_main_module_if_needed
"$<$<IN_LIST:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:-s MAIN_MODULE=1>")
set(set_shared_module_type_if_needed
"${enable_side_module_if_needed}"
"${enable_main_module_if_needed}"
)
# shared libs are SIDE_MODULE
target_compile_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:" -s SIDE_MODULE=1>)
# Add Qt libdir to linker library paths
set(qt_lib_location
"${QT_BUILD_INTERNALS_RELOCATABLE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
target_link_options("${wasmTarget}" INTERFACE
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:" -s SIDE_MODULE=1>)
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:SHELL:" -L${qt_lib_location}/>)
target_compile_options("${wasmTarget}" INTERFACE "${set_shared_module_type_if_needed}")
target_link_options("${wasmTarget}" INTERFACE "${set_shared_module_type_if_needed}")
else()
target_link_options("${wasmTarget}" INTERFACE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=1")

View File

@ -39,15 +39,30 @@ function(qt_internal_create_wrapper_scripts)
DESTINATION "${INSTALL_BINDIR}")
endif()
# Provide a private convenience wrapper with options which should not be propagated via the
if(generate_unix)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create" @ONLY
NEWLINE_STYLE LF)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create"
DESTINATION "${INSTALL_BINDIR}")
endif()
if(generate_non_unix)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake-create.bat.in"
"${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.bat" @ONLY
NEWLINE_STYLE CRLF)
qt_install(PROGRAMS "${QT_BUILD_DIR}/${INSTALL_BINDIR}/qt-cmake-create.bat"
DESTINATION "${INSTALL_BINDIR}")
endif()
# Provide a private convenience wrapper with options that 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}\"")
# Ninja generator. In a similar vein, we do want to use the same compiler for all Qt modules,
# but not for user applications.
# The private wrapper is more convenient 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}\" -DQT_USE_ORIGINAL_COMPILER=ON")
if(generate_unix)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/qt-cmake.in"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/qt-cmake-private" @ONLY
@ -188,6 +203,22 @@ function(qt_internal_create_wrapper_scripts)
elseif(CMAKE_BUILD_TYPE)
set(__qt_configured_configs "${CMAKE_BUILD_TYPE}")
endif()
if(
# Skip stripping pure debug builds so it's easier to debug issues in CI VMs.
(NOT QT_FEATURE_debug_and_release
AND QT_FEATURE_debug
AND NOT QT_FEATURE_separate_debug_info)
# Skip stripping on MSVC because ${CMAKE_STRIP} might contain a MinGW strip binary
# and the breaks the linker version flag embedded in the binary and causes Qt Creator
# to mis-identify the Kit ABI.
OR MSVC
)
set(__qt_skip_strip_installed_artifacts TRUE)
else()
set(__qt_skip_strip_installed_artifacts FALSE)
endif()
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/bin/${__qt_cmake_install_script_name}.in"
"${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${__qt_cmake_install_script_name}" @ONLY)
qt_install(FILES "${QT_BUILD_DIR}/${INSTALL_LIBEXECDIR}/${__qt_cmake_install_script_name}"
@ -195,6 +226,7 @@ function(qt_internal_create_wrapper_scripts)
qt_internal_create_qt_configure_tests_wrapper_script()
qt_internal_install_android_helper_scripts()
qt_internal_create_qt_configure_redo_script()
endfunction()
function(qt_internal_create_qt_configure_tests_wrapper_script)
@ -217,7 +249,7 @@ function(qt_internal_create_qt_configure_tests_wrapper_script)
# The script takes a path to the repo for which the standalone tests will be configured.
set(script_name "qt-internal-configure-tests")
set(script_passed_args "-DQT_BUILD_STANDALONE_TESTS=ON")
set(script_passed_args "-DQT_BUILD_STANDALONE_TESTS=ON -DQT_USE_ORIGINAL_COMPILER=ON")
file(RELATIVE_PATH relative_path_from_libexec_dir_to_bin_dir
${__qt_libexec_dir_absolute}
@ -248,3 +280,41 @@ function(qt_internal_install_android_helper_scripts)
qt_copy_or_install(PROGRAMS "${CMAKE_CURRENT_SOURCE_DIR}/util/android/android_emulator_launcher.sh"
DESTINATION "${destination}")
endfunction()
# Create a shell wrapper script to reconfigure Qt with the original configure arguments and
# any additional ones passed.
#
# Removes CMakeCache.txt and friends, either manually, or using CMake's --fresh.
#
# The script is created in the root of the build dir and is called config.redo
# It has the same contents as the 'config.status' script we created in qt 5.
function(qt_internal_create_qt_configure_redo_script)
set(input_script_name "qt-internal-config.redo")
set(input_script_path "${CMAKE_CURRENT_SOURCE_DIR}/libexec/${input_script_name}")
# We don't use QT_BUILD_DIR because we want the file in the root of the build dir in a top-level
# build.
set(output_script_name "config.redo")
set(output_path "${CMAKE_BINARY_DIR}/${output_script_name}")
if(QT_SUPERBUILD)
set(configure_script_path "${Qt_SOURCE_DIR}")
else()
set(configure_script_path "${QtBase_SOURCE_DIR}")
endif()
string(APPEND configure_script_path "/configure")
# Used in the file contents.
file(TO_NATIVE_PATH "${configure_script_path}" configure_path)
if(CMAKE_HOST_UNIX)
string(APPEND input_script_path ".in")
set(newline_style "LF")
else()
string(APPEND input_script_path ".bat.in")
string(APPEND output_path ".bat")
set(newline_style "CRLF")
endif()
configure_file("${input_script_path}" "${output_path}" @ONLY NEWLINE_STYLE ${newline_style})
endfunction()

View File

@ -313,3 +313,16 @@ $ cd some/empty/directory
$ ~/Qt/6.0.0/bin/qt-cmake-standalone-test ~/source/of/qtbase/test/auto/corelib/io/qprocess
$ cmake --build .
```
## qt-cmake-create
Generates a simple CMakeLists.txt based on source files in specified project directory.
Example:
```
$ cd some/source/directory/
$ qt-cmake-create
$ qt-cmake -S . -B /build/directory
$ cmake --build /build/directory
```

View File

@ -17,7 +17,6 @@ The following table describes the mapping of configure options to CMake argument
| -no-feature-foo | -DFEATURE_foo=OFF | |
| -list-features | | At the moment: configure with cmake once, |
| | | then use ccmake or cmake-gui to inspect the features. |
| -list-libraries | | |
| -opensource | n/a | |
| -commercial | n/a | |
| -confirm-license | n/a | |
@ -60,6 +59,7 @@ The following table describes the mapping of configure options to CMake argument
| -R <string> | -DQT_EXTRA_RPATHS=path1;path2 | |
| -rpath | negative CMAKE_SKIP_BUILD_RPATH | |
| | negative CMAKE_SKIP_INSTALL_RPATH | |
| | negative CMAKE_MACOSX_RPATH | |
| -reduce-exports | -DFEATURE_reduce_exports=ON | |
| -reduce-relocations | -DFEATURE_reduce_relocations=ON | |
| -plugin-manifests | | |
@ -75,16 +75,9 @@ The following table describes the mapping of configure options to CMake argument
| -ccache | -DQT_USE_CCACHE=ON | |
| -unity-build | -DQT_UNITY_BUILD=ON | |
| -unity-build-batch-size <int> | -DQT_UNITY_BUILD_BATCH_SIZE=<int> | |
| -make-tool <tool> | n/a | |
| -mp | n/a | |
| -warnings-are-errors | -DWARNINGS_ARE_ERRORS=ON | |
| -silent | n/a | |
| -sysroot <dir> | -DCMAKE_SYSROOT=<dir> | Should be provided by a toolchain file that's |
| | | passed via -DCMAKE_TOOLCHAIN_FILE=<filename> |
| -no-gcc-sysroot | n/a | The corresponding CMake variables are CMAKE_SYSROOT_LINK |
| | | and CMAKE_SYSROOT_COMPILE. |
| | | They are usually set in a toolchain file. |
| -no-pkg-config | -DFEATURE_pkg_config=OFF | |
| -no-vcpkg | -DQT_USE_VCPKG=OFF | |
| -D <string> | -DQT_EXTRA_DEFINES=<string1>;<string2> | |
| -I <string> | -DQT_EXTRA_INCLUDEPATHS=<string1>;<string2> | |
| -L <string> | -DQT_EXTRA_LIBDIRS=<string1>;<string2> | |
@ -110,6 +103,7 @@ The following table describes the mapping of configure options to CMake argument
| | | build them separately, after configuration. |
| -nomake <part> | -DQT_BUILD_TESTS=OFF | A way to turn off tools explicitly is missing. |
| | -DQT_BUILD_EXAMPLES=OFF | |
| -install-examples-sources | -DQT_INSTALL_EXAMPLES_SOURCES=ON | |
| -no-gui | -DFEATURE_gui=OFF | |
| -no-widgets | -DFEATURE_widgets=OFF | |
| -no-dbus | -DFEATURE_dbus=OFF | |

View File

@ -1,11 +1,13 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <QtCore/qglobal.h>
#ifndef @header_base_name_upper@_H
#define @header_base_name_upper@_H
#include <QtCore/qcompilerdetection.h>
#include <QtCore/qtconfigmacros.h> // Q_@module_define_infix@_EXPORT
#include <QtCore/qtdeprecationmarkers.h> // QT_IF_DEPRECATED_SINCE
#if defined(QT_SHARED) || !defined(QT_STATIC)
# if defined(QT_BUILD_@module_define_infix@_LIB)
# define Q_@module_define_infix@_EXPORT Q_DECL_EXPORT

View File

@ -4,6 +4,8 @@
#ifndef @header_base_name_upper@_P_H
#define @header_base_name_upper@_P_H
// This file is autogenerated. Changes will be overwritten.
//
// W A R N I N G
// -------------

View File

@ -0,0 +1,65 @@
{
"Project": {
"Git": {
"_active": true,
"sourceserver_gitdir": "/data/axivion/databases/$(env:TESTED_MODULE_COIN).git"
},
"BuildSystemIntegration": {
"child_order": [
"GCCSetup",
"CMake",
"LinkLibraries"
]
},
"CMake": {
"_active": true,
"_copy_from": "CMakeIntegration",
"build_environment": {},
"build_options": "-j4",
"generate_options": "--fresh",
"generator": "Ninja"
},
"GCCSetup": {
"_active": true,
"_copy_from": "Command",
"build_command": "gccsetup --cc gcc --cxx g++ --config ../../../axivion/"
},
"LinkLibraries": {
"_active": true,
"_copy_from": "AxivionLinker",
"input_files": [
"build/lib/lib*.so*.ir"
],
"ir": "build/$(env:TESTED_MODULE_COIN).ir",
"plugin_files": [
"build/plugins/*/lib*.so*.ir"
]
},
"Project-GlobalOptions": {
"ci_mode": {
"clean_before": false
},
"directory": "../work/qt/$(env:TESTED_MODULE_COIN)",
"ir": "build/$(env:TESTED_MODULE_COIN).ir",
"name": "qt_$(env:TESTED_MODULE_COIN)_dev_$(env:TARGET_OS_COIN)"
}
},
"Results": {
"Dashboard": {
"dashboard_url": "https://axivion-srv.ci.qt.io/axivion/"
},
"Database": {
"ci_mode": {
"directory": "/data/axivion/databases"
}
}
},
"_Format": "1.0",
"_Version": "trunk-9e0ef9c5818",
"_VersionNum": [
7,
6,
9999,
11489
]
}

View File

@ -76,9 +76,14 @@ instructions:
- !include "{{qt/qtbase}}/call_host_install.yaml"
- type: SignPackage
enable_if:
condition: property
property: host.os
equals_value: Windows
condition: and
conditions:
- condition: property
property: host.os
equals_value: Windows
- condition: property
property: features
contains_value: Packaging
directory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200

View File

@ -73,9 +73,14 @@ instructions:
- !include "{{qt/qtbase}}/call_host_install.yaml"
- type: SignPackage
enable_if:
condition: property
property: host.os
equals_value: Windows
condition: and
conditions:
- condition: property
property: host.os
equals_value: Windows
- condition: property
property: features
contains_value: Packaging
directory: "{{.InstallRoot}}/{{.AgentWorkingDir}}"
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200

View File

@ -51,9 +51,21 @@ instructions:
condition: property
property: host.os
equals_value: Windows
- type: EnvironmentVariable
variableName: CTEST_ARGS
variableValue: "-V"
# Keep the testrun quiet for ASAN testruns, since there are FAILs happening all over the place
disable_if:
condition: property
property: features
contains_value: UseAddressSanitizer
# Always print the output from a failing test, even when ctest is not in verbose mode
- type: EnvironmentVariable
variableName: CTEST_OUTPUT_ON_FAILURE
variableValue: "1"
- type: AppendToEnvironmentVariable
variableName: CTEST_ARGS
variableValue: " --stop-on-failure"
@ -61,12 +73,37 @@ instructions:
condition: property
property: features
contains_value: AbortTestingOnFirstFailure
# Enable CTest's JUnit XML summary only for recent versions
- type: AppendToEnvironmentVariable
variableName: CTEST_ARGS
variableValue: " --output-junit {{.Env.COIN_CTEST_RESULTSDIR}}{{.Env.CI_PATH_SEP}}test_summary.ctest_junit_xml"
enable_if:
condition: runtime
env_var: CMAKE_MIN_SUPPORTED_BIN_PATH
equals_value: null
- type: EnvironmentVariable
variableName: COIN_COMMAND_OUTPUT_TIMEOUT
variableValue: "900"
disable_if:
condition: property
property: features
contains_value: UseAddressSanitizer
- type: EnvironmentVariable
variableName: COIN_COMMAND_OUTPUT_TIMEOUT
variableValue: "10800"
enable_if:
condition: property
property: features
contains_value: UseAddressSanitizer
- type: ExecuteCommand
command: "{{.Env.TESTS_ENV_PREFIX}} ctest {{.Env.CTEST_ARGS}}"
executeCommandArgumentSplitingBehavior: SplitAfterVariableSubstitution
ignoreExitCode: false
maxTimeInSeconds: 10800
maxTimeBetweenOutput: 900
maxTimeBetweenOutput: "{{.Env.COIN_COMMAND_OUTPUT_TIMEOUT}}"
userMessageOnFailure: >
Failed to run tests.

View File

@ -0,0 +1,98 @@
analysis_instructions_axivion: &analysis_instructions_axivion
type: Group
instructions:
- type: Group
instructions:
- type: EnvironmentVariable
variableName: AXIVION_CHAINLOAD_TOOLCHAIN_FILE
variableValue: "{{.AgentWorkingDir}}/install/lib/cmake/Qt6/qt.toolchain.cmake"
- type: EnvironmentVariable
variableName: CMAKE_PREFIX_PATH
variableValue: "{{.AgentWorkingDir}}/install/lib/cmake"
enable_if:
condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qtbase"
- type: Group
instructions:
- type: Rename
sourcePath: "{{.SourceDir}}/coin/axivion/ci_config_{{.Env.TARGET_OS_COIN}}.json"
targetPath: "{{.Env.HOME}}/axivion/ci_config.json"
userMessageOnFailure: "Moving ci_config.json failed. Make sure you have included the file in coin/axivion/ -folder"
- type: SetBuildDirectory
directory: "{{.SourceDir}}"
- type: ChangeDirectory
directory: "{{.BuildDir}}"
- type: ExecuteCommand
command: ["../../../axivion/start_analysis.sh"]
maxTimeInSeconds: 28800
maxTimeBetweenOutput: 28800
userMessageOnFailure: "Failed to run analysis"
build_environment_axivion: &build_environment_axivion
type: Group
instructions:
- type: ExecuteCommand
command: ["sudo", "mkdir", "-p","/data/axivion"]
maxTimeInSeconds: 100
maxTimeBetweenOutput: 100
userMessageOnFailure: "Create mount point for results failed"
- type: ExecuteCommand
command: ["sudo", "mount", "-o", "rw", "10.212.0.93:/data/axivion", "/data/axivion"]
maxTimeInSeconds: 100
maxTimeBetweenOutput: 100
userMessageOnFailure: "Mount failed"
- type: ExecuteCommand
command: ["rm","-rf","{{.SourceDir}}"]
maxTimeInSeconds: 100
maxTimeBetweenOutput: 100
userMessageOnFailure: "Failed to remove source directory"
- type: MakeDirectory
directory: "{{.SourceDir}}"
- type: ChangeDirectory
directory: "{{.SourceDir}}"
- type: ExecuteCommand
command: ["git", "clone", "--jobs={{.NumCPU}}", "-n","--depth=50", "git://{{.Env.QT_COIN_GIT_DAEMON}}/qt-project/qt/{{.Env.TESTED_MODULE_COIN}}","."]
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to clone repository"
- type: ExecuteCommand
command: ["git", "fetch", "--recurse-submodules", "origin", "{{.Env.TESTED_MODULE_REVISION_COIN}}"]
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to fetch sources"
- type: ExecuteCommand
command: ["git", "checkout", "--force", "{{.Env.TESTED_MODULE_REVISION_COIN}}"]
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to checkout sources"
- type: ExecuteCommand
command: ["git", "submodule", "update", "--init", "--recursive"]
maxTimeInSeconds: 1800
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to initialize git submodules"
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_module_build_instructions.yaml"
enable_if:
condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qtbase"
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_qtbase_build_instructions.yaml"
enable_if:
condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qtbase"
type: Group
instructions:
- !include "{{qt/qtbase}}/prepare_building_env.yaml"
- *build_environment_axivion
- *analysis_instructions_axivion
enable_if:
condition: property
property: features
contains_value: Axivion

View File

@ -24,6 +24,33 @@ instructions:
- condition: property
property: features
not_contains_value: "TargetBuildOnly"
- condition: property
property: features
not_contains_value: "DebianPackaging"
- condition: property
property: features
not_contains_value: Axivion
- type: Group
instructions:
- !include "{{qt/qtbase}}/coin_module_axivion_template_v2.yaml"
enable_if:
condition: and
conditions:
- condition: property
property: features
contains_value: Axivion
- condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qtdoc"
- condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qtquickeffectmaker"
- condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qttranslations"
- condition: runtime
env_var: TESTED_MODULE_COIN
not_equals_value: "qtwebengine"
- type: Group
instructions:
- !include "{{qt/qtbase}}/cmake_cross_compilation_module_build_instructions.yaml"
@ -48,3 +75,15 @@ instructions:
- condition: property
property: target.arch
equals_value: ARM64
- condition: property
property: features
not_contains_value: "DebianPackaging"
- type: Group
instructions:
- type: Group
instructions:
- !include "{{qt/qtbase}}/debian/debian_build_module.yaml"
enable_if:
condition: property
property: features
contains_value: "DebianPackaging"

View File

@ -17,6 +17,19 @@ instructions:
- condition: property
property: features
not_contains_value: "TargetBuildOnly"
- condition: property
property: features
not_contains_value: "DebianPackaging"
- condition: property
property: features
not_contains_value: Axivion
- type: Group
instructions:
- !include "{{qt/qtbase}}/coin_module_axivion_template_v2.yaml"
enable_if:
condition: property
property: features
contains_value: Axivion
- type: Group
instructions:
- type: Group
@ -53,3 +66,15 @@ instructions:
- condition: property
property: target.arch
equals_value: ARM64
- condition: property
property: features
not_contains_value: "DebianPackaging"
- type: Group
instructions:
- type: Group
instructions:
- !include "{{qt/qtbase}}/debian/debian_build_module.yaml"
enable_if:
condition: property
property: features
contains_value: "DebianPackaging"

View File

@ -0,0 +1,125 @@
type: Group
enable_if:
condition: property
property: features
contains_value: DebianPackaging
instructions:
- !include "{{qt/qtbase}}/debian/prepare_debian_env.yaml"
- type: EnvironmentVariable
variableName: GIT_SSH_COMMAND
variableValue: "ssh -o StrictHostKeyChecking=no"
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}"
- type: MakeDirectory
directory: output/debian_packages
- type: MakeDirectory
directory: debian_packages
- type: ExecuteCommand
command: "git clone git@git.qt.io:tqtc-debian/package_generator.git"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to clone package generator repo"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ExecuteCommand
command: "git clone -b 6.6 git@git.qt.io:tqtc-debian/qt6-{{.Env.TESTED_MODULE_PLAIN_COIN}}.git"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to clone debian packaging repo"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ChangeDirectory
directory: "qt6-{{.Env.TESTED_MODULE_PLAIN_COIN}}"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ExecuteCommand
command: "git checkout {{.Env.DEBIAN_RULES_REF}}"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to checkout debian rules branch"
disable_if:
condition: or
conditions:
- condition: runtime
env_var: DEBIAN_RULES_REF
equals_value: null
- condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}"
- type: ExecuteCommand
command: "wget -q {{.CoinDownloadURL}}/{{.Env.MODULE_SOURCES_RELATIVE_STORAGE_PATH}}"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed get sources"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ExecuteCommand
command: "mv sources_unix.tar.gz qt-{{.Env.QT_REPO_MODULE_VERSION}}-{{.Env.TESTED_MODULE_PLAIN_COIN}}-src_{{.Env.QT_REPO_MODULE_VERSION}}.orig.tar.gz"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed rename src pkg"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}/qt6-{{.Env.TESTED_MODULE_PLAIN_COIN}}"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
# rc is required currently by the script
- type: ExecuteCommand
command: "../package_generator/generate_packaging.sh --qt-version {{.Env.QT_REPO_MODULE_VERSION}} --deb-rev 1 --release tqtc-focal"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed to generate pkg"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ChangeDirectory
directory: "{{.AgentWorkingDir}}"
- type: ExecuteCommand
command: "dpkg-source -b qt6-{{.Env.TESTED_MODULE_PLAIN_COIN}}"
maxTimeInSeconds: 900
maxTimeBetweenOutput: 900
userMessageOnFailure: "Failed dpkg-source"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: ExecuteCommand
command: ["sbuild",
"--build-dep-resolver=apt",
"-sAd", "tqtc-focal",
"-c", "{{.Env.COIN_SBUILD_CHROOT}}",
"--build-dir", "output/debian_packages",
"--extra-repository={{.Env.COIN_EXTRA_DEBIAN_REPO}}",
"--extra-package={{.Env.COIN_EXTRA_DEBIAN_PACKAGES}}",
"--extra-package={{.AgentWorkingDir}}/debian_packages/",
"qt-{{.Env.QT_REPO_MODULE_VERSION}}-{{.Env.TESTED_MODULE_PLAIN_COIN}}-src_{{.Env.QT_REPO_MODULE_VERSION}}-1.dsc"]
maxTimeInSeconds: 18000
maxTimeBetweenOutput: 18000
userMessageOnFailure: "Failed build debian packages"
disable_if:
condition: runtime
env_var: COIN_SKIP_DEBIAN
contains_value: "MISSING_DEBIAN_INST"
- type: UploadArtifact
archiveDirectory: "{{.AgentWorkingDir}}/output"
transferType: UploadModuleBuildArtifact
maxTimeInSeconds: 1200
maxTimeBetweenOutput: 1200

View File

@ -0,0 +1,85 @@
type: Group
enable_if:
condition: property
property: features
contains_value: DebianPackaging
instructions:
- type: EnvironmentVariable
variableName: COIN_SBUILD_CHROOT
variableValue: "stable-arm64-sbuild"
enable_if:
condition: and
conditions:
- condition: runtime
env_var: COIN_SBUILD_CHROOT
equals_value: null
- condition: property
property: target.arch
equals_value: AARCH64
- type: EnvironmentVariable
variableName: COIN_SBUILD_CHROOT
variableValue: "stable-amd64-sbuild"
enable_if:
condition: and
conditions:
- condition: runtime
env_var: COIN_SBUILD_CHROOT
equals_value: null
- condition: property
property: target.arch
equals_value: X86_64
- type: EnvironmentVariable
variableName: COIN_SBUILD_DISTRO
variableValue: "arm64-focal"
enable_if:
condition: property
property: target.arch
equals_value: AARCH64
- type: EnvironmentVariable
variableName: COIN_SBUILD_DISTRO
variableValue: "amd64-focal"
disable_if:
condition: property
property: target.arch
equals_value: AARCH64
- type: EnvironmentVariable
variableName: COIN_SKIP_DEBIAN
variableValue: "MISSING_DEBIAN_INST"
enable_if:
condition: or
conditions:
- condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qtactiveqt"
- condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qtqa"
- condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qtdoc"
- condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qt5"
# Set version info to environment
- type: ParseEnvironmentVariableFromFile
regex: "QT_REPO_MODULE_VERSION \"(?P<QT_REPO_MODULE_VERSION>.*)\""
filename: "{{.SourceDir}}/.cmake.conf"
maxTimeInSeconds: 300
maxTimeBetweenOutput: 300
userMessageOnFailure: "Failed to parse version information from .cmake.conf"
disable_if:
condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qt5"
- type: ParseEnvironmentVariableFromFile
regex: "QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT \"(?P<QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT>.*)\""
filename: "{{.SourceDir}}/.cmake.conf"
maxTimeInSeconds: 300
maxTimeBetweenOutput: 300
userMessageOnFailure: "Failed to parse status information from .cmake.conf"
disable_if:
condition: runtime
env_var: TESTED_MODULE_COIN
equals_value: "qt5"

View File

@ -4,9 +4,17 @@ accept_configuration:
property: features
not_contains_value: Disable
downstream_check:
mode: build
modules:
../qtdeclarative:
ref: dev
configurations:
- rhel-8.4
machine_type:
Build:
cores: 4
cores: 8
Test:
cores: 4

View File

@ -141,7 +141,7 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
// Leading-Zero bit count, Intel Core 4th Generation ("Haswell")
" lzcnt"
#endif
#ifdef __MMX__
#if defined(__MMX__) && defined(__i386__)
// Multimedia Extensions, Pentium MMX, AMD K6-2
" mmx"
#endif
@ -198,11 +198,11 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
// Shadow stack, Intel processor TBA
" shstk"
#endif
#if defined(__SSE__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) || defined(_M_X64)
#if (defined(__SSE__) && defined(__i386__)) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1 && defined(_M_IX86))
// Streaming SIMD Extensions, Intel Pentium III, AMD Athlon
" sse"
#endif
#if defined(__SSE2__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2) || defined(_M_X64)
#if (defined(__SSE2__) && defined(__i386__)) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2 && defined(_M_IX86))
// SSE2, Intel Pentium-M, Intel Pentium 4, AMD Opteron and Athlon 64
" sse2"
#endif

View File

@ -1,7 +1,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# special case skip regeneration
cmake_minimum_required(VERSION 3.16)
project(objcopytest LANGUAGES CXX)
add_executable(objcopytest main.cpp)

View File

@ -64,10 +64,13 @@ Build options:
-cmake-file-api ...... Let CMake store build metadata for loading the build
into an IDE. [no; yes if -developer-build]
-no-guess-compiler ... Do not guess the compiler from the target mkspec.
-release ............. Build Qt with debugging turned off [yes]
-debug ............... Build Qt with debugging turned on [no]
-debug-and-release ... Build two versions of Qt, with and without
debugging turned on [yes] (Apple and Windows only)
-release ............. Build Qt with optimizations and without debug
symbols [yes]
Note that -developer-build implies -debug unless
-release is also explicitly specified
-debug ............... Build Qt without optimizations and with debug symbols
[no]
-debug-and-release ... Build two versions of Qt in one build tree [no]
-optimize-debug ...... Enable debug-friendly optimizations in debug builds
[auto] (Not supported with MSVC or Clang toolchains)
-optimize-size ....... Optimize release builds for size instead of speed [no]
@ -80,7 +83,8 @@ Build options:
sections. [auto for static builds, otherwise no]
-force-asserts ....... Enable Q_ASSERT even in release builds [no]
-developer-build ..... Compile and link Qt for developing Qt itself
(exports for auto-tests, extra checks, etc.) [no]
(exports for auto-tests, extra checks, implies
-no-prefix, etc.) [no]
-shared .............. Build shared Qt libraries [yes] (no for UIKit)
-static .............. Build static Qt libraries [no] (yes for UIKit)
@ -157,10 +161,10 @@ Build options:
Build environment:
-sysroot <dir> ....... Set <dir> as the target sysroot
-pkg-config .......... Use pkg-config [auto] (Unix only)
-vcpkg ............... Use vcpkg [yes]
-D <string> .......... Pass additional preprocessor define
-I <string> .......... Pass additional include path
-L <string> .......... Pass additional library path
@ -198,6 +202,9 @@ Component selection:
[default: libs and examples, also tools if not
cross-building, also tests if -developer-build]
-nomake <part> ....... Exclude <part> from the list of parts to be built.
-install-examples-sources Installs examples source code into the Qt prefix
Only possible when -make examples is also passed
[no]
-gui ................. Build the Qt GUI module and dependencies [yes]
-widgets ............. Build the Qt Widgets module and dependencies [yes]
-no-dbus ............. Do not build the Qt D-Bus module
@ -289,6 +296,6 @@ Gui, printing, widget options:
Database options:
-sql-<driver> ........ Enable SQL <driver> plugin. Supported drivers:
db2 ibase mysql oci odbc psql sqlite
db2 ibase mysql oci odbc psql sqlite mimer
[all auto]
-sqlite .............. Select used sqlite [system/qt]

2
configure vendored
View File

@ -136,7 +136,7 @@ determineOptFilePath "$@"
optfilepath=${outpathPrefix}/config.opt
opttmpfilepath=${outpathPrefix}/config.opt.in
redofilepath=${outpathPrefix}/config.redo
redofilepath=${outpathPrefix}/config.redo.last
redotmpfilepath=${outpathPrefix}/config.redo.in
fresh_requested_arg=

View File

@ -79,7 +79,7 @@ cd "%TOPQTDIR%"
rem Write config.opt if we're not currently -redo'ing
set OPT_FILE_PATH=%TOPQTDIR%\config.opt
set OPT_TMP_FILE_PATH=%TOPQTDIR%\config.opt.in
set REDO_FILE_PATH=%TOPQTDIR%\config.redo
set REDO_FILE_PATH=%TOPQTDIR%\config.redo.last
set REDO_TMP_FILE_PATH=%TOPQTDIR%\config.redo.in
set FRESH_REQUESTED_ARG=
if not defined redoing (

View File

@ -109,7 +109,6 @@ SSL_free(SSL_new(0));
}
")
# special case end
qt_find_package(WrapZSTD 1.3 PROVIDED_TARGETS WrapZSTD::WrapZSTD MODULE_NAME global QMAKE_LIB zstd)
qt_find_package(WrapDBus1 1.2 PROVIDED_TARGETS dbus-1 MODULE_NAME global QMAKE_LIB dbus)
qt_find_package(Libudev PROVIDED_TARGETS PkgConfig::Libudev MODULE_NAME global QMAKE_LIB libudev)
@ -208,51 +207,6 @@ endif()
# machineTuple
qt_config_compile_test_machine_tuple("machine tuple")
# cxx14
qt_config_compile_test(cxx14
LABEL "C++14 support"
CODE
"#if __cplusplus > 201103L
// Compiler claims to support C++14, trust it
#else
# error __cplusplus must be > 201103L (the value of C++11)
#endif
int main(void)
{
/* BEGIN TEST: */
/* END TEST: */
return 0;
}
"
CXX_STANDARD 14
)
# cxx17
qt_config_compile_test(cxx17
LABEL "C++17 support"
CODE
"#if __cplusplus > 201402L
// Compiler claims to support C++17, trust it
#else
# error __cplusplus must be > 201402L (the value for C++14)
#endif
#include <map> // https://bugs.llvm.org//show_bug.cgi?id=33117
#include <variant>
int main(void)
{
/* BEGIN TEST: */
std::variant<int> v(42);
int i = std::get<int>(v);
std::visit([](const auto &) { return 1; }, v);
/* END TEST: */
return 0;
}
"
CXX_STANDARD 17
)
# cxx20
qt_config_compile_test(cxx20
LABEL "C++20 support"
@ -485,7 +439,6 @@ qt_feature("android-style-assets" PRIVATE
)
qt_feature("shared" PUBLIC
LABEL "Building shared libraries"
AUTODETECT NOT UIKIT
CONDITION BUILD_SHARED_LIBS
)
qt_feature_definition("shared" "QT_STATIC" NEGATE PREREQUISITE "!defined(QT_SHARED) && !defined(QT_STATIC)")
@ -517,7 +470,6 @@ qt_feature("optimize_size"
CONDITION NOT QT_FEATURE_debug OR QT_FEATURE_debug_and_release
)
qt_feature_config("optimize_size" QMAKE_PRIVATE_CONFIG)
# special case begin
qt_feature("optimize_full"
LABEL "Fully optimize release builds (-O3)"
AUTODETECT OFF
@ -526,10 +478,10 @@ qt_feature_config("optimize_full" QMAKE_PRIVATE_CONFIG)
qt_feature("msvc_obj_debug_info"
LABEL "Embed debug info in object files (MSVC)"
CONDITION MSVC
ENABLE QT_USE_CCACHE
AUTODETECT OFF
)
qt_feature_config("msvc_obj_debug_info" QMAKE_PRIVATE_CONFIG)
# special case end
qt_feature("pkg-config" PUBLIC
LABEL "Using pkg-config"
AUTODETECT NOT APPLE AND NOT WIN32 AND NOT ANDROID
@ -667,29 +619,10 @@ qt_feature_config("plugin-manifests" QMAKE_PUBLIC_CONFIG
NEGATE
NAME "no_plugin_manifest"
)
qt_feature("c++11" PUBLIC
LABEL "C++11"
)
qt_feature_config("c++11" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("c++14" PUBLIC
LABEL "C++14"
CONDITION QT_FEATURE_cxx11 AND TEST_cxx14
)
qt_feature_config("c++14" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("c++17" PUBLIC
LABEL "C++17"
CONDITION QT_FEATURE_cxx14 AND TEST_cxx17
)
qt_feature_config("c++17" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("c++1z" PUBLIC
LABEL "C++17"
CONDITION QT_FEATURE_cxx17
)
qt_feature_config("c++1z" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("c++20" PUBLIC
LABEL "C++20"
AUTODETECT OFF
CONDITION QT_FEATURE_cxx17 AND TEST_cxx20
CONDITION TEST_cxx20
)
qt_feature_config("c++20" QMAKE_PUBLIC_QT_CONFIG)
qt_feature("c++2a" PUBLIC
@ -707,17 +640,6 @@ qt_feature("c++2b" PUBLIC
AUTODETECT FALSE
CONDITION QT_FEATURE_cxx20 AND (CMAKE_VERSION VERSION_GREATER_EQUAL "3.20") AND TEST_cxx2b
)
qt_feature("c89"
LABEL "C89"
)
qt_feature("c99" PUBLIC
LABEL "C99"
CONDITION c_std_99 IN_LIST CMAKE_C_COMPILE_FEATURES
)
qt_feature("c11" PUBLIC
LABEL "C11"
CONDITION QT_FEATURE_c99 AND c_std_11 IN_LIST CMAKE_C_COMPILE_FEATURES
)
qt_feature("precompile_header"
LABEL "Using precompiled headers"
CONDITION BUILD_WITH_PCH AND TEST_precompile_header
@ -920,7 +842,9 @@ qt_feature_definition("mips_dspr2" "QT_COMPILER_SUPPORTS_MIPS_DSPR2" VALUE "1")
qt_feature_config("mips_dspr2" QMAKE_PRIVATE_CONFIG)
qt_feature("neon" PRIVATE
LABEL "NEON"
CONDITION ( ( ( TEST_architecture_arch STREQUAL arm ) OR ( TEST_architecture_arch STREQUAL arm64 ) ) AND TEST_arch_${TEST_architecture_arch}_subarch_neon ) OR QT_FORCE_FEATURE_neon # special case
CONDITION ( ( ( TEST_architecture_arch STREQUAL arm ) OR
( TEST_architecture_arch STREQUAL arm64 ) ) AND
TEST_arch_${TEST_architecture_arch}_subarch_neon ) OR QT_FORCE_FEATURE_neon
)
qt_feature_definition("neon" "QT_COMPILER_SUPPORTS_NEON" VALUE "1")
qt_feature_config("neon" QMAKE_PRIVATE_CONFIG)
@ -986,7 +910,6 @@ qt_feature("stdlib-libcpp" PRIVATE
AUTODETECT OFF
CONDITION LINUX AND NOT ANDROID
)
# special case begin
# Check whether CMake was built with zstd support.
# See https://gitlab.kitware.com/cmake/cmake/-/issues/21552
if(NOT DEFINED CACHE{QT_CMAKE_ZSTD_SUPPORT})
@ -1003,7 +926,6 @@ if(NOT DEFINED CACHE{QT_CMAKE_ZSTD_SUPPORT})
unset(qt_check_zstd_exit_code)
endif()
endif()
# special case end
qt_feature("thread" PUBLIC
SECTION "Kernel"
LABEL "Thread support"
@ -1143,22 +1065,10 @@ qt_configure_add_summary_entry(
ARGS "optimize_size"
CONDITION NOT QT_FEATURE_debug OR QT_FEATURE_debug_and_release
)
# special case begin
qt_configure_add_summary_entry(
ARGS "optimize_full"
)
# special case end
qt_configure_add_summary_entry(ARGS "shared")
qt_configure_add_summary_entry(
TYPE "firstAvailableFeature"
ARGS "c11 c99 c89"
MESSAGE "Using C standard"
)
qt_configure_add_summary_entry(
TYPE "firstAvailableFeature"
ARGS "c++2b c++20 c++17 c++14 c++11"
MESSAGE "Using C++ standard"
)
qt_configure_add_summary_entry(
ARGS "ccache"
CONDITION UNIX
@ -1232,6 +1142,13 @@ qt_configure_add_summary_entry(ARGS "sanitize_fuzzer_no_link")
qt_configure_add_summary_entry(ARGS "sanitize_undefined")
qt_configure_end_summary_section() # end of "Sanitizers" section
qt_configure_add_summary_build_parts("Build parts")
if(QT_INSTALL_EXAMPLES_SOURCES)
set(_examples_sources_entry_message "yes")
else()
set(_examples_sources_entry_message "no")
endif()
qt_configure_add_summary_entry(ARGS "Install examples sources" TYPE "message"
MESSAGE "${_examples_sources_entry_message}")
qt_configure_add_summary_entry(
ARGS "appstore-compliant"
CONDITION APPLE OR ANDROID OR WIN32
@ -1251,6 +1168,14 @@ qt_configure_add_summary_entry(ARGS "xml")
qt_configure_end_summary_section() # end of "Qt modules and options" section
qt_configure_add_summary_section(NAME "Support enabled for")
qt_configure_add_summary_entry(ARGS "pkg-config")
if(QT_USE_VCPKG AND (DEFINED ENV{VCPKG_ROOT} OR VCPKG_TARGET_TRIPLET))
set(_vcpkg_entry_message "yes")
else()
set(_vcpkg_entry_message "no")
endif()
qt_configure_add_summary_entry(ARGS "Using vcpkg" TYPE "message" MESSAGE "${_vcpkg_entry_message}")
qt_configure_add_summary_entry(ARGS "libudev")
qt_configure_add_summary_entry(ARGS "openssl")
qt_configure_add_summary_entry(ARGS "openssl-linked")
@ -1265,13 +1190,6 @@ qt_configure_add_report_entry(
MESSAGE "Using static linking will disable the use of dynamically loaded plugins. Make sure to import all needed static plugins, or compile needed modules into the library."
CONDITION NOT QT_FEATURE_shared
)
# special case begin
# qt_configure_add_report_entry(
# TYPE ERROR
# MESSAGE "Debug build without Release build is not currently supported on ios see QTBUG-71990. Use -debug-and-release."
# CONDITION IOS AND QT_FEATURE_debug AND NOT QT_FEATURE_debug_and_release
# )
# special case end
qt_configure_add_report_entry(
TYPE WARNING
MESSAGE "-debug-and-release is only supported on Darwin and Windows platforms. Qt can be built in release mode with separate debug information, so -debug-and-release is no longer necessary."
@ -1301,6 +1219,16 @@ if (TEST_architecture_arch STREQUAL x86_64 OR TEST_architecture_arch STREQUAL i3
MESSAGE [=[
All x86 intrinsics and SIMD support were disabled. If this was in error, check
the result of the build in config.tests/x86intrin and report at https://bugreports.qt.io.
]=]
)
elseif (MSVC AND CLANG)
# Warn only
qt_configure_add_report_entry(
TYPE WARNING
CONDITION (NOT QT_FEATURE_x86intrin)
MESSAGE [=[
x86 intrinsics support is disabled for clang-cl build. This might be necessary due to
https://github.com/llvm/llvm-project/issues/53520
]=]
)
else()
@ -1317,7 +1245,6 @@ ${TEST_x86intrin_OUTPUT}
)
endif()
endif()
# special case begin
qt_configure_add_report_entry(
TYPE ERROR
MESSAGE "Setting a library infix is not supported for framework builds."
@ -1336,7 +1263,6 @@ qt_configure_add_report_entry(
if(WASM)
qt_extra_definition("QT_EMCC_VERSION" "\"${EMCC_VERSION}\"" PUBLIC)
endif()
# special case end
qt_extra_definition("QT_VERSION_STR" "\"${PROJECT_VERSION}\"" PUBLIC)
qt_extra_definition("QT_VERSION_MAJOR" ${PROJECT_VERSION_MAJOR} PUBLIC)
qt_extra_definition("QT_VERSION_MINOR" ${PROJECT_VERSION_MINOR} PUBLIC)

View File

@ -1,7 +1,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
# special case skip regeneration
#
# Copy/Install doc configuration files to the build/install directory
#

View File

@ -125,6 +125,7 @@ macro.cmakepropertywebassemblyonly = "\\note This property is used only if targe
macro.cmakepropertyiosonly = "\\note This property is used only if targeting iOS."
macro.cmakevariableiosonly = "\\note This variable is used only if targeting iOS."
macro.qtpolicydeprecatedbehavior = "\\note The \\c{OLD} behavior of a policy is deprecated, and may be removed in the future."
#Appends the tech preview link to the brief sentence and adds to tech_preview
#group.
#Must be placed directly under a \brief command

View File

@ -35,7 +35,7 @@ manifestmeta.highlighted.attributes = isHighlighted:true
manifestmeta.android.names = "Qt3D/Qt 3D: Basic Shapes C++ Example" \
"Qt3D/Qt 3D: Planets QML Example" \
"Qt3D/Qt 3D: Simple Custom Material QML Example" \
"QtAndroidExtras/Qt Notifier" \
"QtCore/Qt Android Notifier" \
"QtBluetooth/Bluetooth Low Energy Scanner Example" \
"QtBluetooth/Bluetooth Scanner Example" \
"QtBluetooth/QML Bluetooth Scanner Example" \
@ -51,15 +51,12 @@ manifestmeta.android.names = "Qt3D/Qt 3D: Basic Shapes C++ Example" \
"QtLocation/Places Map (QML)" \
"QtLocation/Plane Spotter (QML)" \
"QtMultimedia/AudioEngine Example" \
"QtMultimedia/Camera Example" \
"QtMultimedia/QML Camera Example" \
"QtMultimedia/QML Video Example" \
"QtMultimedia/QML Video Shader Effects Example" \
"QtNFC/Annotated URL Example" \
"QtNFC/QML Poster Example" \
"QtOpenGL/2D Painting Example" \
"QtOpenGL/Hello GLES3 Example" \
"QtOpenGL/Textures Example" \
"QtPositioning/SatelliteInfo (C++/QML)" \
"QtPositioning/Weather Info (C++/QML)" \
"QtPurchasing/Qt Purchasing Examples - QtHangman" \
@ -94,8 +91,6 @@ manifestmeta.android.names = "Qt3D/Qt 3D: Basic Shapes C++ Example" \
"QtQuickControls/Qt Quick Controls - Flat Style" \
"QtQuickControls/Qt Quick Controls - Gallery" \
"QtQuickControls/Qt Quick Controls - Imagine Style Example: Automotive" \
"QtQuickControls/Qt Quick Controls - Side Panel" \
"QtQuickControls/Qt Quick Controls - Swipe to Remove" \
"QtQuickControls/Qt Quick Controls - Text Editor" \
"QtQuickControls/Qt Quick Controls - Wearable Demo" \
"QtQuickDialogs/*" \
@ -107,47 +102,7 @@ manifestmeta.android.names = "Qt3D/Qt 3D: Basic Shapes C++ Example" \
"QtSQL/Master Detail Example" \
"QtSVG/Text Object Example" \
"QtUiTools/Text Finder Example" \
"QtWebView/Qt WebView Examples - Minibrowser" \
"QtWidgets/Address Book Example" \
"QtWidgets/Affine Transformations" \
"QtWidgets/Analog Clock Example" \
"QtWidgets/Animated Tiles Example" \
"QtWidgets/Application Chooser Example" \
"QtWidgets/Basic Layouts Example" \
"QtWidgets/Border Layout Example" \
"QtWidgets/Code Editor Example" \
"QtWidgets/Colliding Mice Example" \
"QtWidgets/Concentric Circles Example" \
"QtWidgets/Digital Clock Example" \
"QtWidgets/Dynamic Layouts Example" \
"QtWidgets/Easing Curves Example" \
"QtWidgets/Editable Tree Model Example" \
"QtWidgets/Elided Label Example" \
"QtWidgets/Fade Message Effect Example" \
"QtWidgets/Flow Layout Example" \
"QtWidgets/Font Sampler Example" \
"QtWidgets/Frozen Column Example" \
"QtWidgets/Gradients" \
"QtWidgets/Group Box Example" \
"QtWidgets/Image Composition Example" \
"QtWidgets/Line Edits Example" \
"QtWidgets/Mouse Button Tester" \
"QtWidgets/Move Blocks Example" \
"QtWidgets/Painter Paths Example" \
"QtWidgets/Painter Paths Example" \
"QtWidgets/Path Stroking" \
"QtWidgets/Pixelator Example" \
"QtWidgets/Recent Files Example" \
"QtWidgets/SDI Example" \
"QtWidgets/Scribble Example" \
"QtWidgets/Simple Tree Model Example" \
"QtWidgets/Sliders Example" \
"QtWidgets/Spreadsheet" \
"QtWidgets/Touch Dials Example" \
"QtWidgets/Transformations Example" \
"QtWidgets/Undo Framework" \
"QtWidgets/Vector Deformation" \
"QtWidgets/Wiggly Example"
"QtWebView/Qt WebView Examples - Minibrowser"
manifestmeta.android.tags = android
@ -247,9 +202,9 @@ manifestmeta.thumbnail.attributes = "imageUrl:qthelp\://org.qt-project.qtdoc.$Q
manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \
"QtCore/Custom Type Example" \
"QtCore/JSON Save Game Example" \
"QtCore/Semaphores Example" \
"QtCore/Wait Conditions Example" \
"QtCore/Saving and Loading a Game" \
"QtCore/Producer and Consumer using Semaphores" \
"QtCore/Producer and Consumer using Wait Conditions" \
"QtConcurrent/Word Count" \
"QtGui/Raster Window Example" \
"QtNetwork/Network Download*" \

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,2 +1,25 @@
qt_internal_add_example(bindablesubscription)
qt_internal_add_example(subscription)
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(bindableproperties LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/bindableproperties")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
add_subdirectory(shared)
add_subdirectory(subscription)
add_subdirectory(bindablesubscription)
install(TARGETS subscription bindablesubscription
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,50 +1,15 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(bindablesubscription LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/bindableproperties/bindablesubscription")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(bindablesubscription
../shared/subscriptionwindow.cpp ../shared/subscriptionwindow.h ../shared/subscriptionwindow.ui
main.cpp
bindablesubscription.cpp bindablesubscription.h
bindableuser.cpp bindableuser.h
bindablesubscription.cpp
bindablesubscription.h
bindableuser.cpp
bindableuser.h
)
target_link_libraries(bindablesubscription PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
bindableproperties_shared
)
# Resources:
set(countries_resource_files
"../shared/finland.png"
"../shared/germany.png"
"../shared/norway.png"
)
qt_add_resources(bindablesubscription "countries"
PREFIX
"/"
BASE
"../shared"
FILES
${countries_resource_files}
)
install(TARGETS bindablesubscription
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -4,7 +4,7 @@
#ifndef BINDABLESUBSCRIPTION_H
#define BINDABLESUBSCRIPTION_H
#include <QPointer>
#include <QBindable>
#include <QProperty>
class BindableUser;

View File

@ -4,6 +4,7 @@
#ifndef BINDABLEUSER_H
#define BINDABLEUSER_H
#include <QBindable>
#include <QLocale>
#include <QProperty>

View File

@ -6,15 +6,15 @@
#include "bindableuser.h"
#include <QApplication>
#include <QButtonGroup>
#include <QBindable>
#include <QLabel>
#include <QLocale>
#include <QPushButton>
#include <QRadioButton>
#include <QSpinBox>
#include <QProperty>
#include <QString>
#include <QDateTimeEdit>
#include <QBindable>
using namespace Qt::StringLiterals;
int main(int argc, char *argv[])
{
@ -27,38 +27,38 @@ int main(int argc, char *argv[])
// when subscription is out of scope so is window
// Initialize subscription data
QRadioButton *monthly = w.findChild<QRadioButton *>("btnMonthly");
QRadioButton *monthly = w.findChild<QRadioButton *>(u"btnMonthly"_s);
QObject::connect(monthly, &QRadioButton::clicked, [&] {
subscription.setDuration(BindableSubscription::Monthly);
});
QRadioButton *quarterly = w.findChild<QRadioButton *>("btnQuarterly");
QRadioButton *quarterly = w.findChild<QRadioButton *>(u"btnQuarterly"_s);
QObject::connect(quarterly, &QRadioButton::clicked, [&] {
subscription.setDuration(BindableSubscription::Quarterly);
});
QRadioButton *yearly = w.findChild<QRadioButton *>("btnYearly");
QRadioButton *yearly = w.findChild<QRadioButton *>(u"btnYearly"_s);
QObject::connect(yearly, &QRadioButton::clicked, [&] {
subscription.setDuration(BindableSubscription::Yearly);
});
// Initialize user data
QPushButton *germany = w.findChild<QPushButton *>("btnGermany");
QPushButton *germany = w.findChild<QPushButton *>(u"btnGermany"_s);
QObject::connect(germany, &QPushButton::clicked, [&] {
user.setCountry(BindableUser::Country::Germany);
});
QPushButton *finland = w.findChild<QPushButton *>("btnFinland");
QPushButton *finland = w.findChild<QPushButton *>(u"btnFinland"_s);
QObject::connect(finland, &QPushButton::clicked, [&] {
user.setCountry(BindableUser::Country::Finland);
});
QPushButton *norway = w.findChild<QPushButton *>("btnNorway");
QPushButton *norway = w.findChild<QPushButton *>(u"btnNorway"_s);
QObject::connect(norway, &QPushButton::clicked, [&] {
user.setCountry(BindableUser::Country::Norway);
});
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>("ageSpinBox");
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>(u"ageSpinBox"_s);
QBindable<int> ageBindable(ageSpinBox, "value");
user.bindableAge().setBinding([ageBindable](){ return ageBindable.value();});
QLabel *priceDisplay = w.findChild<QLabel *>("priceDisplay");
QLabel *priceDisplay = w.findChild<QLabel *>(u"priceDisplay"_s);
// Track price changes
//! [update-ui]

View File

@ -3,7 +3,8 @@
/*!
\example bindableproperties
\title Bindable Properties Example
\examplecategory {Data Processing & I/O}
\title Bindable Properties
\brief Demonstrates how the usage of bindable properties can simplify
your C++ code.

View File

@ -0,0 +1,23 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_library(bindableproperties_shared STATIC
subscriptionwindow.cpp
subscriptionwindow.h
subscriptionwindow.ui
)
target_link_libraries(bindableproperties_shared PUBLIC
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
qt_add_resources(bindableproperties_shared "countries"
PREFIX
"/"
FILES
"finland.png"
"germany.png"
"norway.png"
)

View File

@ -1,50 +1,12 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(subscription LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/corelib/bindableproperties/subscription")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
qt_add_executable(subscription
../shared/subscriptionwindow.cpp ../shared/subscriptionwindow.h ../shared/subscriptionwindow.ui
main.cpp
subscription.cpp subscription.h
user.cpp user.h
)
target_link_libraries(subscription PRIVATE
Qt6::Core
Qt6::Gui
Qt6::Widgets
)
# Resources:
set(countries_resource_files
"../shared/finland.png"
"../shared/germany.png"
"../shared/norway.png"
)
qt_add_resources(subscription "countries"
PREFIX
"/"
BASE
"../shared"
FILES
${countries_resource_files}
)
install(TARGETS subscription
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
bindableproperties_shared
)

View File

@ -6,11 +6,14 @@
#include "user.h"
#include <QApplication>
#include <QButtonGroup>
#include <QLabel>
#include <QLocale>
#include <QPushButton>
#include <QRadioButton>
#include <QSpinBox>
#include <QString>
using namespace Qt::StringLiterals;
int main(int argc, char *argv[])
{
@ -24,40 +27,40 @@ int main(int argc, char *argv[])
SubscriptionWindow w;
// Initialize subscription data
QRadioButton *monthly = w.findChild<QRadioButton *>("btnMonthly");
QRadioButton *monthly = w.findChild<QRadioButton *>(u"btnMonthly"_s);
QObject::connect(monthly, &QRadioButton::clicked, &subscription, [&] {
subscription.setDuration(Subscription::Monthly);
});
QRadioButton *quarterly = w.findChild<QRadioButton *>("btnQuarterly");
QRadioButton *quarterly = w.findChild<QRadioButton *>(u"btnQuarterly"_s);
QObject::connect(quarterly, &QRadioButton::clicked, &subscription, [&] {
subscription.setDuration(Subscription::Quarterly);
});
QRadioButton *yearly = w.findChild<QRadioButton *>("btnYearly");
QRadioButton *yearly = w.findChild<QRadioButton *>(u"btnYearly"_s);
QObject::connect(yearly, &QRadioButton::clicked, &subscription, [&] {
subscription.setDuration(Subscription::Yearly);
});
// Initialize user data
QPushButton *germany = w.findChild<QPushButton *>("btnGermany");
QPushButton *germany = w.findChild<QPushButton *>(u"btnGermany"_s);
QObject::connect(germany, &QPushButton::clicked, &user, [&] {
user.setCountry(User::Country::Germany);
});
QPushButton *finland = w.findChild<QPushButton *>("btnFinland");
QPushButton *finland = w.findChild<QPushButton *>(u"btnFinland"_s);
QObject::connect(finland, &QPushButton::clicked, &user, [&] {
user.setCountry(User::Country::Finland);
});
QPushButton *norway = w.findChild<QPushButton *>("btnNorway");
QPushButton *norway = w.findChild<QPushButton *>(u"btnNorway"_s);
QObject::connect(norway, &QPushButton::clicked, &user, [&] {
user.setCountry(User::Country::Norway);
});
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>("ageSpinBox");
QSpinBox *ageSpinBox = w.findChild<QSpinBox *>(u"ageSpinBox"_s);
QObject::connect(ageSpinBox, &QSpinBox::valueChanged, &user, [&](int value) {
user.setAge(value);
});
// Initialize price data
QLabel *priceDisplay = w.findChild<QLabel *>("priceDisplay");
QLabel *priceDisplay = w.findChild<QLabel *>(u"priceDisplay"_s);
priceDisplay->setText(QString::number(subscription.price()));
priceDisplay->setEnabled(subscription.isValid());

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -3,14 +3,16 @@
/*!
\example ipc/localfortuneclient
\title Local Fortune Client Example
\examplecategory {Connectivity}
\title Local Fortune Client
\ingroup examples-ipc
\brief Demonstrates using QLocalSocket for a simple local service client.
The Local Fortune Client example shows how to create a client for a simple
local service using QLocalSocket. It is intended to be run alongside the
\l{Local Fortune Server Example}.
\l{Local Fortune Server} example.
\image localfortuneclient-example.png Screenshot of the Local Fortune Client example
\image localfortuneclient-example.png Screenshot of the Local Fortune Client
example
*/

View File

@ -3,13 +3,14 @@
/*!
\example ipc/localfortuneserver
\title Local Fortune Server Example
\examplecategory {Connectivity}
\title Local Fortune Server
\ingroup examples-ipc
\brief Demonstrates using QLocalServer and QLocalSocket for serving a simple local service.
The Local Fortune Server example shows how to create a server for a simple
local service. It is intended to be run alongside the
\l{Local Fortune Client Example}
\l{Local Fortune Client} example.
\image localfortuneserver-example.png Screenshot of the Local Fortune Server example
*/

View File

@ -3,10 +3,11 @@
/*!
\example ipc/sharedmemory
\title Shared Memory Example
\examplecategory {Data Processing & I/O}
\title IPC: Shared Memory
\ingroup examples-ipc
\brief Demonstrates doing inter-process communication using shared memory with
the QSharedMemory class.
\brief Demonstrates how to share image data between different processes
using the Shared Memory IPC mechanism.
The Shared Memory example shows how to use the QSharedMemory class
to implement inter-process communication using shared memory. To

View File

@ -1,14 +1,19 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QtWidgets>
#include <QtNetwork>
#include "client.h"
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGuiApplication>
#include <QMessageBox>
#include <QTimer>
using namespace Qt::StringLiterals;
Client::Client(QWidget *parent)
: QDialog(parent),
hostLineEdit(new QLineEdit("fortune")),
hostLineEdit(new QLineEdit(u"fortune"_s)),
getFortuneButton(new QPushButton(tr("Get Fortune"))),
statusLabel(new QLabel(tr("This examples requires that you run the "
"Local Fortune Server example as well."))),
@ -28,7 +33,7 @@ Client::Client(QWidget *parent)
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
in.setDevice(socket);
in.setVersion(QDataStream::Qt_5_10);
in.setVersion(QDataStream::Qt_6_0);
connect(hostLineEdit, &QLineEdit::textChanged,
this, &Client::enableGetFortuneButton);

View File

@ -4,15 +4,12 @@
#ifndef CLIENT_H
#define CLIENT_H
#include <QDialog>
#include <QDataStream>
#include <QDialog>
#include <QLabel>
#include <QLineEdit>
#include <QLocalSocket>
QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE
#include <QPushButton>
class Client : public QDialog
{

View File

@ -1,10 +1,10 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include "client.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

View File

@ -1,10 +1,10 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include "server.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);

View File

@ -3,27 +3,33 @@
#include "server.h"
#include <QtWidgets>
#include <QtNetwork>
#include <QDialogButtonBox>
#include <QGuiApplication>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QLocalSocket>
#include <QMessageBox>
#include <QPushButton>
#include <QRandomGenerator>
using namespace Qt::StringLiterals;
static const QString idleStateText = QObject::tr("Press \"Listen\" to start the server");
Server::Server(QWidget *parent)
: QDialog(parent)
: QDialog(parent),
server(new QLocalServer(this)),
hostLineEdit(new QLineEdit(u"fortune"_s)),
statusLabel(new QLabel(idleStateText)),
listenButton(new QPushButton(tr("Listen"))),
stopListeningButton(new QPushButton(tr("Stop Listening")))
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
server = new QLocalServer(this);
if (!server->listen("fortune")) {
QMessageBox::critical(this, tr("Local Fortune Server"),
tr("Unable to start the server: %1.")
.arg(server->errorString()));
close();
return;
}
QLabel *statusLabel = new QLabel;
statusLabel->setWordWrap(true);
statusLabel->setText(tr("The server is running.\n"
"Run the Local Fortune Client example now."));
stopListeningButton->setDisabled(true);
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
<< tr("You've got to think about tomorrow.")
@ -33,28 +39,71 @@ Server::Server(QWidget *parent)
<< tr("You cannot kill time without injuring eternity.")
<< tr("Computers are not intelligent. They only think they are.");
QLabel *hostLabel = new QLabel(tr("Server name:"));
connect(server, &QLocalServer::newConnection, this, &Server::sendFortune);
connect(hostLineEdit, &QLineEdit::textChanged, this, &Server::toggleListenButton);
connect(listenButton, &QPushButton::clicked, this, &Server::listenToServer);
connect(stopListeningButton, &QPushButton::clicked,this, &Server::stopListening);
QPushButton *quitButton = new QPushButton(tr("Quit"));
quitButton->setAutoDefault(false);
connect(quitButton, &QPushButton::clicked, this, &Server::close);
connect(server, &QLocalServer::newConnection, this, &Server::sendFortune);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(quitButton);
buttonLayout->addStretch(1);
QDialogButtonBox *buttonBox = new QDialogButtonBox;
buttonBox->addButton(listenButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(stopListeningButton, QDialogButtonBox::ActionRole);
buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->addWidget(statusLabel);
mainLayout->addLayout(buttonLayout);
QGridLayout *mainLayout = new QGridLayout(this);
mainLayout->addWidget(hostLabel, 0, 0);
mainLayout->addWidget(hostLineEdit, 0, 1);
mainLayout->addWidget(statusLabel, 2, 0, 3, 2);
mainLayout->addWidget(buttonBox, 10, 0, 2, 2);
setWindowTitle(QGuiApplication::applicationDisplayName());
hostLineEdit->setFocus();
}
void Server::listenToServer()
{
name = hostLineEdit->text();
if (!server->listen(name)) {
QMessageBox::critical(this, tr("Local Fortune Server"),
tr("Unable to start the server: %1.")
.arg(server->errorString()));
name.clear();
return;
}
statusLabel->setText(tr("The server is running.\n"
"Run the Local Fortune Client example now."));
toggleListenButton();
}
void Server::stopListening()
{
server->close();
name.clear();
statusLabel->setText(idleStateText);
toggleListenButton();
}
void Server::toggleListenButton()
{
if (server->isListening()) {
listenButton->setDisabled(true);
stopListeningButton->setEnabled(true);
} else {
listenButton->setEnabled(!hostLineEdit->text().isEmpty());
stopListeningButton->setDisabled(true);
}
}
void Server::sendFortune()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_5_10);
out.setVersion(QDataStream::Qt_6_0);
const int fortuneIndex = QRandomGenerator::global()->bounded(0, fortunes.size());
const QString &message = fortunes.at(fortuneIndex);
out << quint32(message.size());

View File

@ -4,27 +4,33 @@
#ifndef SERVER_H
#define SERVER_H
#include <QApplication>
#include <QDialog>
QT_BEGIN_NAMESPACE
class QLabel;
class QPushButton;
class QLocalServer;
QT_END_NAMESPACE
#include <QLabel>
#include <QLineEdit>
#include <QLocalServer>
#include <QPushButton>
class Server : public QDialog
{
Q_OBJECT
Q_DECLARE_TR_FUNCTIONS(Server)
public:
explicit Server(QWidget *parent = nullptr);
private slots:
void sendFortune();
private:
void sendFortune();
void toggleListenButton();
void listenToServer();
void stopListening();
QLocalServer *server;
QLineEdit *hostLineEdit;
QLabel *statusLabel;
QPushButton *listenButton;
QPushButton *stopListeningButton;
QStringList fortunes;
QString name;
};
#endif

View File

@ -2,8 +2,12 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "dialog.h"
#include <QFileDialog>
#include <QBuffer>
#include <QFileDialog>
#include <QNativeIpcKey>
using namespace Qt::StringLiterals;
/*!
\class Dialog
@ -29,8 +33,9 @@
each button.
*/
//! [0]
Dialog::Dialog(QWidget *parent)
: QDialog(parent), sharedMemory("QSharedMemoryExample")
: QDialog(parent), sharedMemory(QNativeIpcKey(u"QSharedMemoryExample"_s))
{
ui.setupUi(this);
connect(ui.loadFromFileButton, &QPushButton::clicked,

View File

@ -6,6 +6,7 @@
#include <QDialog>
#include <QSharedMemory>
#include "ui_dialog.h"
//! [0]
@ -13,21 +14,21 @@ class Dialog : public QDialog
{
Q_OBJECT
public:
public:
Dialog(QWidget *parent = nullptr);
public slots:
public slots:
void loadFromFile();
void loadFromMemory();
private:
private:
void detach();
private:
private:
Ui::Dialog ui;
QSharedMemory sharedMemory;
};
//! [0]
#endif
#endif // DIALOG_H

View File

@ -1,9 +1,10 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include "dialog.h"
#include <QApplication>
//! [0]
int main(int argc, char *argv[])
{

View File

@ -3,8 +3,9 @@
/*!
\example mimetypes/mimetypebrowser
\examplecategory {Data Processing & I/O}
\ingroup examples-mimetype
\title MIME Type Browser Example
\title MIME Type Browser
\brief Shows the hierarchy of MIME types and
can be used to determine the MIME type of a file.

View File

@ -4,10 +4,8 @@
#include "mainwindow.h"
#include <QApplication>
#include <QScreen>
#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QScreen>
int main(int argc, char *argv[])
{

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