Refactor qt_internal_add_plugin() and qt6_add_plugin()

Remove code duplication by calling qt6_add_plugin() from
qt_internal_add_plugin().

Separate out the public and internal arguments for the
variables defined in QtBuild.cmake for these functions.
Provide them via commands instead for greater robustness.
This separation allows other Qt repos to access the appropriate
set of keywords where they define commands that forward
on to *_add_plugin() in their implementations. Retain
the old variables for now to simplify the integration
steps for updating other repos. The old variables can
be removed once there are no more references left to
them in any repo.

Task-number: QTBUG-88763
Pick-to: 6.1
Change-Id: I0105523afd95995923bd20fc963d245bbb15d34d
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Craig Scott 2021-03-23 15:48:56 +11:00
parent 2801c19887
commit aa4a1006cb
6 changed files with 183 additions and 133 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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