diff --git a/CMakeLists.txt b/CMakeLists.txt index cb61a22..ec4f3bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,8 @@ set(META_APP_AUTHOR "Martchus") set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}") set(META_APP_DESCRIPTION "Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models") -set(META_VERSION_MAJOR 5) -set(META_VERSION_MINOR 13) +set(META_VERSION_MAJOR 6) +set(META_VERSION_MINOR 0) set(META_VERSION_PATCH 0) set(META_APP_VERSION ${META_VERSION_MAJOR}.${META_VERSION_MINOR}.${META_VERSION_PATCH}) @@ -86,8 +86,8 @@ set(CMAKE_MODULE_FILES cmake/modules/QtConfig.cmake cmake/modules/QtGuiConfig.cmake cmake/modules/QtLinkage.cmake - cmake/modules/JsProviderConfig.cmake - cmake/modules/WebViewProviderConfig.cmake) + cmake/modules/QtWebViewProviderConfig.cmake + cmake/modules/QtJsProviderConfig.cmake) set(CMAKE_TEMPLATE_FILES cmake/templates/qtconfig.h.in cmake/templates/webviewdefs.h.in diff --git a/cmake/modules/JsProviderConfig.cmake b/cmake/modules/JsProviderConfig.cmake deleted file mode 100644 index 77fc29b..0000000 --- a/cmake/modules/JsProviderConfig.cmake +++ /dev/null @@ -1,75 +0,0 @@ -# determines the JavaScript provider (either Qt Script or Qt Declarative) - -if (TARGET_CONFIG_DONE) - message(FATAL_ERROR "Can not include JsProviderConfig module when targets are already configured.") -endif () - -include(QtLinkage) - -set(JS_PROVIDER "auto" CACHE STRING "specifies the JavaScript provider: auto (default), qml, script or none") -if (NOT JS_PROVIDER OR "${JS_PROVIDER}" STREQUAL "auto") - find_qt5_module(Script OPTIONAL) - if (QT5_Script_FOUND) - set(JS_PROVIDER Script) - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_SCRIPT") - list(APPEND ADDITIONAL_QT_REPOS "script") - message(STATUS "No JavaScript provider explicitly specified, defaulting to Qt Script.") - else () - find_qt5_module(Qml OPTIONAL) - if (QT5_Qml_FOUND) - set(JS_PROVIDER Qml) - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_JSENGINE") - list(APPEND ADDITIONAL_QT_REPOS "declarative") - message(STATUS "No JavaScript provider explicitly specified, defaulting to Qt QML.") - else () - set(JS_PROVIDER "") - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_JSENGINE") - message(STATUS "No JavaScript provider available, features requiring JavaScript have been disabled.") - endif () - endif () -else () - if (${JS_PROVIDER} STREQUAL "script") - find_qt5_module(Script REQUIRED) - set(JS_PROVIDER Script) - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_SCRIPT") - list(APPEND ADDITIONAL_QT_REPOS "script") - message(STATUS "Using Qt Script as JavaScript provider.") - elseif (${JS_PROVIDER} STREQUAL "qml") - find_qt5_module(Qml REQUIRED) - set(JS_PROVIDER Qml) - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_JSENGINE") - list(APPEND ADDITIONAL_QT_REPOS "declarative") - message(STATUS "Using Qt QML as JavaScript provider.") - elseif (${JS_PROVIDER} STREQUAL "none") - set(JS_PROVIDER "") - set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_JSENGINE") - message(STATUS "JavaScript provider has been disabled.") - else () - message(FATAL_ERROR "The specified JavaScript provider '${JS_PROVIDER}' is unknown.") - endif () -endif () - -if (JS_PROVIDER) - use_qt5_module(${JS_PROVIDER} REQUIRED) - - # add header files with some defines/includes to conveniently use the selected provider - if (META_JS_SRC_DIR) - set(JS_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${META_JS_SRC_DIR}") - else () - set(JS_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") - endif () - include(TemplateFinder) - find_template_file("jsdefs.h" QT_UTILITIES JS_DEFS_H_TEMPLATE_FILE) - configure_file("${JS_DEFS_H_TEMPLATE_FILE}" - "${JS_HEADER_DIR}/jsdefs.h" # simply add this to source to ease inclusion - NEWLINE_STYLE UNIX # since this goes to sources ensure consistency - ) - find_template_file("jsincludes.h" QT_UTILITIES JS_INCLUDES_H_TEMPLATE_FILE) - configure_file("${JS_INCLUDES_H_TEMPLATE_FILE}" - "${JS_HEADER_DIR}/jsincludes.h" # simply add this to source to ease inclusion - NEWLINE_STYLE UNIX # since this goes to sources ensure consistency - ) - list(APPEND WIDGETS_FILES "${JS_HEADER_DIR}/jsdefs.h" "${JS_HEADER_DIR}/jsincludes.h") -endif () - -list(APPEND META_PUBLIC_COMPILE_DEFINITIONS ${JS_DEFINITION}) diff --git a/cmake/modules/QtConfig.cmake b/cmake/modules/QtConfig.cmake index 6923e79..4e14bfb 100644 --- a/cmake/modules/QtConfig.cmake +++ b/cmake/modules/QtConfig.cmake @@ -1,7 +1,8 @@ cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR) -# applies Qt specific configuration for GUI applications, QtGuiAppConfig must be included before this module must always be -# included before AppTarget/LibraryTarget +# applies Qt specific configuration +# notes: For GUI applications, QtGuiConfig must be included before. +# This module must always be included before AppTarget/LibraryTarget. # ensure generated sources are processed by AUTOMOC and AUTOUIC if (POLICY CMP0071) @@ -18,9 +19,10 @@ if (TARGET_CONFIG_DONE) message(FATAL_ERROR "Can not include QtConfig module when targets are already configured.") endif () -# add the Core module as it is always required also add additional Qt/KF modules which must have been specified before if -# required the Gui/Widgets/Quick modules should be added by including QtGuiAppConfig -set(QT_REPOS base ${ADDITIONAL_QT_REPOS}) +# add the Core module as it is always required and also add additional Qt/KF modules +# which must have been specified before if required +# note: The Gui/Widgets/Quick modules should be added by including QtGuiConfig. +set(QT_REPOS ${ADDITIONAL_QT_REPOS} base) set(QT_MODULES ${ADDITIONAL_QT_MODULES} Core) set(KF_MODULES ${ADDITIONAL_KF_MODULES}) @@ -49,73 +51,74 @@ if (IMPORTED_KF_MODULES) list(REMOVE_DUPLICATES IMPORTED_KF_MODULES) endif () -# actually find the required Qt/KF modules -foreach (QT_MODULE ${QT_MODULES}) - # using those helpers allows using static Qt 5 build - find_qt5_module(${QT_MODULE} REQUIRED) - use_qt5_module(${QT_MODULE} REQUIRED) +# find and use the required Qt/KF modules +set(QT_PACKAGE_PREFIX "Qt5" CACHE STRING "specifies the prefix for Qt packages") +foreach (MODULE ${QT_MODULES}) + unset(MODULE_OPTIONS) + if ("${MODULE}" IN_LIST META_PUBLIC_QT_MODULES) + list(APPEND MODULE_OPTIONS VISIBILITY PUBLIC) + endif() + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE "${MODULE}" ${MODULE_OPTIONS}) endforeach () -foreach (QT_MODULE ${IMPORTED_QT_MODULES}) +set(KF_PACKAGE_PREFIX "KF5" CACHE STRING "specifies the prefix for KDE Frameworks packages") +foreach (MODULE ${KF_MODULES}) + unset(MODULE_OPTIONS) + if ("${MODULE}" IN_LIST META_PUBLIC_KF_MODULES) + list(APPEND MODULE_OPTIONS VISIBILITY PUBLIC) + endif() + use_qt_module(PREFIX "${KF_PACKAGE_PREFIX}" MODULE "${MODULE}" ${MODULE_OPTIONS}) +endforeach () + +# hack for using static Qt via "StaticQt5" prefix: find regular Qt5Core module as well so Qt version is defined +if (QT_PACKAGE_PREFIX STREQUAL "StaticQt5") + find_package(Qt5Core) +endif() + +# find transitively required Qt/KF modules +foreach (MODULE ${IMPORTED_QT_MODULES}) if (NOT "${QT_MODULE}" IN_LIST QT_MODULES) - find_qt5_module(${QT_MODULE} REQUIRED) + find_package("${QT_PACKAGE_PREFIX}${MODULE}" REQUIRED) endif () endforeach () -foreach (KF_MODULE ${KF_MODULES}) - # only shared KF5 modules supported - find_package(KF5${KF_MODULE} REQUIRED) - set(KF5_${KF_MODULE}_DYNAMIC_LIB KF5::${KF_MODULE}) - link_against_library(KF5_${KF_MODULE} "AUTO_LINKAGE" REQUIRED) -endforeach () -foreach (KF_MODULE ${IMPORTED_KF_MODULES}) +foreach (MODULE ${IMPORTED_KF_MODULES}) if (NOT "${KF_MODULE}" IN_LIST KF_MODULES) - find_package(KF5${KF_MODULE} REQUIRED) + find_package("${KF_PACKAGE_PREFIX}${MODULE}" REQUIRED) endif () endforeach () -# built-in platform, imageformat and iconengine plugins when linking statically against Qt Gui -> determine whether -# application target links statically against Qt Gui -if (META_PROJECT_TYPE STREQUAL "application") - set(USING_STATIC_QT_GUI_FOR_APPLICATION NO) - foreach (MODULE Gui Widgets Quick) - if (QT5_${MODULE}_STATIC_LIB IN_LIST LIBRARIES OR QT5_${MODULE}_STATIC_LIB IN_LIST PRIVATE_LIBRARIES) - set(USING_STATIC_QT_GUI_FOR_APPLICATION YES) - message(STATUS "Linking application ${META_PROJECT_NAME} against static Qt 5 plugins.") - break() - endif () - endforeach () -endif () -# -> link against plugins according to platform and configuration -if (USING_STATIC_QT_GUI_FOR_APPLICATION) - if (NOT USE_STATIC_QT5_Gui) - find_qt5_module(Gui REQUIRED) - endif () +# built-in platform, imageformat and iconengine plugins when linking statically against Qt +if (STATIC_LINKAGE AND META_PROJECT_IS_APPLICATION) + message(STATUS "Linking application ${META_PROJECT_NAME} against Qt 5 plugins because static linkage is enabled.") - # ensure platform integration plugins for corresponding platforms are built-in when creating a GUI application - if (WIN32) - use_static_qt5_plugin(Gui WindowsIntegration ON OFF) - elseif (APPLE) - use_static_qt5_plugin(Gui CocoaIntegration ON OFF) - elseif (TARGET ${QT5_Gui_STATIC_PREFIX}QXcbIntegrationPlugin) - use_static_qt5_plugin(Gui XcbIntegration ON OFF) - else () - message(WARNING "The required platform plugin for your platform is unknown an can not be linked in statically.") - endif () + if (Gui IN_LIST QT_MODULES OR Widgets IN_LIST QT_MODULES OR Quick IN_LIST QT_MODULES) + if (WIN32) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Gui PLUGINS WindowsIntegration ONLY_PLUGINS) + elseif (APPLE) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Gui PLUGINS CocoaIntegration ONLY_PLUGINS) + elseif (TARGET ${QT5_Gui_STATIC_PREFIX}QXcbIntegrationPlugin) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Gui PLUGINS XcbIntegration ONLY_PLUGINS) + else () + message(WARNING "The required platform plugin for your platform is unknown an can not be linked in statically.") + endif () + endif() # ensure all available widget style plugins are built-in when creating a Qt Widgets application note: required since Qt # 5.10 because the styles have been "pluginized" (see commit 4f3249f) set(KNOWN_WIDGET_STYLE_PLUGINS WindowsVistaStyle MacStyle AndroidStyle) set(USED_WIDGET_STYLE_PLUGINS) - if (QT5_Widgets_STATIC_LIB IN_LIST LIBRARIES OR QT5_Widgets_STATIC_LIB IN_LIST PRIVATE_LIBRARIES) + if (Widgets IN_LIST QT_MODULES) foreach (WIDGET_STYLE_PLUGIN ${KNOWN_WIDGET_STYLE_PLUGINS}) - if (TARGET "${QT5_Widgets_STATIC_PREFIX}Q${WIDGET_STYLE_PLUGIN}Plugin") - use_static_qt5_plugin(Widgets "${WIDGET_STYLE_PLUGIN}" ON OFF) + if (TARGET "${QT_PACKAGE_PREFIX}::Q${WIDGET_STYLE_PLUGIN}Plugin") + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Widgets PLUGINS ${WIDGET_STYLE_PLUGIN} ONLY_PLUGINS) list(APPEND USED_WIDGET_STYLE_PLUGINS "${WIDGET_STYLE_PLUGIN}") endif () endforeach () # allow importing image format plugins via config.h - include(ListToString) - list_to_string(" " "\\\n Q_IMPORT_PLUGIN(Q" "Plugin)" "${USED_WIDGET_STYLE_PLUGINS}" WIDGET_STYLE_PLUGINS_ARRAY) + if (USED_WIDGET_STYLE_PLUGINS) + include(ListToString) + list_to_string(" " "\\\n Q_IMPORT_PLUGIN(Q" "Plugin)" "${USED_WIDGET_STYLE_PLUGINS}" WIDGET_STYLE_PLUGINS_ARRAY) + endif () endif () # ensure image format plugins (beside SVG) are built-in if configured @@ -126,7 +129,7 @@ if (USING_STATIC_QT_GUI_FOR_APPLICATION) set(SVG_SUPPORT ON) list(REMOVE_ITEM IMAGE_FORMAT_SUPPORT Svg) else () - use_static_qt5_plugin(Gui "${IMAGE_FORMAT}" ON OFF) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Gui PLUGINS ${IMAGE_FORMAT} ONLY_PLUGINS) endif () endforeach () @@ -136,14 +139,14 @@ if (USING_STATIC_QT_GUI_FOR_APPLICATION) endif () # ensure SVG plugins are built-in if configured - if ((SVG_SUPPORT OR SVG_ICON_SUPPORT) AND NOT USE_STATIC_QT5_Svg) - find_qt5_module(Svg REQUIRED) + if ((SVG_SUPPORT OR SVG_ICON_SUPPORT) AND NOT Svg IN_LIST QT_MODULES) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Svg) endif () if (SVG_SUPPORT) - use_static_qt5_plugin(Svg Svg ON OFF) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Svg PLUGINS Svg ONLY_PLUGINS) endif () if (SVG_ICON_SUPPORT) - use_static_qt5_plugin(Svg SvgIcon ON OFF) + use_qt_module(PREFIX "${QT_PACKAGE_PREFIX}" MODULE Svg PLUGINS SvgIcon ONLY_PLUGINS) endif () endif () @@ -153,6 +156,10 @@ option(BUILTIN_TRANSLATIONS "enables/disables built-in translations when buildin # determine relevant Qt translation files set(QT_TRANSLATION_FILES) set(QT_TRANSLATION_SEARCH_PATHS) +query_qmake_variable(QT_INSTALL_TRANSLATIONS) +if (QT_INSTALL_TRANSLATIONS) + list(APPEND QT_TRANSLATION_SEARCH_PATHS "${QT_INSTALL_TRANSLATIONS}") +endif () if (CMAKE_FIND_ROOT_PATH) list(APPEND QT_TRANSLATION_SEARCH_PATHS "${CMAKE_FIND_ROOT_PATH}/share/qt/translations" "${CMAKE_FIND_ROOT_PATH}/share/qt5/translations") @@ -411,18 +418,18 @@ foreach (RES_FILE ${RES_FILES}) endforeach () # export Qt resources required by static libraries the static library depends on -if (STATIC_LIBRARIES_QT_RESOURCES) +if (META_PROJECT_IS_LIBRARY AND NOT BUILD_SHARED_LIBS AND STATIC_LIBRARIES_QT_RESOURCES) list(REMOVE_DUPLICATES STATIC_LIBRARIES_QT_RESOURCES) list(APPEND QT_RESOURCES ${STATIC_LIBRARIES_QT_RESOURCES}) endif () -# enable Qt resources required by static libraries the shared library or application depends on -if (LIBRARIES_QT_RESOURCES) - list(REMOVE_DUPLICATES LIBRARIES_QT_RESOURCES) +# enable Qt resources required by libraries the application depends on +if (QT_RESOURCES) + list(REMOVE_DUPLICATES QT_RESOURCES) # make enabling resources of static dependencies available via config.h unset(ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES) - foreach (QT_RESOURCE ${LIBRARIES_QT_RESOURCES}) + foreach (QT_RESOURCE ${STATIC_LIBRARIES_QT_RESOURCES}) set( ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES "${ENABLE_QT_RESOURCES_OF_STATIC_DEPENDENCIES} \\\n struct initializer_${QT_RESOURCE} { \\\n initializer_${QT_RESOURCE}() { Q_INIT_RESOURCE(${QT_RESOURCE}); } \\\n ~initializer_${QT_RESOURCE}() { Q_CLEANUP_RESOURCE(${QT_RESOURCE}); } \\\n } dummy_${QT_RESOURCE};" @@ -430,11 +437,6 @@ if (LIBRARIES_QT_RESOURCES) endforeach () endif () -# prevent duplicated resources -if (QT_RESOURCES) - list(REMOVE_DUPLICATES QT_RESOURCES) -endif () - # enable moc, uic and rcc by default for all targets set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) diff --git a/cmake/modules/QtGuiConfig.cmake b/cmake/modules/QtGuiConfig.cmake index 3e34ca4..7ec8bb3 100644 --- a/cmake/modules/QtGuiConfig.cmake +++ b/cmake/modules/QtGuiConfig.cmake @@ -10,6 +10,13 @@ if (TARGET_CONFIG_DONE) message(FATAL_ERROR "Can not include QtGuiConfig module when targets are already configured.") endif () +if (NOT WIDGETS_GUI AND NOT QUICK_GUI) + message(STATUS "GUI is completely disabled.") + return() +endif() + +list(APPEND ADDITIONAL_QT_MODULES Gui) + # enable Qt Widgets GUI if (WIDGETS_GUI) list(APPEND META_PRIVATE_COMPILE_DEFINITIONS GUI_QTWIDGETS) @@ -60,28 +67,26 @@ else () message(STATUS "Building WITHOUT Qt Quick GUI.") endif () -# do further GUI-related configuration only if at least one kind of GUI is enabled (tageditor allows building without GUI so -# this is a valid configuration) -if (WIDGETS_GUI OR QUICK_GUI) - if (WIN32) - # set "GUI-type" to WIN32 to hide console under Windows - set(GUI_TYPE WIN32) - elseif (APPLE) - # make the GUI application a "bundle" under MacOSX - set(GUI_TYPE MACOSX_BUNDLE) - endif () - - # add source files requried by both GUI variants - list(APPEND SRC_FILES ${GUI_SRC_FILES}) - list(APPEND ADDITIONAL_HEADER_FILES ${GUI_HEADER_FILES}) - - # add option for enabling/disabling static Qt plugins - option(SVG_SUPPORT "whether to link against the SVG image format plugin (only relevant when using static Qt)" ON) - option(SVG_ICON_SUPPORT "whether to link against the SVG icon engine (only relevant when using static Qt)" ON) - set(IMAGE_FORMAT_SUPPORT "Gif;ICO;Jpeg" - CACHE STRING "specifies the image format plugins to link against (only relevant when using static Qt)") - - if (ANDROID) - list(APPEND ADDITIONAL_QT_MODULES Svg) - endif () +# set platform-specific GUI-type +if (WIN32) + # set "GUI-type" to WIN32 to hide console under Windows + set(GUI_TYPE WIN32) +elseif (APPLE) + # make the GUI application a "bundle" under MacOSX + set(GUI_TYPE MACOSX_BUNDLE) +endif () + +# add source files requried by both GUI variants +list(APPEND SRC_FILES ${GUI_SRC_FILES}) +list(APPEND ADDITIONAL_HEADER_FILES ${GUI_HEADER_FILES}) + +# add option for enabling/disabling static Qt plugins +option(SVG_SUPPORT "whether to link against the SVG image format plugin (only relevant when using static Qt)" ON) +option(SVG_ICON_SUPPORT "whether to link against the SVG icon engine (only relevant when using static Qt)" ON) +set(IMAGE_FORMAT_SUPPORT "Gif;ICO;Jpeg" + CACHE STRING "specifies the image format plugins to link against (only relevant when using static Qt)") + +# always enable the Svg module under Android +if (ANDROID) + list(APPEND ADDITIONAL_QT_MODULES Svg) endif () diff --git a/cmake/modules/QtJsProviderConfig.cmake b/cmake/modules/QtJsProviderConfig.cmake new file mode 100644 index 0000000..7c643e0 --- /dev/null +++ b/cmake/modules/QtJsProviderConfig.cmake @@ -0,0 +1,51 @@ +# determines the JavaScript provider (either Qt Script or Qt Declarative) + +if (TARGET_CONFIG_DONE) + message(FATAL_ERROR "Can not include QtJsProviderConfig module when targets are already configured.") +endif () + +# configure the specified JavaScript provider +set(JS_PROVIDER "qml" CACHE STRING "specifies the JavaScript provider: qml (default), script or none") +if (JS_PROVIDER STREQUAL "script") + set(JS_PROVIDER Script) + set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_SCRIPT") + list(APPEND ADDITIONAL_QT_REPOS "script") + message(STATUS "Using Qt Script as JavaScript provider.") +elseif (JS_PROVIDER STREQUAL "qml") + set(JS_PROVIDER Qml) + set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_JSENGINE") + list(APPEND ADDITIONAL_QT_REPOS "declarative") + message(STATUS "Using Qt QML as JavaScript provider.") +elseif (JS_PROVIDER STREQUAL "none") + set(JS_PROVIDER "") + set(JS_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_JSENGINE") + message(STATUS "JavaScript provider has been disabled.") +else () + message(FATAL_ERROR "The specified JavaScript provider '${JS_PROVIDER}' is unknown.") +endif () + +# add header files with some defines/includes to conveniently use the selected provider +if (JS_PROVIDER) + list(APPEND ADDITIONAL_QT_MODULES "${JS_PROVIDER}") + + if (META_JS_SRC_DIR) + set(JS_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${META_JS_SRC_DIR}") + else () + set(JS_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") + endif () + + include(TemplateFinder) + find_template_file("jsdefs.h" QT_UTILITIES JS_DEFS_H_TEMPLATE_FILE) + configure_file("${JS_DEFS_H_TEMPLATE_FILE}" + "${JS_HEADER_DIR}/jsdefs.h" # simply add this to source to ease inclusion + NEWLINE_STYLE UNIX # since this goes to sources ensure consistency + ) + find_template_file("jsincludes.h" QT_UTILITIES JS_INCLUDES_H_TEMPLATE_FILE) + configure_file("${JS_INCLUDES_H_TEMPLATE_FILE}" + "${JS_HEADER_DIR}/jsincludes.h" # simply add this to source to ease inclusion + NEWLINE_STYLE UNIX # since this goes to sources ensure consistency + ) + list(APPEND WIDGETS_FILES "${JS_HEADER_DIR}/jsdefs.h" "${JS_HEADER_DIR}/jsincludes.h") +endif () + +list(APPEND META_PUBLIC_COMPILE_DEFINITIONS ${JS_DEFINITION}) diff --git a/cmake/modules/QtLinkage.cmake b/cmake/modules/QtLinkage.cmake index 55c2366..1ab56f9 100644 --- a/cmake/modules/QtLinkage.cmake +++ b/cmake/modules/QtLinkage.cmake @@ -8,136 +8,103 @@ if (DEFINED QT_LINKAGE_DETERMINED) endif () set(QT_LINKAGE_DETERMINED ON) -include(3rdParty) - # by default, require Qt 5.6 or higher if (NOT META_QT5_VERSION) set(META_QT5_VERSION 5.6) endif () -# determine whether to use dynamic or shared version of Qt (or both) -set(QT_LINKAGE "AUTO_LINKAGE" CACHE STRING "specifies whether to link statically or dynamically against Qt 5") -if (BUILD_STATIC_LIBS - OR ("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE" - AND ((STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") - OR (STATIC_LIBRARY_LINKAGE - AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) - OR ("${QT_LINKAGE}" STREQUAL "STATIC")) - set(USE_STATIC_QT_BUILD ON) - message( - STATUS "Checking for static Qt 5 libraries to use in project ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}") -endif () -if (("${QT_LINKAGE}" STREQUAL "AUTO_LINKAGE" - AND (NOT - (STATIC_LINKAGE AND "${META_PROJECT_TYPE}" STREQUAL "application") - OR NOT - (STATIC_LIBRARY_LINKAGE AND ("${META_PROJECT_TYPE}" STREQUAL "" OR "${META_PROJECT_TYPE}" STREQUAL "library")))) - OR ("${QT_LINKAGE}" STREQUAL "SHARED")) - set(USE_SHARED_QT_BUILD ON) - message( - STATUS "Checking for dynamic Qt 5 libraries to use in project ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}") -endif () +# define function for using Qt and KDE Frameworks modules and static plugins +include(3rdParty) +macro (use_qt_module) + # parse arguments + set(OPTIONAL_ARGS ONLY_PLUGINS) + set(ONE_VALUE_ARGS PREFIX MODULE VISIBILITY LIBRARIES_VARIABLE) + set(MULTI_VALUE_ARGS TARGETS PLUGINS) + cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) -macro (find_qt5_module MODULE REQUIRED) - # determine whether the library is required or optional FIXME: improve passing required argument - if ("${REQUIRED}" STREQUAL "OPTIONAL") - unset(QT_5_${MODULE}_REQUIRED) - elseif ("${REQUIRED}" STREQUAL "REQUIRED") - set(QT_5_${MODULE}_REQUIRED "REQUIRED") - else () - message(FATAL_ERROR "Invalid use of link_against_library; must specify either REQUIRED or OPTIONAL.") - endif () + # validate values + if (NOT ARGS_PREFIX) + message(FATAL_ERROR "use_qt_module called without PREFIX.") + endif() + if (NOT ARGS_MODULE) + message(FATAL_ERROR "use_qt_module called without MODULE.") + endif() + if (ARGS_VISIBILITY) + validate_visibility(${ARGS_VISIBILITY}) + else() + set (ARGS_VISIBILITY PRIVATE) + endif() + if (NOT ARGS_LIBRARIES_VARIABLE) + set (ARGS_LIBRARIES_VARIABLE "${ARGS_VISIBILITY}_LIBRARIES") + endif() + if (NOT ARGS_TARGETS) + if (${MODULE}_MODULE_TARGETS) + set(ARGS_TARGETS "${${MODULE}_MODULE_TARGETS}") + else() + set(ARGS_TARGETS "${ARGS_PREFIX}::${ARGS_MODULE}") + endif() + endif() + if (ARGS_ONLY_PLUGINS AND NOT ARGS_PLUGINS) + message(FATAL_ERROR "ONLY_PLUGINS specified but no plugins.") + endif() - # find static version - if (USE_STATIC_QT_BUILD) - # check for 'Static'-prefixed CMake module first - patched mingw-w64-qt5 packages providing those files are available - # in my PKGBUILDs repository - has the advantage that usage of dynamic and static Qt during the same build is - # possible - find_package(StaticQt5${MODULE} ${META_QT5_VERSION}) - if (StaticQt5${MODULE}_FOUND) - if (TARGET StaticQt5::${MODULE}) - set(QT5_${MODULE}_STATIC_PREFIX "StaticQt5::") - else () - set(QT5_${MODULE}_STATIC_PREFIX "Qt5::static::") - endif () - set(QT5_${MODULE}_STATIC_LIB "${QT5_${MODULE}_STATIC_PREFIX}${MODULE}") - set(QT5_${MODULE}_ASSUME_STATIC OFF) - set(QT5_${MODULE}_FOUND ON) - # reverse lookup for pkg-config - set(PC_PKG_STATIC_Qt5_${MODULE} "StaticQt5${MODULE}") - set(PC_PKG_STATIC_StaticQt5_${MODULE} "StaticQt5${MODULE}") - set(PC_PKG_STATIC_Qt5_static_${MODULE} "StaticQt5${MODULE}") - else () - # consider the regular Qt package (without "Static" prefix) the static version if static Qt is required and Qt - # package with "Static" prefix doesn't exist (fallback if not using patched version of Qt mentioned above) - find_package(Qt5${MODULE} ${META_QT5_VERSION} ${QT_5_${MODULE}_REQUIRED}) - if (Qt5${MODULE}_FOUND) - set(QT5_${MODULE}_STATIC_PREFIX "Qt5::") - set(QT5_${MODULE}_STATIC_LIB "${QT5_${MODULE}_STATIC_PREFIX}${MODULE}") - set(QT5_${MODULE}_ASSUME_STATIC ON) - set(QT5_${MODULE}_FOUND ON) - # reverse lookup for pkg-config - set(PC_PKG_STATIC_Qt5_${MODULE} "Qt5${MODULE}") - message( - WARNING - "Building static libs and/or static Qt linkage has been enabled. Hence assuming provided Qt 5 module ${MODULE} is static." - ) - endif () - endif () - - # use INTERFACE_LINK_LIBRARIES_RELEASE of the imported target as general INTERFACE_LINK_LIBRARIES to get correct - # transitive dependencies under any configuration - if (StaticQt5${MODULE}_FOUND OR Qt5${MODULE}_FOUND) - get_target_property(QT5_${MODULE}_STATIC_LIB_DEPS "${QT5_${MODULE}_STATIC_LIB}" INTERFACE_LINK_LIBRARIES_RELEASE) - set_target_properties("${QT5_${MODULE}_STATIC_LIB}" - PROPERTIES INTERFACE_LINK_LIBRARIES "${QT5_${MODULE}_STATIC_LIB_DEPS}") - endif () - endif () - - # find dynamic version - if (USE_SHARED_QT_BUILD) - if (QT5_${MODULE}_ASSUME_STATIC) + # find and use module + if (NOT ONLY_PLUGINS) + find_package("${ARGS_PREFIX}${ARGS_MODULE}" "${META_QT5_VERSION}" REQUIRED) + foreach(TARGET ${ARGS_TARGETS}) + if (NOT TARGET "${TARGET}") + message(FATAL_ERROR "The ${ARGS_PREFIX}${ARGS_MODULE} does not provide the target ${TARGET}.") + endif() + if ("${TARGET}" IN_LIST "${ARGS_LIBRARIES_VARIABLE}") + continue() + endif() + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};${TARGET}") + set("PKG_CONFIG_${ARGS_PREFIX}_${ARGS_MODULE}" "${ARGS_PREFIX}${ARGS_MODULE}") message( - FATAL_ERROR - "The provided Qt 5 module ${MODULE} is assumed to be static. However, a shared version is required for building dynamic libs and/or dynamic Qt linkage." + STATUS + "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} against Qt 5 module ${TARGET}." ) - endif () - find_package(Qt5${MODULE} ${META_QT5_VERSION} ${QT_5_${MODULE}_REQUIRED}) - if (Qt5${MODULE}_FOUND) - set(QT5_${MODULE}_DYNAMIC_LIB Qt5::${MODULE}) - set(QT5_${MODULE}_FOUND ON) - # reverse lookup for pkg-config - set(PC_PKG_SHARED_Qt5_${MODULE} "Qt5${MODULE}") - endif () - endif () -endmacro () -macro (use_qt5_module MODULE REQUIRED) - if (${MODULE} IN_LIST META_PUBLIC_QT_MODULES) - list(APPEND META_PUBLIC_SHARED_LIB_DEPENDS "${QT5_${MODULE}_DYNAMIC_LIB}") - list(APPEND META_PUBLIC_STATIC_LIB_DEPENDS "${QT5_${MODULE}_STATIC_LIB}") - endif () - link_against_library("QT5_${MODULE}" "${QT_LINKAGE}" "${REQUIRED}") -endmacro () + # hack for "StaticQt5": re-assign INTERFACE_LINK_LIBRARIES_RELEASE to INTERFACE_LINK_LIBRARIES + get_target_property("${ARGS_MODULE}_INTERFACE_LINK_LIBRARIES_RELEASE" "${TARGET}" INTERFACE_LINK_LIBRARIES_RELEASE) + if ("${ARGS_MODULE}_INTERFACE_LINK_LIBRARIES_RELEASE") + set_target_properties("${TARGET}" PROPERTIES INTERFACE_LINK_LIBRARIES "${${ARGS_MODULE}_INTERFACE_LINK_LIBRARIES_RELEASE}") + endif () + endforeach() + endif() -macro (use_static_qt5_plugin MODULE PLUGIN FOR_SHARED_TARGET FOR_STATIC_TARGET) - if ("${FOR_SHARED_TARGET}") - list(APPEND PRIVATE_LIBRARIES "${QT5_${MODULE}_STATIC_PREFIX}Q${PLUGIN}Plugin") + # find and use plugins + foreach (PLUGIN ${ARGS_PLUGINS}) + if (NOT TARGET "${ARGS_PREFIX}::Q${PLUGIN}Plugin") + find_package("${PREFIX}${MODULE}" "${META_QT5_VERSION}" REQUIRED) + endif() + if (NOT TARGET "${ARGS_PREFIX}::Q${PLUGIN}Plugin") + message(FATAL_ERROR "The ${ARGS_PREFIX}${MODULE} does not provide the target ${ARGS_PREFIX}::Q${PLUGIN}Plugin.") + endif() + if ("${ARGS_PREFIX}::Q${PLUGIN}Plugin" IN_LIST "${ARGS_LIBRARIES_VARIABLE}") + continue() + endif() + set("${ARGS_LIBRARIES_VARIABLE}" "${${ARGS_LIBRARIES_VARIABLE}};${ARGS_PREFIX}::Q${PLUGIN}Plugin") message( STATUS - "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} against static Qt 5 plugin ${QT5_${MODULE}_STATIC_PREFIX}Q${PLUGIN}Plugin" + "Linking ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX} against Qt 5 plugin ${ARGS_PREFIX}::Q${PLUGIN}Plugin." ) - endif () - if ("${FOR_STATIC_TARGET}") - list(APPEND PRIVATE_STATIC_LIBRARIES "${QT5_${MODULE}_STATIC_PREFIX}Q${PLUGIN}Plugin") - message( - STATUS - "Adding static Qt 5 plugin ${QT5_${MODULE}_STATIC_PREFIX}Q${PLUGIN}Plugin to dependencies of static ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" - ) - endif () -endmacro () + endforeach() -macro (query_qmake_variable QMAKE_VARIABLE) + # unset variables (can not simply use a function because Qt's variables need to be exported) + foreach (ARGUMENT ${OPTIONAL_ARGS} ${ONE_VALUE_ARGS} ${MULTI_VALUE_ARGS}) + unset(ARGS_${ARGUMENT}) + endforeach() +endmacro() + +# define function to make qmake variable available within CMake +function (query_qmake_variable QMAKE_VARIABLE) + # prevent queries for variables already known + if (NOT "${${QMAKE_VARIABLE}}" STREQUAL "") + return() + endif() + + # execute qmake get_target_property(QMAKE_BIN Qt5::qmake IMPORTED_LOCATION) execute_process(COMMAND "${QMAKE_BIN}" -query "${QMAKE_VARIABLE}" RESULT_VARIABLE "${QMAKE_VARIABLE}_RESULT" @@ -148,10 +115,15 @@ macro (query_qmake_variable QMAKE_VARIABLE) "Unable to read qmake variable ${QMAKE_VARIABLE} via \"${QMAKE_BIN} -query ${QMAKE_VARIABLE}\"; output was \"${${QMAKE_VARIABLE}}\"." ) endif () + + # remove new-line character at the end string(REGEX REPLACE "\n$" "" "${QMAKE_VARIABLE}" "${${QMAKE_VARIABLE}}") + + # export variable to parent scope + set("${QMAKE_VARIABLE}" "${${QMAKE_VARIABLE}}" PARENT_SCOPE) message(STATUS "qmake variable ${QMAKE_VARIABLE} is ${${QMAKE_VARIABLE}}") -endmacro () +endfunction() diff --git a/cmake/modules/QtWebViewProviderConfig.cmake b/cmake/modules/QtWebViewProviderConfig.cmake new file mode 100644 index 0000000..9cf28cd --- /dev/null +++ b/cmake/modules/QtWebViewProviderConfig.cmake @@ -0,0 +1,50 @@ +# determines the web view provider (either Qt WebKit or Qt WebEngine) + +if (TARGET_CONFIG_DONE) + message(FATAL_ERROR "Can not include QtWebViewProviderConfig module when targets are already configured.") +endif () + +# configure the specified web view provider +set(WEBVIEW_PROVIDER "webengine" CACHE STRING "specifies the web view provider: webengine (default), webkit or none") +if (WEBVIEW_PROVIDER STREQUAL "webkit") + set(WEBVIEW_PROVIDER WebKitWidgets) + set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBKIT") + message(STATUS "Using Qt WebKit as web view provider.") +elseif (WEBVIEW_PROVIDER STREQUAL "webengine") + set(WEBVIEW_PROVIDER WebEngineWidgets) + set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBENGINE") + list(APPEND ADDITIONAL_QT_REPOS "webengine") + message(STATUS "Using Qt WebEngine as web view provider.") +elseif (WEBVIEW_PROVIDER STREQUAL "none") + set(WEBVIEW_PROVIDER "") + set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_WEBVIEW") + message(STATUS "Built-in web view has been disabled.") +else () + message(FATAL_ERROR "The specified web view provider '${WEBVIEW_PROVIDER}' is unknown.") +endif () + +# add header files with some defines/includes to conveniently use the selected provider +if (WEBVIEW_PROVIDER) + list(APPEND ADDITIONAL_QT_MODULES "${WEBVIEW_PROVIDER}") + + if (META_WEBVIEW_SRC_DIR) + set(WEBVIEW_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${META_WEBVIEW_SRC_DIR}") + else () + set(WEBVIEW_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") + endif () + + include(TemplateFinder) + find_template_file("webviewdefs.h" QT_UTILITIES WEBVIEWDEFS_H_TEMPLATE_FILE) + configure_file("${WEBVIEWDEFS_H_TEMPLATE_FILE}" + "${WEBVIEW_HEADER_DIR}/webviewdefs.h" # simply add this to source to ease inclusion + NEWLINE_STYLE UNIX # since this goes to sources ensure consistency + ) + find_template_file("webviewincludes.h" QT_UTILITIES WEBVIEWINCLUDES_H_TEMPLATE_FILE) + configure_file("${WEBVIEWINCLUDES_H_TEMPLATE_FILE}" + "${WEBVIEW_HEADER_DIR}/webviewincludes.h" # simply add this to source to ease inclusion + NEWLINE_STYLE UNIX # since this goes to sources ensure consistency + ) + list(APPEND WIDGETS_FILES "${WEBVIEW_HEADER_DIR}/webviewdefs.h" "${WEBVIEW_HEADER_DIR}/webviewincludes.h") +endif () + +list(APPEND META_PUBLIC_COMPILE_DEFINITIONS ${WEBVIEW_DEFINITION}) diff --git a/cmake/modules/WebViewProviderConfig.cmake b/cmake/modules/WebViewProviderConfig.cmake deleted file mode 100644 index 0af33b9..0000000 --- a/cmake/modules/WebViewProviderConfig.cmake +++ /dev/null @@ -1,74 +0,0 @@ -# determines the web view provider (either Qt WebKit or Qt WebEngine) - -if (TARGET_CONFIG_DONE) - message(FATAL_ERROR "Can not include WebViewProviderConfig module when targets are already configured.") -endif () - -include(QtLinkage) - -set(WEBVIEW_PROVIDER "auto" CACHE STRING "specifies the web view provider: auto (default), webkit, webengine or none") -if (NOT WEBVIEW_PROVIDER OR "${WEBVIEW_PROVIDER}" STREQUAL "auto") - find_qt5_module(WebKitWidgets OPTIONAL) - if (QT5_WebKitWidgets_FOUND) - set(WEBVIEW_PROVIDER WebKitWidgets) - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBKIT") - message(STATUS "No web view provider explicitly specified, defaulting to Qt WebKit.") - else () - find_qt5_module(WebEngineWidgets OPTIONAL) - if (QT5_WebEngineWidgets_FOUND) - set(WEBVIEW_PROVIDER WebEngineWidgets) - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBENGINE") - list(APPEND ADDITIONAL_QT_REPOS "webengine") - message(STATUS "No web view provider explicitly specified, defaulting to Qt WebEngine.") - else () - set(WEBVIEW_PROVIDER "") - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_WEBVIEW") - message(STATUS "No web view provider available, web view has been disabled.") - endif () - endif () -else () - if (${WEBVIEW_PROVIDER} STREQUAL "webkit") - find_qt5_module(WebKitWidgets REQUIRED) - set(WEBVIEW_PROVIDER WebKitWidgets) - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBKIT") - message(STATUS "Using Qt WebKit as web view provider.") - elseif (${WEBVIEW_PROVIDER} STREQUAL "webengine") - find_qt5_module(WebEngineWidgets REQUIRED) - set(WEBVIEW_PROVIDER WebEngineWidgets) - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_USE_WEBENGINE") - list(APPEND ADDITIONAL_QT_REPOS "webengine") - message(STATUS "Using Qt WebEngine as web view provider.") - elseif (${WEBVIEW_PROVIDER} STREQUAL "none") - set(WEBVIEW_DEFINITION "${META_PROJECT_VARNAME_UPPER}_NO_WEBVIEW") - set(WEBVIEW_PROVIDER "") - message(STATUS "Web view has been disabled.") - else () - message(FATAL_ERROR "The specified web view provider '${WEBVIEW_PROVIDER}' is unknown.") - endif () -endif () - -if (WEBVIEW_PROVIDER) - # require the selected Qt module - use_qt5_module(${WEBVIEW_PROVIDER} REQUIRED) - - # add header files with some defines/includes to conveniently use the selected provider - if (META_WEBVIEW_SRC_DIR) - set(WEBVIEW_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${META_WEBVIEW_SRC_DIR}") - else () - set(WEBVIEW_HEADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/gui") - endif () - include(TemplateFinder) - find_template_file("webviewdefs.h" QT_UTILITIES WEBVIEWDEFS_H_TEMPLATE_FILE) - configure_file("${WEBVIEWDEFS_H_TEMPLATE_FILE}" - "${WEBVIEW_HEADER_DIR}/webviewdefs.h" # simply add this to source to ease inclusion - NEWLINE_STYLE UNIX # since this goes to sources ensure consistency - ) - find_template_file("webviewincludes.h" QT_UTILITIES WEBVIEWINCLUDES_H_TEMPLATE_FILE) - configure_file("${WEBVIEWINCLUDES_H_TEMPLATE_FILE}" - "${WEBVIEW_HEADER_DIR}/webviewincludes.h" # simply add this to source to ease inclusion - NEWLINE_STYLE UNIX # since this goes to sources ensure consistency - ) - list(APPEND WIDGETS_FILES "${WEBVIEW_HEADER_DIR}/webviewdefs.h" "${WEBVIEW_HEADER_DIR}/webviewincludes.h") -endif () - -list(APPEND META_PUBLIC_COMPILE_DEFINITIONS ${WEBVIEW_DEFINITION})