Don't mix building static and shared libraries

This commit is contained in:
Martchus 2019-04-04 19:13:30 +02:00
parent 3502be2826
commit c707591128
8 changed files with 291 additions and 360 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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