1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
# SPDX-FileCopyrightText: 2023 Alexander Lohnau <alexander.lohnau@gmx.de>
# SPDX-License-Identifier: BSD-2-Clause
#
# kcoreaddons_add_plugin(plugin_name
# [SOURCES <src> [<src> [...]]] # optional since 5.83, required before
# [STATIC]
# [INSTALL_NAMESPACE "servicename"]
# )
#
# This macro helps simplifying the creation of plugins for KPluginFactory
# based systems.
# It will create a plugin given the SOURCES list and the INSTALL_NAMESPACE so that
# the plugin is installed with the rest of the plugins from the same sub-system,
# within ${KDE_INSTALL_PLUGINDIR}.
# Since 5.89 the macro supports static plugins by passing in the STATIC option.
#
# Example:
# kcoreaddons_add_plugin(kdeconnect_share SOURCES ${kdeconnect_share_SRCS} INSTALL_NAMESPACE "kdeconnect")
#
# Since 5.10.0
function(kcoreaddons_add_plugin plugin)
set(options STATIC)
set(oneValueArgs INSTALL_NAMESPACE)
set(multiValueArgs SOURCES)
cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT ARGS_INSTALL_NAMESPACE)
message(FATAL_ERROR "Must specify INSTALL_NAMESPACE for ${plugin}")
endif()
if (ARGS_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "kcoreaddons_add_plugin method call received unexpected arguments: ${ARGS_UNPARSED_ARGUMENTS}")
endif()
if (NOT BUILD_SHARED_LIBS)
set(ARGS_STATIC ON)
endif()
if (ARGS_STATIC)
add_library(${plugin} STATIC ${ARGS_SOURCES})
target_compile_definitions(${plugin} PRIVATE QT_STATICPLUGIN)
string(REPLACE "/" "_" SANITIZED_PLUGIN_NAMESPACE ${ARGS_INSTALL_NAMESPACE})
if (NOT ${plugin} IN_LIST KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE})
set(KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE} "${KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE}};${plugin}" CACHE INTERNAL "list of known static plugins for ${ARGS_INSTALL_NAMESPACE} namespace")
endif()
set_target_properties(${plugin} PROPERTIES PLUGIN_INSTALL_NAMESPACE "${ARGS_INSTALL_NAMESPACE}" PLUGIN_NAME "${plugin}")
set_property(TARGET ${plugin} APPEND PROPERTY EXPORT_PROPERTIES "PLUGIN_INSTALL_NAMESPACE;PLUGIN_NAME")
else()
add_library(${plugin} MODULE ${ARGS_SOURCES})
endif()
string(REPLACE "." "_" PLUGIN_FACTORY_NAME ${plugin}_factory)
string(REPLACE "-" "_" PLUGIN_FACTORY_NAME ${PLUGIN_FACTORY_NAME})
target_compile_definitions(${plugin} PRIVATE KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME=${PLUGIN_FACTORY_NAME})
# If we have static plugins there are no plugins to install
if (ARGS_STATIC)
return()
endif()
if (NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)
message(FATAL_ERROR "CMAKE_LIBRARY_OUTPUT_DIRECTORY is not set, set it explicitly or include KDECMakeSettings")
endif()
set_target_properties(${plugin} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${ARGS_INSTALL_NAMESPACE}")
if (NOT KCOREADDONS_INTERNAL_SKIP_PLUGIN_INSTALLATION)
if(NOT ANDROID)
install(TARGETS ${plugin} DESTINATION ${KDE_INSTALL_PLUGINDIR}/${ARGS_INSTALL_NAMESPACE})
else()
string(REPLACE "/" "_" pluginprefix "${ARGS_INSTALL_NAMESPACE}")
set_property(TARGET ${plugin} PROPERTY PREFIX "libplugins_")
if(NOT pluginprefix STREQUAL "")
set_property(TARGET ${plugin} APPEND_STRING PROPERTY PREFIX "${pluginprefix}_")
endif()
install(TARGETS ${plugin} DESTINATION ${KDE_INSTALL_PLUGINDIR})
endif()
endif()
endfunction()
# This macro imports the plugins for the given namespace that were
# registered using the kcoreaddons_add_plugin function.
# This includes the initialization statements and linking the plugins to the given target.
#
# In case the plugins are used in both the executable and multiple autotests it it recommended to
# bundle the static plugins in a shared lib for the autotests. In case of shared libs the plugin registrations
# will take effect when the test link against it.
#
# Since 5.89
function(kcoreaddons_target_static_plugins app_target)
cmake_parse_arguments(ARGS "" "LINK_OPTION;NAMESPACE;TARGETS" "" ${ARGN})
if ((ARGS_LINK_OPTION AND ARGS_NAMESPACE) OR (NOT ARGS_NAMESPACE AND NOT ARGS_TARGETS))
message(FATAL_ERROR "Either NAMESPACE or TARGETS must be set")
endif()
set(START_COMMENTS "// This file is autogenerated by kcoreaddons_target_static_plugins, do not edit!\n//clazy:excludeall=non-pod-global-static\n")
# We access this as extern, because then we don't have to install the header file for it
set(PLUGIN_REGISTRATION_AUTOGEN "${START_COMMENTS}#include <QPluginLoader>\nextern void kRegisterStaticPluginFunction(const QString &, const QString &, QStaticPlugin)\;\n\n")
macro(generate_plugin_registration PLUGIN_NAME PLUGIN_NAMESPACE)
string(REPLACE "." "_" PLUGIN_FACTORY_NAME ${PLUGIN_NAME}_factory)
string(REPLACE "-" "_" PLUGIN_FACTORY_NAME ${PLUGIN_FACTORY_NAME})
set(REGISTER_PLUGIN_CALL "
extern const QT_PREPEND_NAMESPACE(QStaticPlugin) qt_static_plugin_${PLUGIN_FACTORY_NAME}()\;
class Static${PLUGIN_FACTORY_NAME}PluginInstance
{
public:
Static${PLUGIN_FACTORY_NAME}PluginInstance()
{
kRegisterStaticPluginFunction(
QStringLiteral(\"${PLUGIN_NAME}\"),
QStringLiteral(\"${PLUGIN_NAMESPACE}\"),
qt_static_plugin_${PLUGIN_FACTORY_NAME}()
)\;
}
}\;
static Static${PLUGIN_FACTORY_NAME}PluginInstance static${PLUGIN_FACTORY_NAME}Instance\;")
set(PLUGIN_REGISTRATION_AUTOGEN "${PLUGIN_REGISTRATION_AUTOGEN}${REGISTER_PLUGIN_CALL}\n")
endmacro()
if(ARGS_NAMESPACE)
string(REPLACE "/" "_" SANITIZED_PLUGIN_NAMESPACE ${ARGS_NAMESPACE})
set(TMP_PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${SANITIZED_PLUGIN_NAMESPACE}_plugins_tmp.cpp")
set(PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${SANITIZED_PLUGIN_NAMESPACE}_plugins.cpp")
foreach(PLUGIN_NAME IN LISTS KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE})
if (PLUGIN_NAME)
generate_plugin_registration(${PLUGIN_NAME} ${ARGS_NAMESPACE})
target_link_libraries(${app_target} ${ARGS_LINK_OPTION} ${PLUGIN_NAME})
endif()
endforeach()
elseif(ARGS_TARGETS)
set(TMP_PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${app_target}_plugins_tmp.cpp")
set(PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${app_target}_plugins.cpp")
foreach(ARG_TARGET IN LISTS ARGS_TARGETS)
get_target_property(PLUGIN_NAME ${ARG_TARGET} PLUGIN_NAME)
get_target_property(PLUGIN_INSTALL_NAMESPACE ${ARG_TARGET} PLUGIN_INSTALL_NAMESPACE)
generate_plugin_registration(${PLUGIN_NAME} ${PLUGIN_INSTALL_NAMESPACE})
target_link_libraries(${app_target} ${ARGS_LINK_OPTION} ${ARG_TARGET})
endforeach()
endif()
file(WRITE ${TMP_PLUGIN_FILE} ${PLUGIN_REGISTRATION_AUTOGEN})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TMP_PLUGIN_FILE} ${PLUGIN_FILE})
file(REMOVE ${TMP_PLUGIN_FILE})
target_sources(${app_target} PRIVATE ${PLUGIN_FILE})
endfunction()
# Clear previously set plugins, otherwise the linker will fail due to the symbols of a removed pugin being missing
get_directory_property(_cache_vars CACHE_VARIABLES)
foreach(CACHED_VAR IN LISTS _cache_vars)
if (CACHED_VAR MATCHES "^KCOREADDONS_STATIC_PLUGINS")
set(${CACHED_VAR} "" CACHE INTERNAL "")
endif()
endforeach()
|