CMake: Remove qt6_enable_object_libraries_finalizer_mode
qt6_enable_object_libraries_finalizer_mode is not needed anymore now that static Qt builds require CMake 3.21 and thus CMake takes care of placing object library object files at the beginning of the link line. Rename qt6_enable_import_plugins_finalizer_mode to a more generic qt6_set_finalizer_mode that can enable or disable multiple different modes. For now the only available mode is "static_plugins" which handles the behavior of the old function name. The mode can be enabled by calling qt6_set_finalizer_mode(${target} ENABLE MODES "static_plugins") Note that the function is re-tagged as being in Technical Preview. Ideally we would not need it at all. But we need to provide some workaround for the limitations of linking Qt static plugins in CMake on Linux-y platforms that use bfd ld or ld.gold. The workaround does not work well with dependencies wrapped in generator expressions which is why we can't confidently advertise it as a proper solution. Our hope is that this can be fixed in future upstream CMake versions and the function can be removed. See6fcc272ac9
for details. Adjust the tests due to the renamed and removed functions. Amends19e789bace
Amendscdbb390c4a
Amendsa25027eecb
Amends6fcc272ac9
Amendsa3c430f390
Pick-to: 6.2 Fixes: QTBUG-95169 Task-number: QTBUG-95601 Task-number: QTBUG-95603 Change-Id: I51b85f776ec29fc04fed1a637eba7d1f60609e69 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
f95a446641
commit
5161d8d525
@ -131,7 +131,7 @@ endfunction()
|
||||
# Wraps the genex condition to evaluate to true only when using the regular plugin importing mode
|
||||
# (not finalizer mode).
|
||||
function(__qt_internal_get_plugin_condition_regular_mode plugin_condition out_var)
|
||||
set(not_finalizer_mode "$<NOT:$<BOOL:$<TARGET_PROPERTY:_qt_static_plugins_use_finalizer_mode>>>")
|
||||
set(not_finalizer_mode "$<NOT:$<BOOL:$<TARGET_PROPERTY:_qt_static_plugins_finalizer_mode>>>")
|
||||
set(full_plugin_condition "$<AND:${plugin_condition},${not_finalizer_mode}>")
|
||||
set(${out_var} "${full_plugin_condition}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@ -368,17 +368,6 @@ function(__qt_internal_collect_plugin_targets_from_dependencies_of_plugins targe
|
||||
set("${out_var}" "${plugin_targets}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Helper to check if the finalizer mode of plugin importing should be used.
|
||||
# If true or unset, use finalizer mode.
|
||||
# If false, use regular mode (usage requirement propagation via associated Qt module)
|
||||
function(__qt_internal_get_plugin_imports_finalizer_mode target out_var)
|
||||
get_target_property(value ${target} _qt_static_plugins_use_finalizer_mode)
|
||||
if("${value}" STREQUAL "value-NOTFOUND")
|
||||
set(value "")
|
||||
endif()
|
||||
set(${out_var} "${value}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# Main logic of finalizer mode.
|
||||
function(__qt_internal_apply_plugin_imports_finalizer_mode target)
|
||||
# Nothing to do in a shared build.
|
||||
@ -392,17 +381,15 @@ function(__qt_internal_apply_plugin_imports_finalizer_mode target)
|
||||
return()
|
||||
endif()
|
||||
|
||||
__qt_internal_get_plugin_imports_finalizer_mode(${target} use_finalizer_mode)
|
||||
|
||||
# By default if the project hasn't explicitly opted in or out, use finalizer mode.
|
||||
# The precondition for this is that qt_finalize_target was called (either explicitly by the user
|
||||
# or auto-deferred by CMake 3.19+).
|
||||
if("${use_finalizer_mode}" STREQUAL "")
|
||||
qt_enable_import_plugins_finalizer_mode(${target} TRUE)
|
||||
endif()
|
||||
__qt_internal_check_finalizer_mode("${target}"
|
||||
use_finalizer_mode
|
||||
static_plugins
|
||||
DEFAULT_VALUE "TRUE"
|
||||
)
|
||||
|
||||
# Check if the project chose a mode explicitly.
|
||||
__qt_internal_get_plugin_imports_finalizer_mode(${target} use_finalizer_mode)
|
||||
if(NOT use_finalizer_mode)
|
||||
return()
|
||||
endif()
|
||||
|
@ -881,48 +881,52 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# This function allows enabling or disabling the finalizer mode of plugin importing in static Qt
|
||||
# builds.
|
||||
# This function is currently in Technical Preview. It's signature may change or be removed entirely.
|
||||
|
||||
# This function allows enabling or disabling finalizer modes for a specific target.
|
||||
# Currently, the only supported finalizer mode is for plugin importing in static Qt builds which
|
||||
# is called 'static_plugins'. You can enable / disable it by calling
|
||||
#
|
||||
# When finalizer mode is enabled, all plugins initializer object libraries are directly linked to
|
||||
# the given '${target}' (executable or shared library).
|
||||
# This prevents cycles between Qt provided static libraries and reduces link time, due to the
|
||||
# libraries not being repeated because they are not part of a cycle anymore.
|
||||
# qt6_set_finalizer_mode(${target} ENABLE MODES "static_plugins")
|
||||
# qt6_set_finalizer_mode(${target} DISABLE MODES "static_plugins")
|
||||
#
|
||||
# When finalizer mode is disabled, each plugin initializer is propagated via usage requirements
|
||||
# of its associated module.
|
||||
# When the "static_plugins" finalizer mode is enabled, all plugins initializer object libraries are
|
||||
# directly linked to the given ${target} (executable or shared library).
|
||||
# This prevents cycles between Qt provided static libraries and reduces link time, thanks to the
|
||||
# libraries not being repeated on the link line because they are not part of a cycle anymore.
|
||||
#
|
||||
# Finalizer mode is enabled by default if:
|
||||
# When the finalizer mode is disabled, each plugin initializer is propagated via usage requirements
|
||||
# of its associated module, which may cause cycles in the current build system implementation.
|
||||
#
|
||||
# The "static_plugins" finalizer mode is enabled by default if:
|
||||
# - the project calls qt_finalize_target explicitly at the end of the project file or
|
||||
# - the project uses qt_add_executable and a CMake version greater than or equal to 3.19
|
||||
# (which will DEFER CALL qt_finalize_target)
|
||||
function(qt6_enable_import_plugins_finalizer_mode target enabled)
|
||||
if(enabled)
|
||||
set(enabled "TRUE")
|
||||
else()
|
||||
set(enabled "FALSE")
|
||||
function(qt6_set_finalizer_mode target)
|
||||
cmake_parse_arguments(arg "ENABLE;DISABLE" "" "MODES" ${ARGN})
|
||||
if(NOT arg_ENABLE AND NOT arg_DISABLE)
|
||||
message(FATAL_ERROR "No option was specified whether to enable or disable the modes.")
|
||||
elseif(arg_ENABLE AND arg_DISABLE)
|
||||
message(FATAL_ERROR "Both ENABLE and DISABLE options were specified.")
|
||||
endif()
|
||||
set_property(TARGET "${target}" PROPERTY _qt_static_plugins_use_finalizer_mode "${enabled}")
|
||||
if(NOT arg_MODES)
|
||||
message(FATAL_ERROR "No modes were specified in qt6_set_finalizer_mode() call.")
|
||||
endif()
|
||||
|
||||
if(arg_ENABLE)
|
||||
set(value "TRUE")
|
||||
elseif(arg_DISABLE)
|
||||
set(value "FALSE")
|
||||
endif()
|
||||
|
||||
foreach(mode ${arg_MODES})
|
||||
__qt_internal_enable_finalizer_mode("${target}" "${mode}" "${value}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
function(qt_enable_import_plugins_finalizer_mode)
|
||||
qt6_enable_import_plugins_finalizer_mode(${ARGV})
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
# This function allows enabling or disabling the finalizer mode of resource objects linking in
|
||||
# static Qt builds.
|
||||
# It makes sense to manually disable the finalizer of the resource object if you are using
|
||||
# linkers other than ld, since the dependencies between resource objects and static libraries
|
||||
# are resolved correctly by them.
|
||||
function(qt6_enable_object_libraries_finalizer_mode target enabled)
|
||||
__qt_internal_enable_finalizer_mode(${target} object_libraries ${enabled})
|
||||
endfunction()
|
||||
|
||||
if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
|
||||
function(qt_enable_object_libraries_finalizer_mode)
|
||||
qt6_enable_object_libraries_finalizer_mode(${ARGV})
|
||||
function(qt_set_finalizer_mode)
|
||||
qt6_set_finalizer_mode(${ARGV})
|
||||
endfunction()
|
||||
endif()
|
||||
|
||||
|
@ -38,12 +38,12 @@ function(create_test_executable target)
|
||||
add_test(test_${target_name_adjusted} ${target_name_adjusted})
|
||||
|
||||
if(arg_FINALIZER_MODE)
|
||||
set(finalizer_mode "TRUE")
|
||||
set(finalizer_mode_state "ENABLE")
|
||||
else()
|
||||
set(finalizer_mode "FALSE")
|
||||
set(finalizer_mode_state "DISABLE")
|
||||
endif()
|
||||
qt_enable_import_plugins_finalizer_mode(${target_name_adjusted} ${finalizer_mode})
|
||||
|
||||
qt_set_finalizer_mode(${target_name_adjusted} ${finalizer_mode_state} MODES static_plugins)
|
||||
set(target ${target_name_adjusted} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@ -73,7 +73,7 @@ target_link_libraries(${target} PRIVATE Qt6::MockPlugins2)
|
||||
|
||||
# Check that both regular and finalizer mode plugin importing pulls in the same set of plugins.
|
||||
# In regular mode, qt_finalize_target won't execute the finalizer plugin importing, because
|
||||
# we opt out via qt_enable_import_plugins_finalizer_mode(target FALSE).
|
||||
# we opt out via qt_set_finalizer_mode(target DISABLE MODES static_plugins).
|
||||
foreach(import_mode "" "FINALIZER_MODE")
|
||||
create_test_executable(manual QMock1Plugin QMock2Plugin QMock3Plugin QMock4Plugin
|
||||
${import_mode})
|
||||
|
@ -1,3 +1,10 @@
|
||||
# TODO: Revisit which of these tests makes sense to keep now that we depend on CMake 3.21 to
|
||||
# properly place object libraries object files on the link line.
|
||||
# See QTBUG-95601
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# Add a dummy library that links the static "Qt" module containing resources
|
||||
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp" CONTENT "void dummy() { }")
|
||||
add_library(dummy STATIC "${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp")
|
||||
@ -77,24 +84,26 @@ if(NOT link_order_matters)
|
||||
COMMAND test_static_resources_propagation_non_ld
|
||||
)
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
|
||||
qt_add_executable(test_static_resources_propagation_not_finalize main.cpp)
|
||||
qt6_enable_object_libraries_finalizer_mode(
|
||||
test_static_resources_propagation_not_finalize FALSE
|
||||
)
|
||||
set_target_properties(test_static_resources_propagation_not_finalize PROPERTIES
|
||||
AUTOMOC TRUE
|
||||
)
|
||||
target_link_libraries(test_static_resources_propagation_not_finalize
|
||||
PRIVATE
|
||||
dummy
|
||||
Qt::Core
|
||||
Qt::Test
|
||||
)
|
||||
add_test(NAME test_static_resources_propagation_not_finalize
|
||||
COMMAND test_static_resources_propagation_not_finalize
|
||||
)
|
||||
endif()
|
||||
# FIXME: qt6_enable_object_libraries_finalizer_mode is not available anymore. See QTBUG-95601
|
||||
#
|
||||
# if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.19)
|
||||
# qt_add_executable(test_static_resources_propagation_not_finalize main.cpp)
|
||||
# qt6_enable_object_libraries_finalizer_mode(
|
||||
# test_static_resources_propagation_not_finalize FALSE
|
||||
# )
|
||||
# set_target_properties(test_static_resources_propagation_not_finalize PROPERTIES
|
||||
# AUTOMOC TRUE
|
||||
# )
|
||||
# target_link_libraries(test_static_resources_propagation_not_finalize
|
||||
# PRIVATE
|
||||
# dummy
|
||||
# Qt::Core
|
||||
# Qt::Test
|
||||
# )
|
||||
# add_test(NAME test_static_resources_propagation_not_finalize
|
||||
# COMMAND test_static_resources_propagation_not_finalize
|
||||
# )
|
||||
# endif()
|
||||
endif()
|
||||
|
||||
# Add the executable using add_executable, expecting resources are propagated using
|
||||
|
Loading…
Reference in New Issue
Block a user