Warning, /frameworks/kcoreaddons/KF5CoreAddonsMacros.cmake is written in an unsupported language. File is not indexed.

0001 #
0002 # kcoreaddons_desktop_to_json(target desktopfile
0003 #                             DEFAULT_SERVICE_TYPE | SERVICE_TYPES <file> [<file> [...]]
0004 #                             [OUTPUT_DIR dir | OUTPUT_FILE file] [COMPAT_MODE])
0005 #
0006 # This macro uses desktoptojson to generate a json file from a plugin
0007 # description in a .desktop file. The generated file can be compiled
0008 # into the plugin using the K_PLUGIN_FACTORY_WITH_JSON (cpp) macro.
0009 #
0010 # All files in SERVICE_TYPES will be parsed by desktoptojson to ensure that the generated
0011 # json uses the right data type (string, string list, int, double or bool) for all of the
0012 # properties. If your application does not have any custom properties defined you should pass
0013 # DEFAULT_SERVICE_TYPE instead. It is an error if neither of these arguments is given.
0014 # This is done in order to ensure that all applications explicitly choose the right service
0015 # type and don't have runtime errors because of the data being wrong (QJsonValue does not
0016 # perform any type conversions).
0017 #
0018 # If COMPAT_MODE is passed as an argument the generated JSON file will be compatible with
0019 # the metadata format used by KPluginInfo (from KService), otherwise it will default to
0020 # the new format that is used by KPluginMetaData (from KCoreAddons).
0021 #
0022 # If OUTPUT_DIR is set the generated file will be created inside <dir> instead of in
0023 # ${CMAKE_CURRENT_BINARY_DIR}
0024 #
0025 # If OUTPUT_FILE is set the generated file will be <file> instead of the default
0026 # ${CMAKE_CURRENT_BINARY_DIR}/$(basename desktopfile).json
0027 # .. note::
0028 # This is only considered porting aid and will be removed in KF6. Please convert the desktop files
0029 # in-source to json using the desktoptojson executable
0030 #
0031 # Example:
0032 #
0033 #  kcoreaddons_desktop_to_json(plasma_engine_time plasma-dataengine-time.desktop
0034 #                              SERVICE_TYPES plasma-dataengine.desktop)
0035 
0036 function(kcoreaddons_desktop_to_json target desktop)
0037     message(WARNING "kcoreaddons_desktop_to_json is deprecated and will be removed in KF6. Convert the desktop files to JSON in source using the desktoptojson executable")
0038     get_filename_component(desktop_basename ${desktop} NAME_WE) # allow passing an absolute path to the .desktop
0039     cmake_parse_arguments(DESKTOP_TO_JSON "COMPAT_MODE;DEFAULT_SERVICE_TYPE" "OUTPUT_DIR;OUTPUT_FILE" "SERVICE_TYPES" ${ARGN})
0040 
0041     if(DESKTOP_TO_JSON_OUTPUT_FILE)
0042         set(json "${DESKTOP_TO_JSON_OUTPUT_FILE}")
0043     elseif(DESKTOP_TO_JSON_OUTPUT_DIR)
0044         set(json "${DESKTOP_TO_JSON_OUTPUT_DIR}/${desktop_basename}.json")
0045     else()
0046         set(json "${CMAKE_CURRENT_BINARY_DIR}/${desktop_basename}.json")
0047     endif()
0048 
0049     if(CMAKE_VERSION VERSION_LESS 2.8.12.20140127 OR "${target}" STREQUAL "")
0050         _desktop_to_json_cmake28(${desktop} ${json} ${DESKTOP_TO_JSON_COMPAT_MODE})
0051         return()
0052     elseif(MSVC_IDE AND CMAKE_VERSION VERSION_LESS 3.0)
0053         # autogen dependencies for visual studio generator are broken until cmake commit 2ed0d06
0054         _desktop_to_json_cmake28(${desktop} ${json} ${DESKTOP_TO_JSON_COMPAT_MODE})
0055         return()
0056     endif()
0057     kcoreaddons_desktop_to_json_crosscompilation_args(_crosscompile_args)
0058     set(command KF5::desktoptojson ${_crosscompile_args} -i ${desktop} -o ${json})
0059     if(DESKTOP_TO_JSON_COMPAT_MODE)
0060       list(APPEND command -c)
0061     endif()
0062     if(DESKTOP_TO_JSON_SERVICE_TYPES)
0063       foreach(type ${DESKTOP_TO_JSON_SERVICE_TYPES})
0064         if(NOT IS_ABSOLUTE "${type}")
0065           if(CMAKE_CROSSCOMPILING)
0066             if (DEFINED KSERVICETYPE_PATH_${type})
0067               set(_guess ${KSERVICETYPE_PATH_${type}})
0068             else()
0069               set(_guess ${CMAKE_SYSROOT}/${KDE_INSTALL_FULL_KSERVICETYPESDIR}/${type})
0070             endif()
0071             if(EXISTS ${_guess})
0072               set(type ${CMAKE_SYSROOT}/${KDE_INSTALL_FULL_KSERVICETYPESDIR}/${type})
0073             else()
0074               message(WARNING "Could not find service type ${type}, tried ${_guess}. Set KSERVICETYPE_PATH_${type} to override this guess.")
0075             endif()
0076           elseif(EXISTS ${KDE_INSTALL_FULL_KSERVICETYPESDIR}/${type})
0077             set(type ${KDE_INSTALL_FULL_KSERVICETYPESDIR}/${type})
0078           endif()
0079         endif()
0080         list(APPEND command -s ${type})
0081       endforeach()
0082     endif()
0083 
0084     file(RELATIVE_PATH relativejson ${CMAKE_CURRENT_BINARY_DIR} ${json})
0085     add_custom_command(
0086         OUTPUT ${json}
0087         COMMAND ${command}
0088         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
0089         DEPENDS ${desktop}
0090         COMMENT "Generating ${relativejson}"
0091     )
0092     set_property(TARGET ${target} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS ${json})
0093 endfunction()
0094 
0095 # Internal function to get the additional arguments that should be passed to desktoptojson when cross-compiling
0096 function(kcoreaddons_desktop_to_json_crosscompilation_args output_var)
0097   set(_extra_args)
0098   # When cross-compiling we can't use relative paths since that might find an incompatible file on the host
0099   # using QStandardPaths (or not find any at all e.g. when cross-compiling from macOS).
0100   if(CMAKE_CROSSCOMPILING)
0101     set(_extra_args --strict-path-mode --generic-data-path "${CMAKE_SYSROOT}/${KDE_INSTALL_FULL_DATAROOTDIR}")
0102   endif()
0103   set(${output_var} ${_extra_args} PARENT_SCOPE)
0104 endfunction()
0105 
0106 function(_desktop_to_json_cmake28 desktop json compat)
0107     # This function runs desktoptojson at *configure* time, ie, when CMake runs.
0108     # This is necessary with CMake < 3.0.0 because the .json file must be
0109     # generated before moc is run, and there was no way until CMake 3.0.0 to
0110     # define a target as a dependency of the automoc target.
0111     message("Using CMake 2.8 way to call desktoptojson")
0112     get_target_property(DESKTOPTOJSON_LOCATION KF5::desktoptojson LOCATION)
0113     if(compat)
0114         execute_process(
0115             COMMAND ${DESKTOPTOJSON_LOCATION} -i ${desktop} -o ${json} -c
0116             RESULT_VARIABLE result
0117             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
0118         )
0119     else()
0120         execute_process(
0121             COMMAND ${DESKTOPTOJSON_LOCATION} -i ${desktop} -o ${json}
0122             RESULT_VARIABLE result
0123             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
0124         )
0125     endif()
0126 
0127     if (NOT result EQUAL 0)
0128         message(FATAL_ERROR "Generating ${json} failed")
0129     endif()
0130 endfunction()
0131 
0132 #
0133 # kcoreaddons_add_plugin(plugin_name
0134 #     [SOURCES <src> [<src> [...]]] # optional since 5.83, required before
0135 #     [JSON "pluginname.json"]
0136 #     [STATIC]
0137 #     [INSTALL_NAMESPACE "servicename"]
0138 # )
0139 #
0140 # This macro helps simplifying the creation of plugins for KPluginFactory
0141 # based systems.
0142 # It will create a plugin given the SOURCES list and the INSTALL_NAMESPACE so that
0143 # the plugin is installed with the rest of the plugins from the same sub-system,
0144 # within ${KDE_INSTALL_PLUGINDIR}.
0145 # The JSON parameter is deprecated since 5.85, because it is not needed when the project is properly set up using
0146 # the ECMSetupQtPluginMacroNames module. In case of plugin export macros provided by the KDE Frameworks this is already done and the parameter
0147 # can be dropped with any older KF5 requirement.
0148 # In case you generate the JSON files during the build it should be manually added to the AUTOGEN_TARGET_DEPENDS property,
0149 # the kcoreaddons_desktop_to_json already does this for the generated file.
0150 # Since 5.89 the macro supports static plugins by passing in the STATIC option.
0151 #
0152 # Example:
0153 #   kcoreaddons_add_plugin(kdeconnect_share SOURCES ${kdeconnect_share_SRCS} INSTALL_NAMESPACE "kdeconnect")
0154 #
0155 # Since 5.10.0
0156 
0157 function(kcoreaddons_add_plugin plugin)
0158     set(options STATIC)
0159     set(oneValueArgs JSON INSTALL_NAMESPACE)
0160     set(multiValueArgs SOURCES)
0161     cmake_parse_arguments(KCA_ADD_PLUGIN "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0162 
0163     if (NOT KCA_ADD_PLUGIN_INSTALL_NAMESPACE)
0164         message(FATAL_ERROR "Must specify INSTALL_NAMESPACE for ${plugin}")
0165     endif()
0166     if (KCA_ADD_PLUGIN_UNPARSED_ARGUMENTS)
0167         if ("${ECM_GLOBAL_FIND_VERSION}" VERSION_GREATER_EQUAL "5.91.0")
0168             message(FATAL_ERROR "kcoreaddons_add_plugin method call recieved unexpected arguments: ${KCA_ADD_PLUGIN_UNPARSED_ARGUMENTS}")
0169         else()
0170             message(WARNING "kcoreaddons_add_plugin method call recieved unexpected arguments: ${KCA_ADD_PLUGIN_UNPARSED_ARGUMENTS}")
0171         endif()
0172     endif()
0173 
0174     string(REPLACE "-" "_" SANITIZED_PLUGIN_NAME ${plugin})
0175     string(REPLACE "." "_" SANITIZED_PLUGIN_NAME ${SANITIZED_PLUGIN_NAME})
0176     if (KCA_ADD_PLUGIN_STATIC)
0177         add_library(${plugin} STATIC ${KCA_ADD_PLUGIN_SOURCES})
0178         target_compile_definitions(${plugin} PRIVATE QT_STATICPLUGIN)
0179         set_property(TARGET ${plugin} PROPERTY AUTOMOC_MOC_OPTIONS -MX-KDE-FileName=${KCA_ADD_PLUGIN_INSTALL_NAMESPACE}/${plugin})
0180         string(REPLACE "/" "_" SANITIZED_PLUGIN_NAMESPACE ${KCA_ADD_PLUGIN_INSTALL_NAMESPACE})
0181 
0182         if (NOT ${SANITIZED_PLUGIN_NAME} IN_LIST KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE})
0183             set(KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE} "${KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE}};${SANITIZED_PLUGIN_NAME}" CACHE INTERNAL "list of known static plugins for ${KCA_ADD_PLUGIN_INSTALL_NAMESPACE} namespace, used to generate Q_IMPORT_PLUGIN macros")
0184         endif()
0185     else()
0186         add_library(${plugin} MODULE ${KCA_ADD_PLUGIN_SOURCES})
0187     endif()
0188 
0189     if ("${ECM_GLOBAL_FIND_VERSION}" VERSION_GREATER_EQUAL "5.85.0" AND KCA_ADD_PLUGIN_JSON)
0190         message(WARNING "Setting the JSON parameter is deprecated, see function docs for details")
0191     endif()
0192     get_filename_component(json "${KCA_ADD_PLUGIN_JSON}" REALPATH)
0193     set_property(TARGET ${plugin} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS ${json})
0194 
0195 
0196     if ("${ECM_GLOBAL_FIND_VERSION}" VERSION_GREATER_EQUAL "5.88.0")
0197         target_compile_definitions(${plugin} PRIVATE KPLUGINFACTORY_PLUGIN_CLASS_INTERNAL_NAME=${SANITIZED_PLUGIN_NAME}_factory)
0198     endif()
0199 
0200     # If we have static plugins there are no plugins to install
0201     if (KCA_ADD_PLUGIN_STATIC)
0202         return()
0203     endif()
0204     # If find_package(ECM 5.38) or higher is called, output the plugin in a INSTALL_NAMESPACE subfolder.
0205     # See https://community.kde.org/Guidelines_and_HOWTOs/Making_apps_run_uninstalled
0206     # From 5.90 we went back to putting the plugins in a INSTALL_NAMESPACE subfolder in the builddir, but
0207     # without putting that in a "plugins/" dir as that broke running unittests directly on the command line
0208     # (i.e. without using ctest, e.g. in gdb).
0209     if(ECM_GLOBAL_FIND_VERSION VERSION_EQUAL "5.88.0" OR ECM_GLOBAL_FIND_VERSION VERSION_EQUAL "5.89.0")
0210         set_target_properties(${plugin} PROPERTIES
0211             LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/plugins/${KCA_ADD_PLUGIN_INSTALL_NAMESPACE}")
0212     elseif(ECM_GLOBAL_FIND_VERSION VERSION_GREATER_EQUAL "5.38.0")
0213         set_target_properties(${plugin} PROPERTIES
0214             LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${KCA_ADD_PLUGIN_INSTALL_NAMESPACE}")
0215     endif()
0216 
0217     if (NOT KCOREADDONS_INTERNAL_SKIP_PLUGIN_INSTALLATION)
0218         if(NOT ANDROID)
0219             install(TARGETS ${plugin} DESTINATION ${KDE_INSTALL_PLUGINDIR}/${KCA_ADD_PLUGIN_INSTALL_NAMESPACE})
0220         else()
0221             string(REPLACE "/" "_" pluginprefix "${KCA_ADD_PLUGIN_INSTALL_NAMESPACE}")
0222             set_property(TARGET ${plugin} PROPERTY PREFIX "libplugins_")
0223             if(NOT pluginprefix STREQUAL "")
0224                 set_property(TARGET ${plugin} APPEND_STRING PROPERTY PREFIX "${pluginprefix}_")
0225             endif()
0226             install(TARGETS ${plugin} DESTINATION ${KDE_INSTALL_PLUGINDIR})
0227         endif()
0228     endif()
0229 endfunction()
0230 
0231 # This macro imports the plugins for the given namespace that were
0232 # registered using the kcoreaddons_add_plugin function.
0233 # This includes the K_IMPORT_PLUGIN statements and linking the plugins to the given target.
0234 #
0235 # In case the plugins are used in both the executable and multiple autotests it it recommended to
0236 # bundle the static plugins in a shared lib for the autotests. In case of shared libs the plugin registrations
0237 # will take effect when the test link against it.
0238 #
0239 # Since 5.89
0240 function(kcoreaddons_target_static_plugins app_target plugin_namespace)
0241     cmake_parse_arguments(ARGS "" "LINK_OPTION" "" ${ARGN})
0242     set(IMPORT_PLUGIN_STATEMENTS "#include <kstaticpluginhelpers.h>\n\n")
0243     string(REPLACE "/" "_" SANITIZED_PLUGIN_NAMESPACE ${plugin_namespace})
0244     set(TMP_PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${SANITIZED_PLUGIN_NAMESPACE}_plugins_tmp.cpp")
0245     set(PLUGIN_FILE "${CMAKE_CURRENT_BINARY_DIR}/kcoreaddons_static_${SANITIZED_PLUGIN_NAMESPACE}_plugins.cpp")
0246 
0247     foreach(PLUGIN_TARGET_NAME IN LISTS KCOREADDONS_STATIC_PLUGINS${SANITIZED_PLUGIN_NAMESPACE})
0248         if (PLUGIN_TARGET_NAME)
0249             set(IMPORT_PLUGIN_STATEMENTS "${IMPORT_PLUGIN_STATEMENTS}K_IMPORT_PLUGIN(QStringLiteral(\"${plugin_namespace}\"), ${PLUGIN_TARGET_NAME}_factory)\;\n")
0250             target_link_libraries(${app_target} ${ARGS_LINK_OPTION} ${PLUGIN_TARGET_NAME})
0251         endif()
0252     endforeach()
0253     file(WRITE ${TMP_PLUGIN_FILE} ${IMPORT_PLUGIN_STATEMENTS})
0254     execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TMP_PLUGIN_FILE} ${PLUGIN_FILE})
0255     file(REMOVE ${TMP_PLUGIN_FILE})
0256     if(ECM_GLOBAL_FIND_VERSION VERSION_GREATER_EQUAL "5.91.0")
0257         target_sources(${app_target} PRIVATE ${PLUGIN_FILE})
0258     else()
0259         # in case of apps bundling their plugins in a small static lib the linking needs to be public
0260         # see API docs for a better solution in consumer's code.
0261         # Because this will not change the behavior if the plugins are targeted directly to the executable, only
0262         # an ECM version check is used and not an additional option.
0263         target_sources(${app_target} PUBLIC ${PLUGIN_FILE})
0264     endif()
0265 endfunction()
0266 
0267 # Clear previously set plugins, otherwise Q_IMPORT_PLUGIN statements
0268 # will fail to compile if plugins got removed from the build
0269 get_directory_property(_cache_vars CACHE_VARIABLES)
0270 foreach(CACHED_VAR IN LISTS _cache_vars)
0271     if (CACHED_VAR MATCHES "^KCOREADDONS_STATIC_PLUGINS")
0272         set(${CACHED_VAR} "" CACHE INTERNAL "")
0273     endif()
0274 endforeach()