summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt10
-rw-r--r--cmake/QtBuildInternals/QtBuildInternalsConfig.cmake5
-rw-r--r--cmake/QtFindPackageHelpers.cmake4
-rw-r--r--cmake/QtFlagHandlingHelpers.cmake530
-rw-r--r--src/corelib/CMakeLists.txt5
-rw-r--r--src/gui/CMakeLists.txt5
-rw-r--r--src/winmain/CMakeLists.txt6
-rw-r--r--tests/CMakeLists.txt10
8 files changed, 514 insertions, 61 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b089814803..d0014b5363 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -83,6 +83,13 @@ if(NOT QT_BUILD_STANDALONE_TESTS)
# Needed when building qtbase for android.
include(src/corelib/Qt6AndroidMacros.cmake)
+ # Set up optimization flags like in qmake.
+ # This function must be called after the global QT_FEATURE_xxx variables have been set up,
+ # aka after QtBaseGlobalTargets is processed.
+ # It also has to be called /before/ adding add_subdirectory(src), so that per-directory
+ # modifications can still be applied if necessary (like in done in Core and Gui).
+ qt_internal_set_up_config_optimizations_like_in_qmake()
+
## Setup documentation
add_subdirectory(doc)
@@ -122,9 +129,6 @@ endif()
qt_build_repo_end()
-# This function must be called after the QT_FEATURE_xxx variables have been set up.
-qt_internal_set_up_config_optimizations_like_in_qmake()
-
if(NOT QT_BUILD_STANDALONE_TESTS AND BUILD_EXAMPLES)
add_subdirectory(examples)
if(QT_NO_MAKE_EXAMPLES)
diff --git a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
index 529b83ff73..84273b5e9e 100644
--- a/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
+++ b/cmake/QtBuildInternals/QtBuildInternalsConfig.cmake
@@ -201,6 +201,11 @@ macro(qt_enable_cmake_languages)
endif()
endforeach()
+ # The qtbase call is handled in qtbase/CMakeLists.txt.
+ # This call is used for projects other than qtbase, including for other project's standalone
+ # tests.
+ # Because the function uses QT_FEATURE_foo values, it's important that find_package(Qt6Core) is
+ # called before this function. but that's usually the case for Qt repos.
if(NOT PROJECT_NAME STREQUAL "QtBase")
qt_internal_set_up_config_optimizations_like_in_qmake()
endif()
diff --git a/cmake/QtFindPackageHelpers.cmake b/cmake/QtFindPackageHelpers.cmake
index c68ba4d14a..d2bacd48cc 100644
--- a/cmake/QtFindPackageHelpers.cmake
+++ b/cmake/QtFindPackageHelpers.cmake
@@ -57,6 +57,7 @@ macro(qt_find_package)
# Re-append components to forward them.
list(APPEND arg_UNPARSED_ARGUMENTS "COMPONENTS;${arg_COMPONENTS}")
endif()
+ # TODO: Handle REQUIRED_COMPONENTS.
# Don't look for packages in PATH if requested to.
if(QT_NO_USE_FIND_PACKAGE_SYSTEM_ENVIRONMENT_PATH)
@@ -97,6 +98,9 @@ macro(qt_find_package)
endif()
endforeach()
+ # TODO: Handle packages with components where a previous component is already found.
+ # E.g. find_package(Qt6 COMPONENTS BuildInternals) followed by
+ # qt_find_package(Qt6 COMPONENTS Core) doesn't end up calling find_package(Qt6Core).
if (NOT ${ARGV0}_FOUND AND NOT _qt_find_package_skip_find_package)
# Unset the NOTFOUND ${package}_DIR var that might have been set by the previous
# find_package call, to get rid of "not found" messagees in the feature summary
diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake
index a2b498bf20..db2790171d 100644
--- a/cmake/QtFlagHandlingHelpers.cmake
+++ b/cmake/QtFlagHandlingHelpers.cmake
@@ -245,6 +245,9 @@ function(qt_enable_utf8_sources target)
endif()
endfunction()
+# Saves the list of known optimization flags for the current compiler in out_var.
+#
+# Mostly used for removing them before adding new ones.
function(qt_internal_get_all_possible_optimization_flag_values out_var)
set(flag_values "")
set(vars QT_CFLAGS_OPTIMIZE QT_CFLAGS_OPTIMIZE_FULL
@@ -265,7 +268,35 @@ function(qt_internal_get_all_possible_optimization_flag_values out_var)
set("${out_var}" "${flag_values}" PARENT_SCOPE)
endfunction()
-function(qt_internal_print_optimization_flags_values languages configs target_link_types)
+# Return's the current compiler's optimize_full flags if available.
+# Otherwise returns the regular optimization level flag.
+function(qt_internal_get_optimize_full_flags out_var)
+ set(optimize_full_flags "${QT_CFLAGS_OPTIMIZE_FULL}")
+ if(NOT optimize_full_flags)
+ set(optimize_full_flags "${QT_CFLAGS_OPTIMIZE}")
+ endif()
+ set(${out_var} "${optimize_full_flags}" PARENT_SCOPE)
+endfunction()
+
+# Prints the compiler and linker flags for each configuration, language and target type.
+#
+# Usually it would print the cache variables, but one may also override the variables
+# in a specific directory scope, so this is useful for debugging.
+#
+# Basically dumps either scoped or cached
+# CMAKE_<LANG>_FLAGS_CONFIG> and CMAKE_<TYPE>_LINKER_FLAGS_<CONFIG> variables.
+
+function(qt_internal_print_optimization_flags_values)
+ qt_internal_get_enabled_languages_for_flag_manipulation(languages)
+ qt_internal_get_configs_for_flag_manipulation(configs)
+ qt_internal_get_target_link_types_for_flag_manipulation(target_link_types)
+
+ qt_internal_print_optimization_flags_values_helper(
+ "${languages}" "${configs}" "${target_link_types}")
+endfunction()
+
+# Helper function for printing the optimization flags.
+function(qt_internal_print_optimization_flags_values_helper languages configs target_link_types)
foreach(lang ${languages})
set(flag_var_name "CMAKE_${lang}_FLAGS")
message(STATUS "${flag_var_name}: ${${flag_var_name}}")
@@ -287,17 +318,26 @@ function(qt_internal_print_optimization_flags_values languages configs target_li
endforeach()
endfunction()
-# This function finds the optimization flags set by the default CMake modules or toolchains, and
-# replaces them with ones that Qt qmake builds expect for all the default CMAKE_BUILD_TYPE
-# configurations.
-# This normalizes things like using -O2 for both Release and RelWithDebInfo, among other flags.
-# See QTBUG-85992 for details.
-function(qt_internal_set_up_config_optimizations_like_in_qmake)
- # Allow opt out.
- if(QT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS)
- return()
+# Saves the list of configs for which flag manipulation will occur.
+function(qt_internal_get_configs_for_flag_manipulation out_var)
+ set(configs RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
+
+ # Opt into additional non-standard configs for flag removal only.
+ if(QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS)
+ list(APPEND configs ${QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS})
endif()
+ set(${out_var} "${configs}" PARENT_SCOPE)
+endfunction()
+
+# Saves the list of target link types for which flag manipulation will occur.
+function(qt_internal_get_target_link_types_for_flag_manipulation out_var)
+ set(target_link_types EXE SHARED MODULE STATIC)
+ set(${out_var} "${target_link_types}" PARENT_SCOPE)
+endfunction()
+
+# Saves list of enabled languages for which it is safe to manipulate compilation flags.
+function(qt_internal_get_enabled_languages_for_flag_manipulation out_var)
# Limit flag modification to c-like code. We don't want to accidentally add incompatible
# flags to MSVC's RC or Swift.
set(languages_to_process C CXX OBJC OBJCXX)
@@ -308,70 +348,458 @@ function(qt_internal_set_up_config_optimizations_like_in_qmake)
list(APPEND enabled_languages "${lang}")
endif()
endforeach()
+ set(${out_var} "${enabled_languages}" PARENT_SCOPE)
+endfunction()
- set(configs RELEASE RELWITHDEBINFO MINSIZEREL DEBUG)
- set(target_link_types EXE SHARED MODULE STATIC)
-
- # Opt into additional non-standard configs for flag removal only.
- if(QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS)
- list(APPEND configs ${QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS})
+# Removes all known compiler optimization flags for the given CONFIGS, for all enabled 'safe'
+# languages.
+#
+# IN_CACHE - remove them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - remove them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# CONFIGS - should be a list of upper case configs like DEBUG, RELEASE, RELWITHDEBINFO.
+# LANGUAGES - optional list of languages like 'C', 'CXX', for which to remove the flags
+# if not provided, defaults to the list of enabled C-like languages
+function(qt_internal_remove_known_optimization_flags)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_remove_known_optimization_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ ""
+ "CONFIGS;LANGUAGES"
+ ${ARGN})
+
+ if(NOT arg_CONFIGS)
+ message(FATAL_ERROR
+ "You must specify at least one configuration for which to add the flags.")
endif()
- # You can set QT_DEBUG_OPTIMIZATION_FLAGS to see the before and after results.
- if(QT_DEBUG_OPTIMIZATION_FLAGS)
- message(STATUS "")
- message(STATUS "DEBUG: Original CMake optimization flags.\n")
- qt_internal_print_optimization_flags_values("${enabled_languages}" "${configs}"
- "${target_link_types}")
+ if(arg_LANGUAGES)
+ set(enabled_languages "${arg_LANGUAGES}")
+ else()
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
endif()
- # Remove known optimization flags.
qt_internal_get_all_possible_optimization_flag_values(flag_values)
+ set(configs ${arg_CONFIGS})
+
foreach(lang ${enabled_languages})
foreach(config ${configs})
set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
foreach(flag_value ${flag_values})
- # Remove any existing optimization flags, they will be re-added later on.
string(REPLACE "${flag_value}" "" "${flag_var_name}" "${${flag_var_name}}")
string(STRIP "${${flag_var_name}}" "${flag_var_name}")
endforeach()
+
+ if(arg_IN_CACHE)
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ elseif(arg_IN_CURRENT_SCOPE)
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ else()
+ message(
+ FATAL_ERROR
+ "qt_internal_remove_known_optimization_flags expects a scope argument.")
+ endif()
endforeach()
endforeach()
+endfunction()
+
+# Adds compiler flags for the given CONFIGS either in the current scope or globally in the
+# cache.
+#
+# FLAGS - should be a single string of flags separated by spaces.
+# IN_CACHE - add them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - add them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# CONFIGS - should be a list of upper case configs like DEBUG, RELEASE, RELWITHDEBINFO.
+# LANGUAGES - optional list of languages like 'C', 'CXX', for which to add the flags
+# if not provided, defaults to the list of enabled C-like languages
+function(qt_internal_add_compiler_flags)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_add_compiler_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ "FLAGS"
+ "CONFIGS;LANGUAGES"
+ ${ARGN})
+
+ if(NOT arg_CONFIGS)
+ message(FATAL_ERROR
+ "You must specify at least one configuration for which to add the flags.")
+ endif()
+ if(NOT arg_FLAGS)
+ message(FATAL_ERROR "You must specify at least one flag to add.")
+ endif()
+
+ if(arg_LANGUAGES)
+ set(enabled_languages "${arg_LANGUAGES}")
+ else()
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ endif()
+
+ set(configs ${arg_CONFIGS})
+
+ foreach(lang ${enabled_languages})
+ foreach(config ${configs})
+ set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
+ string(APPEND "${flag_var_name}" " ${arg_FLAGS}")
+
+ if(arg_IN_CACHE)
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ elseif(arg_IN_CURRENT_SCOPE)
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ else()
+ message(
+ FATAL_ERROR
+ "qt_internal_add_compiler_flags expects a scope argument.")
+ endif()
+ endforeach()
+ endforeach()
+endfunction()
+
+# Convenience function that adds compiler flags for all release configurations.
+#
+# FLAGS - should be a single string of flags separated by spaces.
+# IN_CACHE - add them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - add them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# LANGUAGES - optional list of languages like 'C', 'CXX', for which to add the flags
+# if not provided, defaults to the list of enabled C-like languages
+function(qt_internal_add_compiler_flags_for_release_configs)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_add_compiler_flags_for_release_configs"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ "FLAGS"
+ "LANGUAGES"
+ ${ARGN})
+
+ set(args "")
+
+ if(arg_LANGUAGES)
+ set(enabled_languages "${arg_LANGUAGES}")
+ else()
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ endif()
+
+ set(configs RELEASE RELWITHDEBINFO MINSIZEREL)
+
+ list(APPEND args CONFIGS ${configs})
+
+ if(arg_FLAGS)
+ list(APPEND args FLAGS "${arg_FLAGS}")
+ endif()
+
+ if(arg_IN_CACHE)
+ list(APPEND args IN_CACHE)
+ endif()
+ if(arg_IN_CURRENT_SCOPE)
+ list(APPEND args IN_CURRENT_SCOPE)
+ endif()
+ list(APPEND args LANGUAGES ${enabled_languages})
+
+ qt_internal_add_compiler_flags(${args})
+
+ if(arg_IN_CURRENT_SCOPE)
+ foreach(lang ${enabled_languages})
+ foreach(config ${configs})
+ set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ endforeach()
+ endforeach()
+ endif()
+endfunction()
+
+# Convenience function that replaces all optimization flags with the equivalent of '-O3'
+# (optimize_full) flag for all release configs.
+#
+# This is the equivalent of qmake's CONFIG += optimize_full.
+# It is meant to be called in a subdirectory scope to enable full optimizations for a particular
+# Qt module, like Core or Gui.
+function(qt_internal_add_optimize_full_flags)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_add_optimize_full_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ ""
+ ""
+ ${ARGN})
+
+ set(args "")
+ if(arg_IN_CACHE)
+ list(APPEND args IN_CACHE)
+ endif()
+ if(arg_IN_CURRENT_SCOPE)
+ list(APPEND args IN_CURRENT_SCOPE)
+ endif()
+
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ set(configs RELEASE RELWITHDEBINFO MINSIZEREL)
+
+ qt_internal_remove_known_optimization_flags(${args} CONFIGS ${configs})
+
+ # If the respective compiler doesn't have optimize_full flags, use regular optimization flags.
+ # Mainly MSVC.
+ qt_internal_get_optimize_full_flags(optimize_full_flags)
+ list(APPEND args FLAGS "${optimize_full_flags}")
+
+ qt_internal_add_compiler_flags_for_release_configs(${args})
+
+ if(arg_IN_CURRENT_SCOPE)
+ foreach(lang ${enabled_languages})
+ foreach(config ${configs})
+ set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ endforeach()
+ endforeach()
+ endif()
+endfunction()
+
+# Convenience function to replace a compiler flag with another one, for the given configurations
+# for all enabled 'safe' languages.
+# Essentially a glorified string(REPLACE).
+# Can be used to remove compiler flags.
+#
+# match_string - string to match
+# replace_string - replacement string
+# IN_CACHE - replace them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - replace them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# CONFIGS - should be a list of upper case configs like DEBUG, RELEASE, RELWITHDEBINFO.
+# LANGUAGES - optional list of languages like 'C', 'CXX', for which to replace the flags
+# if not provided, defaults to the list of enabled C-like languages
+function(qt_internal_replace_compiler_flags match_string replace_string)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_replace_compiler_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ ""
+ "CONFIGS;LANGUAGES"
+ ${ARGN})
+
+ if(NOT arg_CONFIGS)
+ message(FATAL_ERROR
+ "You must specify at least one configuration for which to replace the flags.")
+ endif()
+
+ if(arg_LANGUAGES)
+ set(enabled_languages "${arg_LANGUAGES}")
+ else()
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ endif()
+ set(configs ${arg_CONFIGS})
+
+ foreach(lang ${enabled_languages})
+ foreach(config ${configs})
+ set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
+
+ # Handle an empty input string and an empty match string as a set().
+ if(match_string STREQUAL "" AND "${${flag_var_name}}" STREQUAL "")
+ set(${flag_var_name} "${replace_string}")
+ else()
+ string(REPLACE
+ "${match_string}" "${replace_string}"
+ "${flag_var_name}" "${${flag_var_name}}")
+ endif()
+
+ if(arg_IN_CACHE)
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ elseif(arg_IN_CURRENT_SCOPE)
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ else()
+ message(
+ FATAL_ERROR
+ "qt_internal_replace_compiler_flags expects a scope argument.")
+ endif()
+ endforeach()
+ endforeach()
+endfunction()
+
+# Convenience function to add linker flags, for the given configurations and target link types.
+#
+# FLAGS - should be a single string of flags separated by spaces.
+# IN_CACHE - add them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - add them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# CONFIGS - should be a list of upper case configs like DEBUG, RELEASE, RELWITHDEBINFO.
+# TYPES - should be a list of target link types as expected by CMake's
+# CMAKE_<LINKER_TYPE>_LINKER_FLAGS_<CONFIG> cache variable.
+# e.g EXE, MODULE, SHARED, STATIC.
+function(qt_internal_add_linker_flags)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_add_linker_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ "FLAGS"
+ "CONFIGS;TYPES"
+ ${ARGN})
+
+ if(NOT arg_TYPES)
+ message(FATAL_ERROR
+ "You must specify at least one linker target type for which to add the flags.")
+ endif()
+ if(NOT arg_CONFIGS)
+ message(FATAL_ERROR
+ "You must specify at least one configuration for which to add the flags.")
+ endif()
+ if(NOT arg_FLAGS)
+ message(FATAL_ERROR "You must specify at least one flag to add.")
+ endif()
+
+ set(configs ${arg_CONFIGS})
+ set(target_link_types ${arg_TYPES})
+
+ foreach(config ${configs})
+ foreach(t ${target_link_types})
+ set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
+ string(APPEND "${flag_var_name}" " ${arg_FLAGS}")
+
+ if(arg_IN_CACHE)
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ elseif(arg_IN_CURRENT_SCOPE)
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ else()
+ message(
+ FATAL_ERROR
+ "qt_internal_add_linker_flags expects a scope argument.")
+ endif()
+ endforeach()
+ endforeach()
+endfunction()
+
+# Convenience function to replace a linker flag with another one, for the given configurations
+# and target link types.
+# Essentially a glorified string(REPLACE).
+# Can be used to remove linker flags.
+#
+# match_string - string to match
+# replace_string - replacement string
+# IN_CACHE - replace them globally (aka in the corresponding cache entries)
+# IN_CURRENT_SCOPE - replace them only in the current directory scope (effectively setting them,
+# if they did not exist beforehand)
+# CONFIGS - should be a list of upper case configs like DEBUG, RELEASE, RELWITHDEBINFO.
+# TYPES - should be a list of target link types as expected by CMake's
+# CMAKE_<LINKER_TYPE>_LINKER_FLAGS_<CONFIG> cache variable.
+# e.g EXE, MODULE, SHARED, STATIC.
+function(qt_internal_replace_linker_flags match_string replace_string)
+ qt_parse_all_arguments(
+ arg
+ "qt_internal_replace_compiler_flags"
+ "IN_CACHE;IN_CURRENT_SCOPE"
+ ""
+ "CONFIGS;TYPES"
+ ${ARGN})
+
+ if(NOT arg_TYPES)
+ message(FATAL_ERROR
+ "You must specify at least one linker target type for which to replace the flags.")
+ endif()
+ if(NOT arg_CONFIGS)
+ message(FATAL_ERROR
+ "You must specify at least one configuration for which to replace the flags.")
+ endif()
+
+ set(configs ${arg_CONFIGS})
+ set(target_link_types ${arg_TYPES})
+
+ foreach(config ${configs})
+ foreach(t ${target_link_types})
+ set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
+
+ # Handle an empty input string and an empty match string as a set().
+ if(match_string STREQUAL "" AND "${${flag_var_name}}" STREQUAL "")
+ set(${flag_var_name} "${replace_string}")
+ else()
+ string(REPLACE
+ "${match_string}" "${replace_string}"
+ "${flag_var_name}" "${${flag_var_name}}")
+ endif()
+
+ if(arg_IN_CACHE)
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ elseif(arg_IN_CURRENT_SCOPE)
+ set("${flag_var_name}" "${${flag_var_name}}" PARENT_SCOPE)
+ else()
+ message(
+ FATAL_ERROR
+ "qt_internal_replace_compiler_flags expects a scope argument.")
+ endif()
+ endforeach()
+ endforeach()
+endfunction()
+
+# This function finds the optimization flags set by the default CMake platform modules or toolchain
+# files and replaces them with flags that Qt qmake builds expect, for all the usual
+# CMAKE_BUILD_TYPE configurations.
+# This normalizes things like using -O2 for both Release and RelWithDebInfo, among other compilation
+# flags. Also some linker flags specific to MSVC.
+# See QTBUG-85992 for details.
+function(qt_internal_set_up_config_optimizations_like_in_qmake)
+ # Allow opt out.
+ if(QT_USE_DEFAULT_CMAKE_OPTIMIZATION_FLAGS)
+ return()
+ endif()
+
+ qt_internal_get_enabled_languages_for_flag_manipulation(enabled_languages)
+ qt_internal_get_configs_for_flag_manipulation(configs)
+ qt_internal_get_target_link_types_for_flag_manipulation(target_link_types)
+
+ # You can set QT_DEBUG_OPTIMIZATION_FLAGS to see the before and after results.
+ set(QT_DEBUG_OPTIMIZATION_FLAGS TRUE)
+ if(QT_DEBUG_OPTIMIZATION_FLAGS)
+ message(STATUS "")
+ message(STATUS "DEBUG: Original CMake optimization flags.\n")
+ qt_internal_print_optimization_flags_values_helper("${enabled_languages}" "${configs}"
+ "${target_link_types}")
+ endif()
+
+ # Remove known optimization flags.
+ qt_internal_remove_known_optimization_flags(IN_CACHE CONFIGS ${configs})
# Re-add optimization flags as per qmake mkspecs.
foreach(lang ${enabled_languages})
foreach(config ${configs})
set(flag_var_name "CMAKE_${lang}_FLAGS_${config}")
+ set(value_to_append "")
# Release and RelWithDebInfo should get the same base optimization flags.
if(config STREQUAL "RELEASE" AND QT_CFLAGS_OPTIMIZE)
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE}")
elseif(config STREQUAL "RELWITHDEBINFO" AND QT_CFLAGS_OPTIMIZE)
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE}")
# MinSizeRel should get the optimize size flag if available, otherwise the regular
# release flag.
elseif(config STREQUAL "MINSIZEREL")
if(QT_CFLAGS_OPTIMIZE_SIZE)
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE_SIZE}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE_SIZE}")
else()
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE}")
endif()
endif()
# Debug should get the OPTIMIZE_DEBUG flag if the respective feature is ON.
if(config STREQUAL "DEBUG" AND QT_FEATURE_optimize_debug)
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE_DEBUG}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE_DEBUG}")
endif()
set(configs_for_optimize_size RELEASE RELWITHDEBINFO)
if(QT_FEATURE_optimize_size AND config IN_LIST configs_for_optimize_size)
- string(APPEND "${flag_var_name}" " ${QT_CFLAGS_OPTIMIZE_SIZE}")
+ set(value_to_append "${QT_CFLAGS_OPTIMIZE_SIZE}")
endif()
# Assign value to the cache entry.
- get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
- set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ if(value_to_append)
+ string(APPEND "${flag_var_name}" " ${value_to_append}")
+ get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
+ set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
+ endif()
+
endforeach()
endforeach()
@@ -379,36 +807,26 @@ function(qt_internal_set_up_config_optimizations_like_in_qmake)
# Handle MSVC /INCREMENTAL flag which should not be enabled for Release configurations.
# First remove them from all configs, and re-add INCREMENTAL for Debug only.
set(flag_values "/INCREMENTAL:YES" "/INCREMENTAL:NO" "/INCREMENTAL")
- foreach(config ${configs})
- foreach(t ${target_link_types})
- set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
- foreach(flag_value ${flag_values})
- string(REPLACE "${flag_value}" "" "${flag_var_name}" "${${flag_var_name}}")
- string(STRIP "${${flag_var_name}}" "${flag_var_name}")
- endforeach()
- endforeach()
+ foreach(flag_value ${flag_values})
+ qt_internal_replace_linker_flags(
+ "${flag_value}" ""
+ CONFIGS ${configs}
+ TYPES ${target_link_types}
+ IN_CACHE)
endforeach()
- foreach(config ${configs})
- foreach(t ${target_link_types})
- set(flag_var_name "CMAKE_${t}_LINKER_FLAGS_${config}")
-
- if(config STREQUAL "RELEASE" OR config STREQUAL "RELWITHDEBINFO"
- OR config STREQUAL "MINSIZEREL")
- string(APPEND "${flag_var_name}" " /INCREMENTAL:NO")
- endif()
-
- # Assign value to the cache entry.
- get_property(help_text CACHE "${flag_var_name}" PROPERTY HELPSTRING)
- set("${flag_var_name}" "${${flag_var_name}}" CACHE STRING "${help_text}" FORCE)
- endforeach()
- endforeach()
+ set(flag_value "/INCREMENTAL:NO")
+ qt_internal_add_linker_flags(
+ FLAGS "${flag_value}"
+ CONFIGS RELEASE RELWITHDEBINFO MINSIZEREL
+ TYPES ${target_link_types}
+ IN_CACHE)
endif()
if(QT_DEBUG_OPTIMIZATION_FLAGS)
message(STATUS "")
message(STATUS "DEBUG: Modified optimization flags to mirror qmake mkspecs.\n")
- qt_internal_print_optimization_flags_values("${enabled_languages}" "${configs}"
- "${target_link_types}")
+ qt_internal_print_optimization_flags_values_helper("${enabled_languages}" "${configs}"
+ "${target_link_types}")
endif()
endfunction()
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 3ad8f86772..802aa274f5 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -1332,4 +1332,9 @@ if(NOT QT_FEATURE_system_zlib)
NO_CONFIG_HEADER_FILE
)
endif()
+
+qt_internal_print_optimization_flags_values()
+qt_internal_add_optimize_full_flags(IN_CURRENT_SCOPE)
+qt_internal_print_optimization_flags_values()
+
# special case end
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt
index e4849939fc..661a887dc8 100644
--- a/src/gui/CMakeLists.txt
+++ b/src/gui/CMakeLists.txt
@@ -1028,3 +1028,8 @@ qt_internal_add_docs(Gui
doc/qtgui.qdocconf
)
+# special case begin
+qt_internal_print_optimization_flags_values()
+qt_internal_add_optimize_full_flags(IN_CURRENT_SCOPE)
+qt_internal_print_optimization_flags_values()
+# special case end
diff --git a/src/winmain/CMakeLists.txt b/src/winmain/CMakeLists.txt
index 1a74a1e3ae..3f3e6f0f1c 100644
--- a/src/winmain/CMakeLists.txt
+++ b/src/winmain/CMakeLists.txt
@@ -16,8 +16,10 @@ qt_internal_add_module(WinMain
if (MSVC)
# Store debug information inside the static lib
- string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
- string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+ qt_internal_replace_compiler_flags(
+ "/Zi" "/Z7"
+ CONFIGS DEBUG RELWITHDEBINFO
+ IN_CURRENT_SCOPE)
endif()
set_property(TARGET WinMain PROPERTY OUTPUT_NAME qtmain)
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 79da3331a8..89b196e593 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -4,6 +4,16 @@ if(QT_BUILD_STANDALONE_TESTS)
# Add qt_find_package calls for extra dependencies that need to be found when building
# the standalone tests here.
# special case begin
+
+ # Needed for early feature values, despite it being found later on in qt_build_tests().
+ # Needs to be find_package, not qt_find_package, because qt_find_package doesn't handle finding
+ # component for a super-package that has already been found.
+ find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS Core)
+
+ # Modify the optimization flags specifically for qtbase standalone tests. Other projects
+ # are handled by qt_enable_cmake_languages().
+ qt_internal_set_up_config_optimizations_like_in_qmake()
+
qt_find_package(WrapDBus1 PROVIDED_TARGETS dbus-1)
qt_find_package(ICU COMPONENTS i18n uc data PROVIDED_TARGETS ICU::i18n ICU::uc ICU::data)
qt_find_package(WrapOpenSSL PROVIDED_TARGETS WrapOpenSSL::WrapOpenSSL)