diff --git a/cmake/Qt3rdPartyLibraryHelpers.cmake b/cmake/Qt3rdPartyLibraryHelpers.cmake index 4d5ffb96ff3..27d615b2b44 100644 --- a/cmake/Qt3rdPartyLibraryHelpers.cmake +++ b/cmake/Qt3rdPartyLibraryHelpers.cmake @@ -19,7 +19,7 @@ function(qt_internal_add_cmake_library target) set(is_static_lib 1) elseif(${arg_SHARED}) add_library("${target}" SHARED) - qt_internal_apply_win_prefix_and_suffix("${target}") + _qt_internal_apply_win_prefix_and_suffix("${target}") elseif(${arg_MODULE}) add_library("${target}" MODULE) set_property(TARGET ${name} PROPERTY C_VISIBILITY_PRESET default) @@ -32,7 +32,7 @@ function(qt_internal_add_cmake_library target) # but Qt plugins are actually suffixed with .dylib. set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib") endif() - qt_internal_apply_win_prefix_and_suffix("${target}") + _qt_internal_apply_win_prefix_and_suffix("${target}") else() add_library("${target}") if(NOT BUILD_SHARED_LIBS) diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index 66ef694121f..c904743b8a4 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -458,28 +458,6 @@ set(__default_target_info_args TARGET_COPYRIGHT ) -# Collection of qt_add_plugin arguments so they can be shared across different -# plugin type wrappers -set(__qt_add_plugin_optional_args - STATIC - EXCEPTIONS - ALLOW_UNDEFINED_SYMBOLS -) -set(__qt_add_plugin_single_args - TYPE - CLASS_NAME - OUTPUT_DIRECTORY - INSTALL_DIRECTORY - ARCHIVE_INSTALL_DIRECTORY - OUTPUT_NAME - ${__default_target_info_args} -) -set(__qt_add_plugin_multi_args - ${__default_private_args} - ${__default_public_args} - DEFAULT_IF -) - # Collection of arguments so they can be shared across qt_internal_add_executable # and qt_internal_add_test_helper. set(__qt_internal_add_executable_optional_args @@ -542,6 +520,43 @@ if(ANDROID) include(QtAndroidHelpers) endif() +# TODO: This block provides support for old variables. It should be removed once +# we remove all references to these variables in other Qt module repos. +# Prefer to use the provided commands to retrieve the relevant things instead. +# We won't have the queried command when we get here for qtbase (it is +# provided by the Core module), but we will for all other repos (which +# is all we need). +if(COMMAND _qt_internal_get_add_plugin_keywords) + _qt_internal_get_add_plugin_keywords( + __qt_public_add_plugin_option_args + __qt_public_add_plugin_single_args + __qt_public_add_plugin_multi_args + ) + qt_internal_get_internal_add_plugin_keywords( + __qt_internal_add_plugin_option_args + __qt_internal_add_plugin_single_args + __qt_internal_add_plugin_multi_args + ) + set(__qt_add_plugin_optional_args + ${__qt_public_add_plugin_option_args} + ${__qt_internal_add_plugin_option_args} + ) + set(__qt_add_plugin_single_args + ${__qt_public_add_plugin_single_args} + ${__qt_internal_add_plugin_single_args} + ) + set(__qt_add_plugin_multi_args + ${__qt_public_add_plugin_multi_args} + ${__qt_internal_add_plugin_multi_args} + ) + unset(__qt_public_add_plugin_option_args) + unset(__qt_public_add_plugin_single_args) + unset(__qt_public_add_plugin_multi_args) + unset(__qt_internal_add_plugin_option_args) + unset(__qt_internal_add_plugin_single_args) + unset(__qt_internal_add_plugin_multi_args) +endif() + # This sets up the poor man's scope finalizer mechanism. # For newer CMake versions, we use cmake_language(DEFER CALL) instead. if(CMAKE_VERSION VERSION_LESS "3.19.0") diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index 1fa17b8afdc..4a3237d4eaa 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -166,7 +166,7 @@ function(qt_internal_add_module target) ) endif() - qt_internal_apply_win_prefix_and_suffix("${target}") + _qt_internal_apply_win_prefix_and_suffix("${target}") if (WIN32 AND BUILD_SHARED_LIBS) _qt_internal_generate_win32_rc_file(${target}) diff --git a/cmake/QtPluginHelpers.cmake b/cmake/QtPluginHelpers.cmake index 530e71aeda8..e3bde9c79f8 100644 --- a/cmake/QtPluginHelpers.cmake +++ b/cmake/QtPluginHelpers.cmake @@ -1,3 +1,24 @@ +# Note that these are only the keywords that are unique to qt_internal_add_plugin(). +# That function also supports the keywords defined by _qt_internal_get_add_plugin_keywords(). +macro(qt_internal_get_internal_add_plugin_keywords option_args single_args multi_args) + set(${option_args} + EXCEPTIONS + ALLOW_UNDEFINED_SYMBOLS + SKIP_INSTALL + ) + set(${single_args} + OUTPUT_DIRECTORY + INSTALL_DIRECTORY + ARCHIVE_INSTALL_DIRECTORY + ${__default_target_info_args} + ) + set(${multi_args} + ${__default_private_args} + ${__default_public_args} + DEFAULT_IF + ) +endmacro() + # This is the main entry point for defining Qt plugins. # A CMake target is created with the given target. The TYPE parameter is needed to place the # plugin into the correct plugins/ sub-directory. @@ -6,10 +27,24 @@ function(qt_internal_add_plugin target) qt_internal_set_qt_known_plugins("${QT_KNOWN_PLUGINS}" "${target}") + _qt_internal_get_add_plugin_keywords( + public_option_args + public_single_args + public_multi_args + ) + qt_internal_get_internal_add_plugin_keywords( + internal_option_args + internal_single_args + internal_multi_args + ) + set(option_args ${public_option_args} ${internal_option_args}) + set(single_args ${public_single_args} ${internal_single_args}) + set(multi_args ${public_multi_args} ${internal_multi_args}) + qt_parse_all_arguments(arg "qt_internal_add_plugin" - "${__qt_add_plugin_optional_args};SKIP_INSTALL" - "${__qt_add_plugin_single_args}" - "${__qt_add_plugin_multi_args}" + "${option_args}" + "${single_args}" + "${multi_args}" "${ARGN}" ) @@ -30,22 +65,25 @@ function(qt_internal_add_plugin target) endforeach() endif() + qt_remove_args(plugin_args + ARGS_TO_REMOVE + ${internal_option_args} + ${internal_single_args} + ${internal_multi_args} + ALL_ARGS + ${option_args} + ${single_args} + ${multi_args} + ARGS + ${ARGN} + ) + qt6_add_plugin(${target} ${plugin_args}) + qt_get_sanitized_plugin_type("${arg_TYPE}" plugin_type_escaped) set(output_directory_default "${QT_BUILD_DIR}/${INSTALL_PLUGINSDIR}/${arg_TYPE}") set(install_directory_default "${INSTALL_PLUGINSDIR}/${arg_TYPE}") - # Derive the class name from the target name if it's not explicitly specified. - # Don't set it for qml plugins though. - set(plugin_class_name "") - if (NOT "${plugin_type_escaped}" STREQUAL "qml_plugin") - if (NOT arg_CLASS_NAME) - set(plugin_class_name "${target}") - else() - set(plugin_class_name "${arg_CLASS_NAME}") - endif() - endif() - qt_internal_check_directory_or_type(OUTPUT_DIRECTORY "${arg_OUTPUT_DIRECTORY}" "${arg_TYPE}" "${output_directory_default}" output_directory) if (NOT arg_SKIP_INSTALL) @@ -57,27 +95,14 @@ function(qt_internal_add_plugin target) endif() endif() - if(arg_STATIC OR NOT BUILD_SHARED_LIBS) - add_library("${target}" STATIC) - else() - add_library("${target}" MODULE) - if(APPLE) - # CMake defaults to using .so extensions for loadable modules, aka plugins, - # but Qt plugins are actually suffixed with .dylib. - set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib") - endif() - qt_internal_apply_win_prefix_and_suffix("${target}") - endif() - qt_set_common_target_properties(${target}) qt_set_target_info_properties(${target} ${ARGN} TARGET_VERSION "${arg_VERSION}") + # Override the OUTPUT_NAME that qt6_add_plugin() set, we need to account for + # QT_LIBINFIX, which is specific to building Qt. # Make sure the Qt6 plugin library names are like they were in Qt5 qmake land. # Whereas the Qt6 CMake target names are like the Qt5 CMake target names. - set(output_name "${target}") - if(arg_OUTPUT_NAME) - set(output_name "${arg_OUTPUT_NAME}") - endif() + get_target_property(output_name ${target} OUTPUT_NAME) set_property(TARGET "${target}" PROPERTY OUTPUT_NAME "${output_name}${QT_LIBINFIX}") # Add a custom target with the Qt5 qmake name for a more user friendly ninja experience. @@ -92,13 +117,6 @@ function(qt_internal_add_plugin target) endif() endif() - if (ANDROID) - qt_android_apply_arch_suffix("${target}") - set_target_properties(${target} - PROPERTIES - LIBRARY_OUTPUT_NAME "plugins_${arg_TYPE}_${output_name}" - ) - endif() qt_internal_add_target_aliases("${target}") qt_skip_warnings_are_errors_when_repo_unclean("${target}") _qt_internal_apply_strict_cpp("${target}") @@ -114,27 +132,25 @@ function(qt_internal_add_plugin target) QT_PLUGIN_TYPE "${plugin_type_escaped}" # Save the non-sanitized plugin type values for qmake consumption via .pri files. QT_QMAKE_PLUGIN_TYPE "${arg_TYPE}" - QT_PLUGIN_CLASS_NAME "${plugin_class_name}") - qt_handle_multi_config_output_dirs("${target}") + ) + + qt_handle_multi_config_output_dirs("${target}") qt_internal_library_deprecation_level(deprecation_define) qt_autogen_tools_initial_setup(${target}) - set(static_plugin_define "") - if (arg_STATIC OR NOT QT_BUILD_SHARED_LIBS) - set(static_plugin_define "QT_STATICPLUGIN") - endif() + unset(plugin_install_package_suffix) - # Save the Qt module in the plug-in's properties + # Save the Qt module in the plug-in's properties and vice versa if(NOT plugin_type_escaped STREQUAL "qml_plugin") qt_internal_get_module_for_plugin("${target}" "${plugin_type_escaped}" qt_module) + if(NOT TARGET "${qt_module}") + message(FATAL_ERROR "${qt_module} is not a known CMake target") + endif() set_target_properties("${target}" PROPERTIES QT_MODULE "${qt_module}") set(plugin_install_package_suffix "${qt_module}") - endif() - # Add the plug-in to the list of plug-ins of this module - if(TARGET "${qt_module}") set_property(TARGET "${qt_module}" APPEND PROPERTY QT_PLUGINS "${target}") get_target_property(module_source_dir ${qt_module} SOURCE_DIR) get_directory_property(module_project_name @@ -155,7 +171,7 @@ function(qt_internal_add_plugin target) endif() # Save the install package suffix as a property, so that the Dependencies file is placed - # in the current location. + # in the correct location. if(plugin_install_package_suffix) set_target_properties("${target}" PROPERTIES _qt_plugin_install_package_suffix "${plugin_install_package_suffix}") @@ -212,10 +228,7 @@ function(qt_internal_add_plugin target) PUBLIC_LIBRARIES ${arg_PUBLIC_LIBRARIES} DEFINES ${arg_DEFINES} - QT_DEPRECATED_WARNINGS ${deprecation_define} - "${static_plugin_define}" - QT_PLUGIN PUBLIC_DEFINES ${arg_PUBLIC_DEFINES} FEATURE_DEPENDENCIES ${arg_FEATURE_DEPENDENCIES} diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake index 0caff0e4840..99e84a2cd7d 100644 --- a/cmake/QtTargetHelpers.cmake +++ b/cmake/QtTargetHelpers.cmake @@ -264,43 +264,6 @@ function(qt_internal_check_directory_or_type name dir type default result_var) endif() endfunction() -function(qt_internal_apply_win_prefix_and_suffix target) - if(WIN32) - # Table of prefix / suffixes for MSVC libraries as qmake expects them to be created. - # static - Qt6EdidSupport.lib (platform support libraries / or static QtCore, etc) - # shared - Qt6Core.dll - # shared import library - Qt6Core.lib - # module aka Qt plugin - qwindows.dll - # module import library - qwindows.lib - # - # The CMake defaults are fine for us. - - # Table of prefix / suffixes for MinGW libraries as qmake expects them to be created. - # static - libQt6EdidSupport.a (platform support libraries / or static QtCore, etc) - # shared - Qt6Core.dll - # shared import library - libQt6Core.a - # module aka Qt plugin - qwindows.dll - # module import library - libqwindows.a - # - # CMake for Windows-GNU platforms defaults the prefix to "lib". - # CMake for Windows-GNU platforms defaults the import suffix to ".dll.a". - # These CMake defaults are not ok for us. - - # This should cover both MINGW with GCC and CLANG. - if(NOT MSVC) - set_property(TARGET "${target}" PROPERTY IMPORT_SUFFIX ".a") - - get_target_property(target_type ${target} TYPE) - if(target_type STREQUAL "STATIC_LIBRARY") - set_property(TARGET "${target}" PROPERTY PREFIX "lib") - else() - set_property(TARGET "${target}" PROPERTY PREFIX "") - set_property(TARGET "${target}" PROPERTY IMPORT_PREFIX "lib") - endif() - endif() - endif() -endfunction() - function(qt_internal_strip_target_directory_scope_token target out_var) # In CMake versions earlier than CMake 3.18, a subdirectory scope id is appended to the # target name if the target is referenced in a target_link_libraries command from a diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index fc8ae6a74f1..9e9b0f1e568 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -423,6 +423,43 @@ if(NOT QT_NO_CREATE_VERSIONLESS_FUNCTIONS) endfunction() endif() +function(_qt_internal_apply_win_prefix_and_suffix target) + if(WIN32) + # Table of prefix / suffixes for MSVC libraries as qmake expects them to be created. + # static - Qt6EdidSupport.lib (platform support libraries / or static QtCore, etc) + # shared - Qt6Core.dll + # shared import library - Qt6Core.lib + # module aka Qt plugin - qwindows.dll + # module import library - qwindows.lib + # + # The CMake defaults are fine for us. + + # Table of prefix / suffixes for MinGW libraries as qmake expects them to be created. + # static - libQt6EdidSupport.a (platform support libraries / or static QtCore, etc) + # shared - Qt6Core.dll + # shared import library - libQt6Core.a + # module aka Qt plugin - qwindows.dll + # module import library - libqwindows.a + # + # CMake for Windows-GNU platforms defaults the prefix to "lib". + # CMake for Windows-GNU platforms defaults the import suffix to ".dll.a". + # These CMake defaults are not ok for us. + + # This should cover both MINGW with GCC and CLANG. + if(NOT MSVC) + set_property(TARGET "${target}" PROPERTY IMPORT_SUFFIX ".a") + + get_target_property(target_type ${target} TYPE) + if(target_type STREQUAL "STATIC_LIBRARY") + set_property(TARGET "${target}" PROPERTY PREFIX "lib") + else() + set_property(TARGET "${target}" PROPERTY PREFIX "") + set_property(TARGET "${target}" PROPERTY IMPORT_PREFIX "lib") + endif() + endif() + endif() +endfunction() + set(_Qt6_COMPONENT_PATH "${CMAKE_CURRENT_LIST_DIR}/..") # This function is currently in Technical Preview. @@ -1383,17 +1420,44 @@ function(_qt_internal_process_resource target resourceName) endif() endfunction() +macro(_qt_internal_get_add_plugin_keywords option_args single_args multi_args) + set(${option_args} + STATIC + ) + set(${single_args} + TYPE + CLASS_NAME + OUTPUT_NAME + ) + set(${multi_args}) +endmacro() + # This function is currently in Technical Preview. # It's signature and behavior might change. function(qt6_add_plugin target) - cmake_parse_arguments(arg - "STATIC" - "OUTPUT_NAME;CLASS_NAME;TYPE" - "" - ${ARGN} - ) - if (arg_STATIC) + _qt_internal_get_add_plugin_keywords(opt_args single_args multi_args) + + # TODO: Transitional use only, replaced by CLASS_NAME. Remove this once + # all other repos have been updated to use CLASS_NAME. + list(APPEND single_args CLASSNAME) + + cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}") + + # Handle the inconsistent CLASSNAME/CLASS_NAME keyword naming between commands + if(arg_CLASSNAME) + if(arg_CLASS_NAME AND NOT arg_CLASSNAME STREQUAL arg_CLASS_NAME) + message(FATAL_ERROR + "Both CLASSNAME and CLASS_NAME were given and were different. " + "Only one of the two should be used." + ) + endif() + set(arg_CLASS_NAME "${arg_CLASSNAME}") + unset(arg_CLASSNAME) + endif() + + if (arg_STATIC OR NOT BUILD_SHARED_LIBS) add_library(${target} STATIC) + target_compile_definitions(${target} PRIVATE QT_STATICPLUGIN) else() add_library(${target} MODULE) if(APPLE) @@ -1401,10 +1465,7 @@ function(qt6_add_plugin target) # but Qt plugins are actually suffixed with .dylib. set_property(TARGET "${target}" PROPERTY SUFFIX ".dylib") endif() - if(WIN32) - # CMake sets for Windows-GNU platforms the suffix "lib" - set_property(TARGET "${target}" PROPERTY PREFIX "") - endif() + _qt_internal_apply_win_prefix_and_suffix(${target}) endif() set(output_name ${target}) @@ -1422,22 +1483,20 @@ function(qt6_add_plugin target) endif() # Derive the class name from the target name if it's not explicitly specified. + # Don't set it for qml plugins though. set(plugin_class_name "") - if (NOT arg_CLASS_NAME) - set(plugin_class_name "${target}") - else() - set(plugin_class_name "${arg_CLASS_NAME}") + if (NOT "${arg_TYPE}" STREQUAL "qml_plugin") + if (NOT arg_CLASS_NAME) + set(plugin_class_name "${target}") + else() + set(plugin_class_name "${arg_CLASS_NAME}") + endif() endif() set_target_properties(${target} PROPERTIES QT_PLUGIN_CLASS_NAME "${plugin_class_name}") - set(static_plugin_define "") - if (arg_STATIC) - set(static_plugin_define "QT_STATICPLUGIN") - endif() target_compile_definitions(${target} PRIVATE QT_PLUGIN QT_DEPRECATED_WARNINGS - ${static_plugin_define} ) endfunction()