summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmake/QtFlagHandlingHelpers.cmake84
-rw-r--r--cmake/QtModuleHelpers.cmake8
-rw-r--r--cmake/QtPublicAndroidHelpers.cmake2
-rw-r--r--cmake/QtTargetHelpers.cmake58
-rw-r--r--cmake/QtToolHelpers.cmake3
-rw-r--r--configure.cmake4
-rw-r--r--mkspecs/android-clang/qmake.conf2
-rw-r--r--mkspecs/features/android/sdk.prf2
-rw-r--r--qmake/doc/src/qmake-manual.qdoc2
-rw-r--r--qt_cmdline.cmake2
-rw-r--r--src/android/jar/build.gradle2
-rw-r--r--src/corelib/Qt6AndroidGradleHelpers.cmake2
-rw-r--r--src/corelib/doc/images/modelindex-no-parent.svg99
-rw-r--r--src/corelib/doc/src/cmake/cmake-properties.qdoc4
-rw-r--r--src/corelib/itemmodels/qabstractitemmodel.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm.cpp12
-rw-r--r--src/corelib/kernel/qeventdispatcher_wasm_p.h2
-rw-r--r--src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp7
-rw-r--r--src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h10
-rw-r--r--src/network/android/jar/build.gradle2
-rw-r--r--src/plugins/networkinformation/android/jar/build.gradle2
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm17
-rw-r--r--src/tools/androiddeployqt/main.cpp2
-rw-r--r--src/tools/bootstrap/CMakeLists.txt4
-rw-r--r--src/tools/rcc/rcc.cpp93
-rw-r--r--src/widgets/kernel/qapplication.cpp13
-rw-r--r--src/widgets/styles/qfusionstyle_p_p.h3
-rw-r--r--tests/auto/corelib/platform/android/tst_android.cpp10
-rw-r--r--tests/auto/other/android/deployment_settings/CMakeLists.txt11
-rw-r--r--tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp4
-rw-r--r--tests/auto/tools/rcc/data/deduplication/deduplication.expected157
-rw-r--r--tests/auto/tools/rcc/data/deduplication/deduplication.qrc10
-rw-r--r--tests/auto/tools/rcc/data/deduplication/files/a.txt1
-rw-r--r--tests/auto/tools/rcc/data/deduplication/files/b.txt1
-rw-r--r--tests/auto/tools/rcc/data/deduplication/files/c_with_a_content.txt1
-rw-r--r--tests/auto/tools/rcc/tst_rcc.cpp5
36 files changed, 595 insertions, 48 deletions
diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake
index b32acc4cfa3..8d616cebd2c 100644
--- a/cmake/QtFlagHandlingHelpers.cmake
+++ b/cmake/QtFlagHandlingHelpers.cmake
@@ -1495,3 +1495,87 @@ function(qt_internal_set_up_config_optimizations_like_in_qmake)
"${target_link_types}")
endif()
endfunction()
+
+# Adds optimized flags to targets created in the calling directory scope.
+# This is the only way to add release flags in a debug build, which would build successfully.
+# The approach of just appending -O3, and thus overriding any previous -O0 works on GCC / Clang
+# but not MSVC, because MSVC has other debug flags which are not compatible when -Ox optimizations
+# are turned on.
+function(qt_internal_add_optimized_flags_for_debug_config_in_current_scope)
+ qt_internal_remove_known_optimization_flags(CONFIGS DEBUG)
+
+ # Remove incompatible Windows debug flags with release flags.
+ if(MSVC)
+ set(default_debug_flags_to_remove "/RTC1")
+
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ foreach(lang ${enabled_languages})
+ set(flag_var_name "CMAKE_${lang}_FLAGS_DEBUG")
+ qt_internal_remove_flags_impl(${flag_var_name} "${default_debug_flags_to_remove}" "")
+ endforeach()
+ endif()
+
+ qt_internal_get_optimize_full_flags(optimize_full_flags)
+ qt_internal_add_compiler_flags(FLAGS "${optimize_full_flags}" CONFIGS DEBUG)
+
+ # Set the flags in the parent scope. This will apply the flags to all targets within
+ # that directory scope.
+ qt_internal_set_optimized_flags_for_debug_config_in_parent_scope()
+endfunction()
+
+# Conditionally adds optimized flags to the calling directory scope, depending on whether
+# the QT_FEATURE_optimized_tools is ON, and whether a target or project specific override was not
+# set.
+# Overrides can be set via:
+# -DQT_FORCE_NO_OPTIMIZE_<target>=ON
+# -DQT_FORCE_NO_OPTIMIZE_<project_name>=ON
+# e.g -DQT_FORCE_NO_OPTIMIZE_moc=ON -DQT_FORCE_NO_OPTIMIZE_qtdeclarative=ON
+function(qt_internal_add_target_optimized_flags_for_debug_config_in_current_scope target)
+ set(opt_args "")
+ set(single_args
+ OUT_VAR_DID_ADD
+ )
+ set(multi_args "")
+
+ cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ string(TOLOWER "${PROJECT_NAME}" project_name_lower)
+
+ if(QT_FEATURE_optimized_tools
+ AND NOT QT_FORCE_NO_OPTIMIZE_${target}
+ AND NOT QT_FORCE_NO_OPTIMIZE_${project_name_lower}
+ )
+ qt_internal_add_optimized_flags_for_debug_config_in_current_scope()
+ qt_internal_set_optimized_flags_for_debug_config_in_parent_scope()
+ set(did_add TRUE)
+ else()
+ set(did_add FALSE)
+ endif()
+
+ if(arg_OUT_VAR_DID_ADD)
+ set(${arg_OUT_VAR_DID_ADD} "${did_add}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Helper to propagate the optimized flags for the debug config to the parent scope.
+macro(qt_internal_set_optimized_flags_for_debug_config_in_parent_scope)
+ qt_internal_get_enabled_languages_for_flag_manipulation(__qt_internal_debug_enabled_languages)
+ foreach(__qt_internal_debug_lang IN LISTS __qt_internal_debug_enabled_languages)
+ set(flag_var_name "CMAKE_${__qt_internal_debug_lang}_FLAGS_DEBUG")
+ set(${flag_var_name} "${${flag_var_name}}" PARENT_SCOPE)
+ endforeach()
+ unset(__qt_internal_debug_lang)
+ unset(__qt_internal_debug_enabled_languages)
+endmacro()
+
+# Same as qt_internal_add_target_optimized_flags_for_debug_config_in_current_scope, but also
+# propagates the optimized flags to the parent scope.
+macro(qt_internal_add_target_optimized_flags_for_debug_config_in_parent_scope target)
+ qt_internal_add_target_optimized_flags_for_debug_config_in_current_scope("${target}"
+ OUT_VAR_DID_ADD __qt_internal_did_add_optimized_flag_in_current_scope)
+ if(__qt_internal_did_add_optimized_flag_in_current_scope)
+ qt_internal_set_optimized_flags_for_debug_config_in_parent_scope()
+ endif()
+ unset(__qt_internal_did_add_optimized_flag_in_current_scope)
+endmacro()
diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake
index b8c9914aba5..358cdadc59c 100644
--- a/cmake/QtModuleHelpers.cmake
+++ b/cmake/QtModuleHelpers.cmake
@@ -326,13 +326,7 @@ function(qt_internal_add_module target)
endif()
endif()
- if((FEATURE_ltcg OR CMAKE_INTERPROCEDURAL_OPTIMIZATION) AND GCC AND is_static_lib)
- # CMake <= 3.19 appends -fno-fat-lto-objects for all library types if
- # CMAKE_INTERPROCEDURAL_OPTIMIZATION is enabled. Static libraries need
- # the opposite compiler option.
- # (https://gitlab.kitware.com/cmake/cmake/-/issues/21696)
- target_compile_options(${target} PRIVATE -ffat-lto-objects)
- endif()
+ qt_internal_workaround_static_lib_gcc_lto_issue("${target}")
qt_internal_add_target_aliases("${target}")
diff --git a/cmake/QtPublicAndroidHelpers.cmake b/cmake/QtPublicAndroidHelpers.cmake
index 30ffec43ad8..dbaf01f0359 100644
--- a/cmake/QtPublicAndroidHelpers.cmake
+++ b/cmake/QtPublicAndroidHelpers.cmake
@@ -67,7 +67,7 @@ function(_qt_internal_locate_android_jar)
# This variable specifies the API level used for building Java code, it can be the same as Qt
# for Android's maximum supported Android version or higher.
if(NOT QT_ANDROID_API_USED_FOR_JAVA)
- set(QT_ANDROID_API_USED_FOR_JAVA "android-35")
+ set(QT_ANDROID_API_USED_FOR_JAVA "android-36")
endif()
set(jar_location "${ANDROID_SDK_ROOT}/platforms/${QT_ANDROID_API_USED_FOR_JAVA}/android.jar")
diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake
index da210820bb2..10d60807212 100644
--- a/cmake/QtTargetHelpers.cmake
+++ b/cmake/QtTargetHelpers.cmake
@@ -2023,3 +2023,61 @@ function(qt_internal_apply_dynamic_list_linker_flags target dynlist_template)
target_link_options(${target} PRIVATE "LINKER:--dynamic-list=${dynlist_file_abspath}")
endfunction()
+
+function(qt_internal_workaround_static_lib_gcc_lto_issue target)
+ get_target_property(target_type "${target}" TYPE)
+ get_target_property(target_lto_enabled "${target}" INTERPROCEDURAL_OPTIMIZATION)
+ get_target_property(target_lto_enabled_debug "${target}" INTERPROCEDURAL_OPTIMIZATION_DEBUG)
+ set(target_lto_enabled_debug_unset FALSE)
+
+ if(target_lto_enabled_debug MATCHES "-NOTFOUND")
+ set(target_lto_enabled_debug_unset TRUE)
+ endif()
+
+ set(general_lto_enabled FALSE)
+
+ if(FEATURE_ltcg
+ OR QT_FEATURE_ltcg
+ OR CMAKE_INTERPROCEDURAL_OPTIMIZATION
+ OR target_lto_enabled)
+ set(general_lto_enabled TRUE)
+ endif()
+
+ if((general_lto_enabled OR target_lto_enabled_debug)
+ AND GCC
+ AND target_type STREQUAL "STATIC_LIBRARY")
+ # CMake <= 3.19 appends -fno-fat-lto-objects for all library types if
+ # CMAKE_INTERPROCEDURAL_OPTIMIZATION is enabled. Static libraries need
+ # the opposite compiler option.
+ # (https://gitlab.kitware.com/cmake/cmake/-/issues/21696)
+ set(flag_name -ffat-lto-objects)
+
+ if((general_lto_enabled AND target_lto_enabled_debug_unset)
+ OR (general_lto_enabled AND target_lto_enabled)
+ )
+ set(flag_wrapped "${flag_name}")
+ elseif(general_lto_enabled AND NOT target_lto_enabled_debug)
+ set(flag_wrapped "$<$<NOT:$<CONFIG:Debug>>:${flag_name}>")
+ elseif(target_lto_enabled_debug)
+ set(flag_wrapped "$<$<CONFIG:Debug>:${flag_name}>")
+ endif()
+
+ target_compile_options("${target}" PRIVATE "${flag_wrapped}")
+ endif()
+endfunction()
+
+# Enable LTO for the debug configuration of optimized tool or library targets.
+# Can be opted out via various options.
+function(qt_internal_enable_optimized_tools_lto target)
+ string(TOLOWER "${PROJECT_NAME}" project_name_lower)
+
+ if(QT_FEATURE_optimized_tools
+ AND NOT QT_FORCE_NO_OPTIMIZED_TOOLS_LTO
+ AND NOT QT_FORCE_NO_OPTIMIZE_${target}
+ AND NOT QT_FORCE_NO_OPTIMIZE_${project_name_lower}
+ AND NOT QT_FORCE_NO_LTO_${target}
+ AND NOT QT_FORCE_NO_LTO_${project_name_lower}
+ )
+ set_target_properties("${target}" PROPERTIES INTERPROCEDURAL_OPTIMIZATION_DEBUG ON)
+ endif()
+endfunction()
diff --git a/cmake/QtToolHelpers.cmake b/cmake/QtToolHelpers.cmake
index 5d531818ebd..16743dcd9eb 100644
--- a/cmake/QtToolHelpers.cmake
+++ b/cmake/QtToolHelpers.cmake
@@ -292,6 +292,9 @@ function(qt_internal_add_tool target_name)
)
qt_internal_install_pdb_files(${target_name} "${install_dir}")
+ qt_internal_add_target_optimized_flags_for_debug_config_in_parent_scope("${target_name}")
+ qt_internal_enable_optimized_tools_lto("${target_name}")
+
if(QT_GENERATE_SBOM)
_qt_internal_forward_function_args(
FORWARD_APPEND
diff --git a/configure.cmake b/configure.cmake
index 0d4e5b04688..efec5435f85 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -588,6 +588,10 @@ qt_feature("optimize_full"
AUTODETECT OFF
)
qt_feature_config("optimize_full" QMAKE_PRIVATE_CONFIG)
+qt_feature("optimized_tools" PRIVATE
+ LABEL "Build optimized tools for the Debug configuration"
+ AUTODETECT OFF
+)
qt_feature("msvc_obj_debug_info"
LABEL "Embed debug info in object files (MSVC)"
ENABLE QT_USE_CCACHE OR CMAKE_CXX_COMPILER_LAUNCHER
diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf
index dd3b6a1d88c..47c0b88e9fc 100644
--- a/mkspecs/android-clang/qmake.conf
+++ b/mkspecs/android-clang/qmake.conf
@@ -44,7 +44,7 @@ isEmpty(ALL_ANDROID_ABIS): ALL_ANDROID_ABIS = arm64-v8a armeabi-v7a x86_64 x86
CONFIG += $$ANDROID_PLATFORM
ANDROID_MIN_SDK_VERSION = $$replace(ANDROID_PLATFORM, "android-", "")
-ANDROID_TARGET_SDK_VERSION = 35
+ANDROID_TARGET_SDK_VERSION = 36
NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST
QMAKE_CC = $$NDK_LLVM_PATH/bin/clang
diff --git a/mkspecs/features/android/sdk.prf b/mkspecs/features/android/sdk.prf
index 6fd1d666e02..39c557890af 100644
--- a/mkspecs/features/android/sdk.prf
+++ b/mkspecs/features/android/sdk.prf
@@ -1,6 +1,6 @@
ANDROID_API_USED_FOR_JAVA = $$(ANDROID_API_VERSION)
isEmpty(ANDROID_API_USED_FOR_JAVA): ANDROID_API_USED_FOR_JAVA = $$API_VERSION
-isEmpty(ANDROID_API_USED_FOR_JAVA): ANDROID_API_USED_FOR_JAVA = android-35
+isEmpty(ANDROID_API_USED_FOR_JAVA): ANDROID_API_USED_FOR_JAVA = android-36
ANDROID_JAR_FILE = $$ANDROID_SDK_ROOT/platforms/$$ANDROID_API_USED_FOR_JAVA/android.jar
!exists($$ANDROID_JAR_FILE) {
diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc
index c8595387b2e..6b8f2322cfc 100644
--- a/qmake/doc/src/qmake-manual.qdoc
+++ b/qmake/doc/src/qmake-manual.qdoc
@@ -1089,7 +1089,7 @@
\note This variable applies only to Android targets.
Specifies the target Android API level for the project. By default, this
- variable is set to API level 35.
+ variable is set to API level 36.
\section1 ANDROID_VERSION_CODE
diff --git a/qt_cmdline.cmake b/qt_cmdline.cmake
index 97a225d670d..132adeb8695 100644
--- a/qt_cmdline.cmake
+++ b/qt_cmdline.cmake
@@ -104,7 +104,7 @@ qt_commandline_option(opensource TYPE void NAME commercial VALUE no)
qt_commandline_option(optimize-debug TYPE boolean NAME optimize_debug)
qt_commandline_option(optimize-size TYPE boolean NAME optimize_size)
qt_commandline_option(optimized-qmake TYPE boolean NAME release_tools)
-qt_commandline_option(optimized-tools TYPE boolean NAME release_tools)
+qt_commandline_option(optimized-tools TYPE boolean NAME optimized_tools)
qt_commandline_option(pch TYPE boolean CMAKE_VARIABLE BUILD_WITH_PCH)
qt_commandline_option(pkg-config TYPE boolean)
qt_commandline_option(platform TYPE string CMAKE_VARIABLE QT_QMAKE_TARGET_MKSPEC)
diff --git a/src/android/jar/build.gradle b/src/android/jar/build.gradle
index 74ecff6b75f..54512f6f4b3 100644
--- a/src/android/jar/build.gradle
+++ b/src/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
namespace = "org.qtproject.qt.android"
defaultConfig {
diff --git a/src/corelib/Qt6AndroidGradleHelpers.cmake b/src/corelib/Qt6AndroidGradleHelpers.cmake
index f71bac4e08a..fc8e009b9da 100644
--- a/src/corelib/Qt6AndroidGradleHelpers.cmake
+++ b/src/corelib/Qt6AndroidGradleHelpers.cmake
@@ -193,7 +193,7 @@ function(_qt_internal_android_generate_target_build_gradle target)
QT_ANDROID_MIN_SDK_VERSION "28")
_qt_internal_android_get_gradle_property(target_sdk_version ${target}
- QT_ANDROID_TARGET_SDK_VERSION "34")
+ QT_ANDROID_TARGET_SDK_VERSION "36")
set(target_abis "$<TARGET_PROPERTY:${target},_qt_android_abis>")
set(target_abi_list "$<JOIN:${target_abis};${CMAKE_ANDROID_ARCH_ABI},'$<COMMA> '>")
diff --git a/src/corelib/doc/images/modelindex-no-parent.svg b/src/corelib/doc/images/modelindex-no-parent.svg
new file mode 100644
index 00000000000..4ce4b86b1f2
--- /dev/null
+++ b/src/corelib/doc/images/modelindex-no-parent.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="300"
+ height="160"
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .line-style { stroke: black; fill: none }
+ svg .fill-style { stroke: black; fill: #c0c0c0 }
+ svg .text-style { font: 12px arial; fill: black }
+ svg .italic-style { font: 12px arial; fill: black; font-style: italic }
+ svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+
+ svg.dark .line-style { stroke: #f2f2f2; fill: none }
+ svg.dark .fill-style { stroke: #f2f2f2; fill: #606060 }
+ svg.dark .text-style { font: 12px arial; fill: #f2f2f2 }
+ svg.dark .italic-style { font: 12px arial; fill: #f2f2f2; font-style: italic }
+ svg.dark .bold-style { font: 12px arial; fill: #f2f2f2; font-weight: bold }
+
+ [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none }
+ [data-theme="dark"] svg .fill-style { stroke: #f2f2f2; fill: #606060 }
+ [data-theme="dark"] svg .text-style { font: 12px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .italic-style { font: 12px arial; fill: #f2f2f2; font-style: italic }
+ [data-theme="dark"] svg .bold-style { font: 12px arial; fill: #f2f2f2; font-weight: bold }
+
+ [data-theme="light"] svg .line-style { stroke: black; fill: none }
+ [data-theme="light"] svg .fill-style { stroke: black; fill: #c0c0c0 }
+ [data-theme="light"] svg .text-style { font: 12px arial; fill: black }
+ [data-theme="light"] svg .italic-style { font: 12px arial; fill: black; font-style: italic }
+ [data-theme="light"] svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+</style>
+
+<text x="25" y="49" font-family="arial" font-size="12px"
+ class="text-style">0</text>
+<text x="25" y="79" font-family="arial" font-size="12px"
+ class="text-style">1</text>
+<text x="25" y="109" font-family="arial" font-size="12px"
+ class="text-style">2</text>
+<g transform="translate(30,139)">
+<text x="0" y="0" font-family="arial" font-size="12px"
+ class="text-style" transform="rotate(270)">...</text>
+</g>
+
+<path d="m 40.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,30.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 130.5,30.5 h 30 v 30" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="#c0c0c0"
+ class="fill-style" />
+<path d="m 130.5,60.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 100.5,90.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" />
+<path d="m 70.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 40.5,120.5 v 30 h 30" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 100.5,150.5 h 30" stroke="black"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 130.5,120.5 h 30 v 30 h -30 z" stroke="black" fill="none"
+ class="line-style" stroke-dasharray="3, 3" />
+<path d="m 160.5,90.5 v 30" stroke="black"
+ class="line-style" stroke-dasharray="3, 3" />
+
+<text x="50" y="20" font-family="arial" font-size="12px"
+ class="text-style">0</text>
+<text x="80" y="20" font-family="arial" font-size="12px"
+ class="text-style">1</text>
+<text x="110" y="20" font-family="arial" font-size="12px"
+ class="text-style">2</text>
+<text x="140" y="20" font-family="arial" font-size="12px"
+ class="text-style">...</text>
+
+<text x="190" y="55" font-family="arial" font-size="12px" font-weight="bold"
+ class="bold-style">Model index</text>
+<rect x="185.5" y="60.5" width="77" height="37" stroke="black" fill="none"
+ class="line-style" />
+<text x="190" y="75" font-family="arial" font-size="12px"
+ class="text-style">row = 1</text>
+<text x="190" y="92" font-family="arial" font-size="12px"
+ class="text-style">column = 2</text>
+
+<path d="m 185.5,85.5 c -35,0 -35,-10 -70,-10" stroke="black" fill="none"
+ stroke-dasharray="2, 2" class="line-style" />
+</svg>
diff --git a/src/corelib/doc/src/cmake/cmake-properties.qdoc b/src/corelib/doc/src/cmake/cmake-properties.qdoc
index c7b1a27a4b4..310debf7edc 100644
--- a/src/corelib/doc/src/cmake/cmake-properties.qdoc
+++ b/src/corelib/doc/src/cmake/cmake-properties.qdoc
@@ -239,7 +239,7 @@ precedence over this CMake property.
\badcode
set_target_properties(${target} PROPERTIES
- QT_ANDROID_COMPILE_SDK_VERSION 35
+ QT_ANDROID_COMPILE_SDK_VERSION 36
)
\endcode
@@ -247,7 +247,7 @@ The following format also works:
\badcode
set_target_properties(${target} PROPERTIES
- QT_ANDROID_COMPILE_SDK_VERSION "android-35"
+ QT_ANDROID_COMPILE_SDK_VERSION "android-36"
)
\endcode
diff --git a/src/corelib/itemmodels/qabstractitemmodel.cpp b/src/corelib/itemmodels/qabstractitemmodel.cpp
index 58a057009ff..8b0a05ee6ed 100644
--- a/src/corelib/itemmodels/qabstractitemmodel.cpp
+++ b/src/corelib/itemmodels/qabstractitemmodel.cpp
@@ -1390,7 +1390,7 @@ void QAbstractItemModel::resetInternalData()
simple table of rows and columns. Each item has a unique index specified by
a QModelIndex.
- \image modelindex-no-parent.png {Screenshot showing a 3x3 grid with numbered
+ \image modelindex-no-parent.svg {Diagram showing a 3x3 grid with numbered
rows and columns that shows the cell at row 1, column 2 highlighted.}
Every item of data that can be accessed via a model has an associated model
diff --git a/src/corelib/kernel/qeventdispatcher_wasm.cpp b/src/corelib/kernel/qeventdispatcher_wasm.cpp
index f7edf3285f8..25a27a0c22b 100644
--- a/src/corelib/kernel/qeventdispatcher_wasm.cpp
+++ b/src/corelib/kernel/qeventdispatcher_wasm.cpp
@@ -150,6 +150,18 @@ bool QEventDispatcherWasm::isValidEventDispatcherPointer(QEventDispatcherWasm *e
bool QEventDispatcherWasm::processEvents(QEventLoop::ProcessEventsFlags flags)
{
+ // Accept the current event if event handling recurses / event loop is reentered,
+ // to prevent the browser from propagating it to other event handlers.
+ if (useAsyncify() && isMainThreadEventDispatcher()) {
+ auto control = QWasmSuspendResumeControl::get();
+ auto currentEvent = control->currentEvent();
+ if (!currentEvent.isUndefined() && currentEvent.instanceof(emscripten::val::global("Event"))) {
+ currentEvent.call<void>("preventDefault");
+ currentEvent.call<void>("stopPropagation");
+ control->setCurrentEvent(emscripten::val::undefined());
+ }
+ }
+
emit awake();
if (!useAsyncify() && isMainThreadEventDispatcher())
diff --git a/src/corelib/kernel/qeventdispatcher_wasm_p.h b/src/corelib/kernel/qeventdispatcher_wasm_p.h
index 674af85dac2..1946bf63ede 100644
--- a/src/corelib/kernel/qeventdispatcher_wasm_p.h
+++ b/src/corelib/kernel/qeventdispatcher_wasm_p.h
@@ -40,7 +40,6 @@ public:
~QEventDispatcherWasm();
bool processEvents(QEventLoop::ProcessEventsFlags flags) override;
- bool sendAllEvents(QEventLoop::ProcessEventsFlags flag);
void registerTimer(Qt::TimerId timerId, Duration interval, Qt::TimerType timerType,
QObject *object) override final;
@@ -69,6 +68,7 @@ protected:
virtual bool sendPostedEvents();
private:
+ bool sendAllEvents(QEventLoop::ProcessEventsFlags flag);
bool isMainThreadEventDispatcher();
bool isSecondaryThreadEventDispatcher();
bool isValidEventDispatcher();
diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
index a4bc7843380..85358d1daf4 100644
--- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
+++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
@@ -225,8 +225,11 @@ int QWasmSuspendResumeControl::sendPendingEvents()
pendingEvents.call<void>("splice", i, 1);
auto it = m_eventHandlers.find(event["index"].as<int>());
- if (it != m_eventHandlers.end())
- it->second(event["arg"]);
+ if (it != m_eventHandlers.end()) {
+ setCurrentEvent(event["arg"]);
+ it->second(currentEvent());
+ setCurrentEvent(emscripten::val::undefined());
+ }
++count;
}
}
diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
index ff97ff3d7ea..4e75d5674be 100644
--- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
+++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
@@ -42,12 +42,22 @@ public:
void suspendExclusive(QList<uint32_t> eventHandlerIndices);
int sendPendingEvents();
+ emscripten::val currentEvent() const
+ {
+ return m_currentEvent;
+ }
+ void setCurrentEvent(emscripten::val currentEvent)
+ {
+ m_currentEvent = currentEvent;
+ }
+
private:
friend void qtSendPendingEvents();
static QWasmSuspendResumeControl *s_suspendResumeControl;
std::map<int, std::function<void(emscripten::val)>> m_eventHandlers;
std::function<bool(int)> m_eventFilter = [](int) { return true; };
+ emscripten::val m_currentEvent = emscripten::val::undefined();
};
class Q_CORE_EXPORT QWasmEventHandler
diff --git a/src/network/android/jar/build.gradle b/src/network/android/jar/build.gradle
index f1f470b6635..580e15b92f6 100644
--- a/src/network/android/jar/build.gradle
+++ b/src/network/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
defaultConfig {
minSdkVersion 28
diff --git a/src/plugins/networkinformation/android/jar/build.gradle b/src/plugins/networkinformation/android/jar/build.gradle
index f1f470b6635..580e15b92f6 100644
--- a/src/plugins/networkinformation/android/jar/build.gradle
+++ b/src/plugins/networkinformation/android/jar/build.gradle
@@ -23,7 +23,7 @@ repositories {
}
android {
- compileSdk 35
+ compileSdk 36
defaultConfig {
minSdkVersion 28
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index a6d96df0fbb..b00e6375e1a 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -269,6 +269,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSViewMenuHelper);
qCDebug(lcQpaWindow) << "Done moving" << self << "to" << self.window;
}
+// QWindow::setParent() promises that the child window will be clipped
+// to its parent, which we rely on in e.g. Qt Widgets when a native window
+// is added to a scroll area. We try to be smart and only enable clipping
+// if we have potential child QWindows that rely on this behavior.
+// FIXME: Be even smarter, and only consider QWindow based subviews,
+// in a way that also includes foreign windows.
+
+- (void)didAddSubview:(NSView *)subview
+{
+ self.clipsToBounds = YES;
+}
+
+- (void)willRemoveSubview:(NSView *)subview
+{
+ self.clipsToBounds = self.subviews.count > 1;
+}
+
// ----------------------------------------------------------------------------
- (QWindow *)topLevelWindow
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 7f24df7eac2..c4e7101b372 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -173,7 +173,7 @@ struct Options
QString versionName;
QString versionCode;
QByteArray minSdkVersion{"28"};
- QByteArray targetSdkVersion{"35"};
+ QByteArray targetSdkVersion{"36"};
// lib c++ path
QString stdCppPath;
diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt
index e6f920dcf32..c12475d69af 100644
--- a/src/tools/bootstrap/CMakeLists.txt
+++ b/src/tools/bootstrap/CMakeLists.txt
@@ -220,6 +220,10 @@ target_link_libraries(Bootstrap PRIVATE PlatformCommonInternal)
qt_internal_apply_gc_binaries(Bootstrap PUBLIC)
set_target_properties(Bootstrap PROPERTIES AUTOMOC OFF AUTOUIC OFF AUTORCC OFF)
qt_internal_add_target_aliases(Bootstrap)
+qt_internal_add_target_optimized_flags_for_debug_config_in_current_scope(Bootstrap)
+qt_internal_enable_optimized_tools_lto(Bootstrap)
+qt_internal_workaround_static_lib_gcc_lto_issue(Bootstrap)
+
qt_set_msvc_cplusplus_options(Bootstrap PUBLIC)
qt_set_common_target_properties(Bootstrap)
qt_internal_apply_intel_cet(Bootstrap PUBLIC)
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 40bfa9c2863..6a6027d44f2 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -1,10 +1,12 @@
// Copyright (C) 2018 The Qt Company Ltd.
// Copyright (C) 2018 Intel Corporation.
+// Copyright (C) 2024 Christoph Cullmann <christoph@cullmann.io>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "rcc.h"
#include <qbytearray.h>
+#include <qcryptographichash.h>
#include <qdatetime.h>
#include <qdebug.h>
#include <qdir.h>
@@ -90,8 +92,28 @@ public:
QString resourceName() const;
+ struct DeduplicationKey {
+ RCCResourceLibrary::CompressionAlgorithm compressAlgo;
+ int compressLevel;
+ int compressThreshold;
+ QByteArray hash;
+
+ bool operator==(const DeduplicationKey &other) const
+ {
+ return compressAlgo == other.compressAlgo &&
+ compressLevel == other.compressLevel &&
+ compressThreshold == other.compressThreshold &&
+ hash == other.hash;
+ }
+ };
+
+ typedef QMultiHash<DeduplicationKey, RCCFileInfo*> DeduplicationMultiHash;
+
public:
- qint64 writeDataBlob(RCCResourceLibrary &lib, qint64 offset, QString *errorMessage);
+ qint64 writeDataBlob(RCCResourceLibrary &lib,
+ qint64 offset,
+ DeduplicationMultiHash &dedupByContent,
+ QString *errorMessage);
qint64 writeDataName(RCCResourceLibrary &, qint64 offset);
void writeDataInfo(RCCResourceLibrary &lib);
@@ -114,6 +136,11 @@ public:
qint64 m_childOffset = 0;
};
+static size_t qHash(const RCCFileInfo::DeduplicationKey &key, size_t seed) noexcept
+{
+ return qHashMulti(seed, key.compressAlgo, key.compressLevel, key.compressThreshold, key.hash);
+}
+
RCCFileInfo::RCCFileInfo(const QString &name, const QFileInfo &fileInfo, QLocale::Language language,
QLocale::Territory territory, uint flags,
RCCResourceLibrary::CompressionAlgorithm compressAlgo, int compressLevel,
@@ -217,8 +244,10 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
}
}
-qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
- QString *errorMessage)
+qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib,
+ qint64 offset,
+ DeduplicationMultiHash &dedupByContent,
+ QString *errorMessage)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
@@ -230,24 +259,58 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
m_dataOffset = offset;
QByteArray data;
+ // determine compession algorithm & level early as used in de-duplication keys
+ // this avoid corruption for the two pass variants (QTBUG-137546)
+#if QT_CONFIG(zstd)
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best && !m_noZstd) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
+ m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
+ }
+#endif
+#ifndef QT_NO_COMPRESS
+ if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
+ m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib;
+ m_compressLevel = 9;
+ }
+#endif
+
if (!m_isEmpty) {
- //find the data to be written
- QFile file(m_fileInfo.absoluteFilePath());
+ // find the data to be written
+ const QString absoluteFilePath = m_fileInfo.absoluteFilePath();
+ QFile file(absoluteFilePath);
if (!file.open(QFile::ReadOnly)) {
- *errorMessage = msgOpenReadFailed(m_fileInfo.absoluteFilePath(), file.errorString());
+ *errorMessage = msgOpenReadFailed(absoluteFilePath, file.errorString());
return 0;
}
-
data = file.readAll();
+
+ // de-duplicate the same file content, we can re-use already written data
+ // we only do that if we have the same compression settings
+ const QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Sha256);
+ const DeduplicationKey key{m_compressAlgo, m_compressLevel, m_compressThreshold, hash};
+ const QList<RCCFileInfo *> potentialCandidates = dedupByContent.values(key);
+ for (const RCCFileInfo *candidate : potentialCandidates) {
+ // check real content, we can have collisions
+ QFile candidateFile(candidate->m_fileInfo.absoluteFilePath());
+ if (!candidateFile.open(QFile::ReadOnly)) {
+ *errorMessage = msgOpenReadFailed(candidate->m_fileInfo.absoluteFilePath(),
+ candidateFile.errorString());
+ return 0;
+ }
+ if (data != candidateFile.readAll())
+ continue;
+ // just remember the offset & flags with final compression state
+ // of the already written data and be done
+ m_dataOffset = candidate->m_dataOffset;
+ m_flags = candidate->m_flags;
+ return offset;
+ }
+ dedupByContent.insert(key, this);
}
// Check if compression is useful for this file
if (data.size() != 0) {
#if QT_CONFIG(zstd)
- if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best && !m_noZstd) {
- m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zstd;
- m_compressLevel = 19; // not ZSTD_maxCLevel(), as 20+ are experimental
- }
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zstd && !m_noZstd) {
if (lib.m_zstdCCtx == nullptr)
lib.m_zstdCCtx = ZSTD_createCCtx();
@@ -292,10 +355,6 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
}
#endif
#ifndef QT_NO_COMPRESS
- if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Best) {
- m_compressAlgo = RCCResourceLibrary::CompressionAlgorithm::Zlib;
- m_compressLevel = 9;
- }
if (m_compressAlgo == RCCResourceLibrary::CompressionAlgorithm::Zlib) {
QByteArray compressed =
qCompress(reinterpret_cast<uchar *>(data.data()), data.size(), m_compressLevel);
@@ -1168,6 +1227,7 @@ bool RCCResourceLibrary::writeDataBlobs()
QStack<RCCFileInfo*> pending;
pending.push(m_root);
qint64 offset = 0;
+ RCCFileInfo::DeduplicationMultiHash dedupByContent;
QString errorMessage;
while (!pending.isEmpty()) {
RCCFileInfo *file = pending.pop();
@@ -1176,7 +1236,8 @@ bool RCCResourceLibrary::writeDataBlobs()
if (child->m_flags & RCCFileInfo::Directory)
pending.push(child);
else {
- offset = child->writeDataBlob(*this, offset, &errorMessage);
+ offset = child->writeDataBlob(*this, offset,
+ dedupByContent, &errorMessage);
if (offset == 0) {
m_errorDevice->write(errorMessage.toUtf8());
return false;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index d2b0fb724ac..a735696adcb 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -3741,6 +3741,14 @@ void QApplicationPrivate::cleanupMultitouch_sys()
{
}
+/*! \internal
+ Check the target widgets of the active touchpoints of the given \a device,
+ and choose the widget that is closest to any of the points. This widget
+ will then get all the touchpoints, even if it would not otherwise be the
+ target for some of them.
+
+ \sa translateRawTouchEvent()
+*/
QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice *device, const QEventPoint &touchPoint)
{
const QPointF globalPos = touchPoint.globalPosition();
@@ -3754,7 +3762,10 @@ QWidget *QApplicationPrivate::findClosestTouchPointTarget(const QPointingDevice
qreal dx = globalPos.x() - pt.globalPosition().x();
qreal dy = globalPos.y() - pt.globalPosition().y();
qreal distance = dx * dx + dy * dy;
- if (closestTouchPointId == -1 || distance < closestDistance) {
+ // closestTouchPointId is -1 at the beginning.
+ // closestTouchPointId may be 0 if
+ // a synth-mouse eventPoint was found in activePoints: that's not relevant here.
+ if (closestTouchPointId <= 0 || distance < closestDistance) {
closestTouchPointId = pt.id();
closestDistance = distance;
closestTarget = QMutableEventPoint::target(pt);
diff --git a/src/widgets/styles/qfusionstyle_p_p.h b/src/widgets/styles/qfusionstyle_p_p.h
index dcb79f9e93c..821be49b2fa 100644
--- a/src/widgets/styles/qfusionstyle_p_p.h
+++ b/src/widgets/styles/qfusionstyle_p_p.h
@@ -94,7 +94,8 @@ public:
QColor buttonColor = pal.button().color();
int val = qGray(buttonColor.rgb());
buttonColor = buttonColor.lighter(100 + qMax(1, (180 - val)/6));
- buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75, buttonColor.value());
+ buttonColor.setHsv(buttonColor.hue(), buttonColor.saturation() * 0.75,
+ buttonColor.value(), buttonColor.alpha());
return buttonColor;
}
diff --git a/tests/auto/corelib/platform/android/tst_android.cpp b/tests/auto/corelib/platform/android/tst_android.cpp
index b4bb0323f8a..93d3f1102c9 100644
--- a/tests/auto/corelib/platform/android/tst_android.cpp
+++ b/tests/auto/corelib/platform/android/tst_android.cpp
@@ -251,6 +251,12 @@ void tst_Android::safeAreaWithWindowFlagsAndStates()
QFETCH(Qt::WindowStates, windowStates);
QFETCH(Qt::WindowFlags, windowFlags);
+ if ((QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_V__) &&
+ qgetenv("QTEST_ENVIRONMENT").split(' ').contains("ci") &
+ (!(windowFlags & Qt::ExpandedClientAreaHint) &&
+ !(windowStates & Qt::WindowFullScreen)))
+ QSKIP("Normal fails on Android 16 (QTBUG-140846).");
+
QWidget widget;
QPalette palette = widget.palette();
palette.setColor(QPalette::Window, Qt::red);
@@ -338,6 +344,10 @@ void tst_Android::safeAreaWithWindowFlagsAndStates()
// QTBUG-107604
void tst_Android::testFullScreenDimensions()
{
+ if ((QNativeInterface::QAndroidApplication::sdkVersion() > __ANDROID_API_V__) &&
+ qgetenv("QTEST_ENVIRONMENT").split(' ').contains("ci") )
+ QSKIP("Keep on failing on Android 16 (QTBUG-141712).");
+
QJniObject activity = QNativeInterface::QAndroidApplication::context();
QVERIFY(activity.isValid());
diff --git a/tests/auto/other/android/deployment_settings/CMakeLists.txt b/tests/auto/other/android/deployment_settings/CMakeLists.txt
index d4546c0ca94..ed373493f97 100644
--- a/tests/auto/other/android/deployment_settings/CMakeLists.txt
+++ b/tests/auto/other/android/deployment_settings/CMakeLists.txt
@@ -33,11 +33,11 @@ set_target_properties(${target} PROPERTIES
my_package_source_dir "path/to/source/dir"
my_libs_property "some/path/to/lib2.so;some/path/to/lib3.so"
my_plugins_property "some/path/to/plugin2.so;some/path/to/plugin3.so"
-
- QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2"
+ # Below build tools should match to minimum supported OS API level version
+ QT_ANDROID_SDK_BUILD_TOOLS_REVISION "28.0.3"
QT_ANDROID_MIN_SDK_VERSION "1"
QT_ANDROID_TARGET_SDK_VERSION "2"
- QT_ANDROID_COMPILE_SDK_VERSION "35"
+ QT_ANDROID_COMPILE_SDK_VERSION "36"
QT_ANDROID_APP_NAME "Android Deployment Settings Test"
QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test"
QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so"
@@ -62,10 +62,11 @@ qt6_policy(SET QTP0002 OLD)
set(target tst_android_deployment_settings_old)
qt6_add_executable(${target} MANUAL_FINALIZATION EXCLUDE_FROM_ALL noop.cpp)
set_target_properties(${target} PROPERTIES
- QT_ANDROID_SDK_BUILD_TOOLS_REVISION "23.0.2"
+ # Below build tools should match to minimum supported OS API level version
+ QT_ANDROID_SDK_BUILD_TOOLS_REVISION "28.0.3"
QT_ANDROID_MIN_SDK_VERSION "1"
QT_ANDROID_TARGET_SDK_VERSION "2"
- QT_ANDROID_COMPILE_SDK_VERSION "35"
+ QT_ANDROID_COMPILE_SDK_VERSION "36"
QT_ANDROID_APP_NAME "Android Deployment Settings Test"
QT_ANDROID_PACKAGE_NAME "org.qtproject.android_deployment_settings_test"
QT_ANDROID_DEPLOYMENT_DEPENDENCIES "dep1.so;dep2.so;dep3.so"
diff --git a/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp b/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
index 03724b7a225..6eed5506324 100644
--- a/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
+++ b/tests/auto/other/android/deployment_settings/tst_android_deployment_settings.cpp
@@ -60,7 +60,7 @@ void tst_android_deployment_settings::DeploymentSettings_data()
QTest::addColumn<QString>("value");
QTest::newRow("sdkBuildToolsRevision") << "sdkBuildToolsRevision"
- << "23.0.2";
+ << "28.0.3";
QTest::newRow("deployment-dependencies") << "deployment-dependencies"
<< "dep1.so,dep2.so,dep3.so";
QTest::newRow("android-extra-plugins")
@@ -78,7 +78,7 @@ void tst_android_deployment_settings::DeploymentSettings_data()
QTest::newRow("android-target-sdk-version") << "android-target-sdk-version"
<< "2";
QTest::newRow("android-compile-sdk-version") << "android-compile-sdk-version"
- << "35";
+ << "36";
QTest::newRow("android-package-name") << "android-package-name"
<< "org.qtproject.android_deployment_settings_test";
QTest::newRow("android-app-name") << "android-app-name"
diff --git a/tests/auto/tools/rcc/data/deduplication/deduplication.expected b/tests/auto/tools/rcc/data/deduplication/deduplication.expected
new file mode 100644
index 00000000000..bd873437b46
--- /dev/null
+++ b/tests/auto/tools/rcc/data/deduplication/deduplication.expected
@@ -0,0 +1,157 @@
+/****************************************************************************
+** Resource object code
+**
+IGNORE:** Created by: The Resource Compiler for Qt version 6.9.0
+**
+** WARNING! All changes made in this file will be lost!
+*****************************************************************************/
+
+#ifdef _MSC_VER
+// disable informational message "function ... selected for automatic inline expansion"
+#pragma warning (disable: 4711)
+#endif
+
+static const unsigned char qt_resource_data[] = {
+ // b.txt
+ 0x0,0x0,0x0,0xb,
+ 0x62,
+ 0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,
+ // c_with_a_content.txt
+ 0x0,0x0,0x0,0xb,
+ 0x61,
+ 0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,
+ // b.txt
+ 0x0,0x0,0x0,0xb,
+ 0x62,
+ 0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,
+
+};
+
+static const unsigned char qt_resource_name[] = {
+ // files
+ 0x0,0x5,
+ 0x0,0x6d,0x2,0xc3,
+ 0x0,0x66,
+ 0x0,0x69,0x0,0x6c,0x0,0x65,0x0,0x73,
+ // b.txt
+ 0x0,0x5,
+ 0x0,0x65,0x5b,0xf4,
+ 0x0,0x62,
+ 0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // c_with_a_content.txt
+ 0x0,0x14,
+ 0x1,0x61,0x1d,0x34,
+ 0x0,0x63,
+ 0x0,0x5f,0x0,0x77,0x0,0x69,0x0,0x74,0x0,0x68,0x0,0x5f,0x0,0x61,0x0,0x5f,0x0,0x63,0x0,0x6f,0x0,0x6e,0x0,0x74,0x0,0x65,0x0,0x6e,0x0,0x74,0x0,0x2e,
+ 0x0,0x74,0x0,0x78,0x0,0x74,
+ // a.txt
+ 0x0,0x5,
+ 0x0,0x64,0x5b,0xf4,
+ 0x0,0x61,
+ 0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // alias_of_b_compress9.txt
+ 0x0,0x18,
+ 0xb,0x26,0xf,0xb4,
+ 0x0,0x61,
+ 0x0,0x6c,0x0,0x69,0x0,0x61,0x0,0x73,0x0,0x5f,0x0,0x6f,0x0,0x66,0x0,0x5f,0x0,0x62,0x0,0x5f,0x0,0x63,0x0,0x6f,0x0,0x6d,0x0,0x70,0x0,0x72,0x0,0x65,
+ 0x0,0x73,0x0,0x73,0x0,0x39,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // alias_of_b.txt
+ 0x0,0xe,
+ 0x1,0xa4,0x6d,0x34,
+ 0x0,0x61,
+ 0x0,0x6c,0x0,0x69,0x0,0x61,0x0,0x73,0x0,0x5f,0x0,0x6f,0x0,0x66,0x0,0x5f,0x0,0x62,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+ // alias_of_b_compress9_dupe.txt
+ 0x0,0x1d,
+ 0x9,0x4,0x7a,0x14,
+ 0x0,0x61,
+ 0x0,0x6c,0x0,0x69,0x0,0x61,0x0,0x73,0x0,0x5f,0x0,0x6f,0x0,0x66,0x0,0x5f,0x0,0x62,0x0,0x5f,0x0,0x63,0x0,0x6f,0x0,0x6d,0x0,0x70,0x0,0x72,0x0,0x65,
+ 0x0,0x73,0x0,0x73,0x0,0x39,0x0,0x5f,0x0,0x64,0x0,0x75,0x0,0x70,0x0,0x65,0x0,0x2e,0x0,0x74,0x0,0x78,0x0,0x74,
+
+};
+
+static const unsigned char qt_resource_struct[] = {
+ // :
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/files
+ 0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x6,0x0,0x0,0x0,0x2,
+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
+ // :/files/a.txt
+ 0x0,0x0,0x0,0x4e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0xf,
+TIMESTAMP:files/a.txt
+ // :/files/b.txt
+ 0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:files/b.txt
+ // :/files/c_with_a_content.txt
+ 0x0,0x0,0x0,0x20,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0xf,
+TIMESTAMP:files/c_with_a_content.txt
+ // :/files/alias_of_b.txt
+ 0x0,0x0,0x0,0x94,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
+TIMESTAMP:files/b.txt
+ // :/files/alias_of_b_compress9_dupe.txt
+ 0x0,0x0,0x0,0xb6,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1e,
+TIMESTAMP:files/b.txt
+ // :/files/alias_of_b_compress9.txt
+ 0x0,0x0,0x0,0x5e,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1e,
+TIMESTAMP:files/b.txt
+
+};
+
+#ifdef QT_NAMESPACE
+# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
+# define QT_RCC_MANGLE_NAMESPACE0(x) x
+# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
+# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
+# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
+ QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
+#else
+# define QT_RCC_PREPEND_NAMESPACE(name) name
+# define QT_RCC_MANGLE_NAMESPACE(name) name
+#endif
+
+#if defined(QT_INLINE_NAMESPACE)
+inline namespace QT_NAMESPACE {
+#elif defined(QT_NAMESPACE)
+namespace QT_NAMESPACE {
+#endif
+
+bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
+
+#ifdef QT_NAMESPACE
+}
+#endif
+
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)();
+int QT_RCC_MANGLE_NAMESPACE(qInitResources)()
+{
+ int version = 3;
+ QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
+ (version, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)();
+int QT_RCC_MANGLE_NAMESPACE(qCleanupResources)()
+{
+ int version = 3;
+ QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
+ (version, qt_resource_struct, qt_resource_name, qt_resource_data);
+ return 1;
+}
+
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wexit-time-destructors"
+#endif
+
+namespace {
+ struct initializer {
+ initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources)(); }
+ ~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources)(); }
+ } dummy;
+}
+
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
diff --git a/tests/auto/tools/rcc/data/deduplication/deduplication.qrc b/tests/auto/tools/rcc/data/deduplication/deduplication.qrc
new file mode 100644
index 00000000000..fd8a776503e
--- /dev/null
+++ b/tests/auto/tools/rcc/data/deduplication/deduplication.qrc
@@ -0,0 +1,10 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>files/a.txt</file>
+ <file>files/b.txt</file>
+ <file alias="files/alias_of_b.txt">files/b.txt</file>
+ <file>files/c_with_a_content.txt</file>
+ <file alias="files/alias_of_b_compress9.txt" compress="9">files/b.txt</file>
+ <file alias="files/alias_of_b_compress9_dupe.txt" compress="9">files/b.txt</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/tools/rcc/data/deduplication/files/a.txt b/tests/auto/tools/rcc/data/deduplication/files/a.txt
new file mode 100644
index 00000000000..abd91bd4652
--- /dev/null
+++ b/tests/auto/tools/rcc/data/deduplication/files/a.txt
@@ -0,0 +1 @@
+a test file \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/deduplication/files/b.txt b/tests/auto/tools/rcc/data/deduplication/files/b.txt
new file mode 100644
index 00000000000..01e4d76fc57
--- /dev/null
+++ b/tests/auto/tools/rcc/data/deduplication/files/b.txt
@@ -0,0 +1 @@
+b test file \ No newline at end of file
diff --git a/tests/auto/tools/rcc/data/deduplication/files/c_with_a_content.txt b/tests/auto/tools/rcc/data/deduplication/files/c_with_a_content.txt
new file mode 100644
index 00000000000..abd91bd4652
--- /dev/null
+++ b/tests/auto/tools/rcc/data/deduplication/files/c_with_a_content.txt
@@ -0,0 +1 @@
+a test file \ No newline at end of file
diff --git a/tests/auto/tools/rcc/tst_rcc.cpp b/tests/auto/tools/rcc/tst_rcc.cpp
index f5edfbcaa51..ba7e5841185 100644
--- a/tests/auto/tools/rcc/tst_rcc.cpp
+++ b/tests/auto/tools/rcc/tst_rcc.cpp
@@ -152,6 +152,11 @@ void tst_rcc::rcc_data()
QTest::newRow("legal") << m_dataPath + QLatin1StringView("/legal")
<< "legal.qrc" << "rcc_legal.cpp";
+
+ if (sizeof(size_t) == 8) {
+ const QString deduplicationPath = m_dataPath + QLatin1String("/deduplication");
+ QTest::newRow("deduplication") << deduplicationPath << "deduplication.qrc" << "deduplication.expected";
+ }
}
static QStringList readLinesFromFile(const QString &fileName,