CMake: Refactor optimization flag handling and add optimize_full

Introduce a bunch of helper functions to manipulate compiler
flags and linker flags for the
CMAKE_<LANG>_FLAGS_<CONFIG>
and
CMAKE_<LINK_TYPE>_LINKER_FLAGS_<CONFIG>
CMake variables.
These variables can be assigned and modified either in the cache
or for a specific subdirectory scope, which will apply the flags
only to targets in that scope.

Add qt_internal_add_optimize_full_flags() function which mimics
qmake's CONFIG += optimize_full behavior.

Calling it will force usage of the '-O3' optimization flag on supported
platforms (falling back '-O2' where not supported).

Use the function for the Core and Gui subdirectories, to enable full
optimization for the respective Qt modules as it is done in the qmake
projects.

To ensure that the global qmake-like compiler flags are assigned
eveywhere,
qt_internal_set_up_config_optimizations_like_in_qmake() needs
to be called after Qt global features like optimize_size and
optimize_full are available.

This means that qtbase and its standalone tests need some special
handling in regards to when to call that function.

Task-number: QTBUG-86866
Change-Id: Ic7ac23de0265561cb06a0ba55089b6c0d3347441
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
Alexandru Croitor 2020-10-02 15:38:47 +02:00
parent e6fd92816d
commit 07b6d3367d
8 changed files with 513 additions and 60 deletions

View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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)
# 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})
# Opt into additional non-standard configs for flag removal only.
if(QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS)
list(APPEND configs ${QT_ADDITIONAL_OPTIMIZATION_FLAG_CONFIGS})
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()

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)