diff options
-rw-r--r-- | CMakeLists.txt | 10 | ||||
-rw-r--r-- | cmake/QtBuildInternals/QtBuildInternalsConfig.cmake | 5 | ||||
-rw-r--r-- | cmake/QtFindPackageHelpers.cmake | 4 | ||||
-rw-r--r-- | cmake/QtFlagHandlingHelpers.cmake | 530 | ||||
-rw-r--r-- | src/corelib/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/gui/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/winmain/CMakeLists.txt | 6 | ||||
-rw-r--r-- | tests/CMakeLists.txt | 10 |
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) |