From 5b43f2776fa53bfe15a5b3b4398dfe3e931d5802 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 19 Mar 2014 21:00:07 +0100 Subject: [PATCH] Simplify handling of (dual-)Qt in the build system We've used a somewhat complex way to link the various targets to the required Qt libraries (and use the correct defines and CFLAGS...), because when that stuff was written, there were no target properties in CMake, and thus it was not easily possible to build targets within the same scope with different settings. Therefore, we couldn't use the QT_USE_FILE and had to write our own library handling. These days, target properties exist, and Qt5 came up with a nice way to attach the needed properties based on the Qt modules in use: qt5_use_modules() This was later backported to Qt4, too, replacing the old way of having to include QT_USE_FILE which would then set global variables. We now make use of this; because qt4_use_modules() only showed up in CMake 2.8.10, we've copied that function. It will be used only if it's not present in CMake proper. As a bonus, I've also wrapped all the qt-related macros into functions that do the check for the Qt version we want to build against, and select the proper macro to call, thus removing lots of WITH_QT5 conditionals from the rest of the build system. Note that Qt5 support is still incomplete, anyway. --- CMakeLists.txt | 5 +- cmake/QuasselMacros.cmake | 125 +++++++++++++++++++++++++---------- src/CMakeLists.txt | 41 +++++------- src/client/CMakeLists.txt | 25 +++---- src/common/CMakeLists.txt | 6 +- src/core/CMakeLists.txt | 7 +- src/qtui/CMakeLists.txt | 58 ++++++---------- src/uisupport/CMakeLists.txt | 15 ++--- 8 files changed, 154 insertions(+), 128 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcc95309..686c96f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,11 +34,14 @@ set(QUASSEL_MINOR 11) set(QUASSEL_PATCH 0) set(QUASSEL_VERSION_STRING "0.11-pre") -# Tell CMake about or own stuff +# Tell CMake about or own modules set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) +# General conveniences set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# Moar stuff include(CheckFunctionExists) include(CheckIncludeFile) diff --git a/cmake/QuasselMacros.cmake b/cmake/QuasselMacros.cmake index f0791ec6..eb9dca6d 100644 --- a/cmake/QuasselMacros.cmake +++ b/cmake/QuasselMacros.cmake @@ -1,41 +1,98 @@ -# This macro sets variables for the Qt modules we need. +# This file contains various macros useful for building Quassel. +# +# (C) 2014 by the Quassel Project +# +# The qt4_use_modules function was taken from CMake's Qt4Macros.cmake: +# (C) 2005-2009 Kitware, Inc. +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -macro(setup_qt_variables) - set(QUASSEL_QT_LIBRARIES ) - set(QUASSEL_QT_INCLUDES ${QT_INCLUDE_DIR}) # Qt4 - set(QUASSEL_QT_DEFINITIONS ${QT_DEFINITIONS}) # Qt4 +############################ +# Macros for dealing with Qt +############################ - IF(WIN32) - set(MAIN Main) - ENDIF(WIN32) - foreach(qtmod Core ${ARGV} ${MAIN}) - if(WITH_QT5) - find_package(Qt5${qtmod} ${QT_MIN_VERSION} REQUIRED) - list(APPEND QUASSEL_QT_LIBRARIES ${Qt5${qtmod}_LIBRARIES}) - list(APPEND QUASSEL_QT_INCLUDES ${Qt5${qtmod}_INCLUDE_DIRS}) - list(APPEND QUASSEL_QT_DEFINITIONS ${Qt5${qtmod}_DEFINITIONS} ${Qt5${qtmod}_EXECUTABLE_COMPILE_FLAGS}) - else(WITH_QT5) - string(TOUPPER ${qtmod} QTMOD) - list(APPEND QUASSEL_QT_LIBRARIES ${QT_QT${QTMOD}_LIBRARY}) - if(STATIC) - list(APPEND QUASSEL_QT_LIBRARIES ${QT_QT${QTMOD}_LIB_DEPENDENCIES}) - endif(STATIC) - list(APPEND QUASSEL_QT_INCLUDES ${QT_QT${QTMOD}_INCLUDE_DIR}) - list(APPEND QUASSEL_QT_DEFINITIONS -DQT_QT${QTMOD}_LIB) - endif(WITH_QT5) - endforeach(qtmod) +# CMake gained this function in 2.8.10. To be able to use older versions, we've copied +# this here. If present, the function from CMake will take precedence and our copy will be ignored. +function(quassel_qt4_use_modules _target _link_type) + message("SPUT calling") + if ("${_link_type}" STREQUAL "LINK_PUBLIC" OR "${_link_type}" STREQUAL "LINK_PRIVATE") + set(modules ${ARGN}) + set(link_type ${_link_type}) + else() + set(modules ${_link_type} ${ARGN}) + endif() + foreach(_module ${modules}) + string(TOUPPER ${_module} _ucmodule) + set(_targetPrefix QT_QT${_ucmodule}) + if (_ucmodule STREQUAL QAXCONTAINER OR _ucmodule STREQUAL QAXSERVER) + if (NOT QT_Q${_ucmodule}_FOUND) + message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") + endif() + set(_targetPrefix QT_Q${_ucmodule}) + else() + if (NOT QT_QT${_ucmodule}_FOUND) + message(FATAL_ERROR "Can not use \"${_module}\" module which has not yet been found.") + endif() + if ("${_ucmodule}" STREQUAL "MAIN") + message(FATAL_ERROR "Can not use \"${_module}\" module with qt4_use_modules.") + endif() + endif() + target_link_libraries(${_target} ${link_type} ${${_targetPrefix}_LIBRARIES}) + set_property(TARGET ${_target} APPEND PROPERTY INCLUDE_DIRECTORIES ${${_targetPrefix}_INCLUDE_DIR} ${QT_HEADERS_DIR} ${QT_MKSPECS_DIR}/default) + set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS ${${_targetPrefix}_COMPILE_DEFINITIONS}) + endforeach() +endfunction() - list(REMOVE_DUPLICATES QUASSEL_QT_LIBRARIES) - list(REMOVE_DUPLICATES QUASSEL_QT_INCLUDES) - list(REMOVE_DUPLICATES QUASSEL_QT_DEFINITIONS) +# Some wrappers for simplifying dual-Qt support - # The COMPILE_FLAGS property expects a string, not a list... - set(QUASSEL_QT_COMPILEFLAGS ) - foreach(flag ${QUASSEL_QT_DEFINITIONS}) - set(QUASSEL_QT_COMPILEFLAGS "${QUASSEL_QT_COMPILEFLAGS} ${flag}") - endforeach(flag) +function(qt_use_modules) + if (WITH_QT5) + qt5_use_modules(${ARGN}) + else() + qt4_use_modules(${ARGN}) + endif() +endfunction() -endmacro(setup_qt_variables) +function(qt_wrap_ui _var) + if (WITH_QT5) + qt5_wrap_ui(var ${ARGN}) + else() + qt4_wrap_ui(var ${ARGN}) + endif() + set(${_var} ${${_var}} ${var} PARENT_SCOPE) +endfunction() + +function(qt_add_resources _var) + if (WITH_QT5) + qt5_add_resources(var ${ARGN}) + else() + qt4_add_resources(var ${ARGN}) + endif() + set(${_var} ${${_var}} ${var} PARENT_SCOPE) +endfunction() + +function(qt_add_dbus_interface _var) + if (WITH_QT5) + qt5_add_dbus_interface(var ${ARGN}) + else() + qt4_add_dbus_interface(var ${ARGN}) + endif() + set(${_var} ${${_var}} ${var} PARENT_SCOPE) +endfunction() + +function(qt_add_dbus_adaptor _var) + if (WITH_QT5) + qt5_add_dbus_adaptor(var ${ARGN}) + else() + qt4_add_dbus_adaptor(var ${ARGN}) + endif() + set(${_var} ${${_var}} ${var} PARENT_SCOPE) +endfunction() + +###################################### +# Macros for dealing with translations +###################################### # This generates a .ts from a .po file macro(generate_ts outvar basename) @@ -50,7 +107,7 @@ macro(generate_ts outvar basename) # This is a workaround to add (duplicate) strings that lconvert missed to the .ts COMMAND ${QT_LUPDATE_EXECUTABLE} ARGS -silent - ${CMAKE_SOURCE_DIR}/src/ + ${CMAKE_SOURCE_DIR}/src/ -ts ${output} DEPENDS ${basename}.po) set(${outvar} ${output}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 244d3941..ad964979 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,52 +24,45 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) # for version.gen # Add resources. Can't be done in other subdirs apparently. # Note that these variables need to contain paths relative to src/ (this dir) -if(WITH_QT5) - qt5_add_resources(CLIENT_DEPS ${CLIENT_RCS}) - qt5_add_resources(CORE_DEPS ${CORE_RCS}) - qt5_add_resources(COMMON_DEPS ${COMMON_RCS}) -else(WITH_QT5) - qt4_add_resources(CLIENT_DEPS ${CLIENT_RCS}) - qt4_add_resources(CORE_DEPS ${CORE_RCS}) - qt4_add_resources(COMMON_DEPS ${COMMON_RCS}) -endif(WITH_QT5) +qt_add_resources(CLIENT_DEPS ${CLIENT_RCS}) +qt_add_resources(CORE_DEPS ${CORE_RCS}) +qt_add_resources(COMMON_DEPS ${COMMON_RCS}) + +# For Windows, Qt4 needs the QtMain module +if (WIN32 AND NOT WITH_QT5) + set(MAIN Main) +endif() if(WANT_CORE) - setup_qt_variables(Network Script Sql ${CORE_QT_MODULES}) - include_directories(${QUASSEL_QT_INCLUDES}) add_executable(quasselcore common/main.cpp ${COMMON_DEPS} ${CORE_DEPS}) + qt_use_modules(quasselcore Core Network ${CORE_QT_MODULES} ${MAIN}) add_dependencies(quasselcore po) set_target_properties(quasselcore PROPERTIES - COMPILE_FLAGS "-DBUILD_CORE ${QUASSEL_QT_COMPILEFLAGS}" + COMPILE_FLAGS "-DBUILD_CORE" OUTPUT_NAME ../quasselcore) - target_link_libraries(quasselcore mod_core mod_common ${COMMON_LIBRARIES} - ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES}) + target_link_libraries(quasselcore mod_core mod_common ${COMMON_LIBRARIES} ${QUASSEL_SSL_LIBRARIES}) install(TARGETS quasselcore RUNTIME DESTINATION ${BIN_INSTALL_DIR}) endif(WANT_CORE) if(WANT_QTCLIENT) - setup_qt_variables(Gui Network ${CLIENT_QT_MODULES}) - include_directories(${QUASSEL_QT_INCLUDES}) add_executable(quasselclient WIN32 common/main.cpp ${COMMON_DEPS} ${CLIENT_DEPS}) + qt_use_modules(quasselclient Core Gui Network ${CLIENT_QT_MODULES} ${MAIN}) add_dependencies(quasselclient po) set_target_properties(quasselclient PROPERTIES - COMPILE_FLAGS "-DBUILD_QTUI ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}" + COMPILE_FLAGS "-DBUILD_QTUI ${CLIENT_COMPILE_FLAGS}" OUTPUT_NAME ../quasselclient) - target_link_libraries(quasselclient ${LINK_KDE} mod_qtui mod_uisupport mod_client mod_common ${COMMON_LIBRARIES} - ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES} ${CLIENT_LIBRARIES}) + target_link_libraries(quasselclient ${LINK_KDE} mod_qtui mod_uisupport mod_client mod_common ${COMMON_LIBRARIES} ${CLIENT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES}) install(TARGETS quasselclient RUNTIME DESTINATION ${BIN_INSTALL_DIR}) endif(WANT_QTCLIENT) if(WANT_MONO) - setup_qt_variables(Gui Network Script Sql ${CLIENT_QT_MODULES} ${CORE_QT_MODULES}) - include_directories(${QUASSEL_QT_INCLUDES}) add_executable(quassel WIN32 common/main.cpp qtui/monoapplication.cpp ${COMMON_DEPS} ${CLIENT_DEPS} ${CORE_DEPS}) + qt_use_modules(quassel Core Gui Network ${CLIENT_QT_MODULES} ${CORE_QT_MODULES} ${MAIN}) add_dependencies(quassel po) set_target_properties(quassel PROPERTIES - COMPILE_FLAGS "-DBUILD_MONO ${QUASSEL_QT_COMPILEFLAGS} ${CLIENT_COMPILE_FLAGS}" + COMPILE_FLAGS "-DBUILD_MONO ${CLIENT_COMPILE_FLAGS}" OUTPUT_NAME ../quassel) - target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${COMMON_LIBRARIES} - ${QUASSEL_QT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES} ${CLIENT_LIBRARIES}) + target_link_libraries(quassel mod_qtui mod_uisupport mod_client mod_core mod_common ${COMMON_LIBRARIES} ${CLIENT_LIBRARIES} ${QUASSEL_SSL_LIBRARIES}) install(TARGETS quassel RUNTIME DESTINATION ${BIN_INSTALL_DIR}) endif(WANT_MONO) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index c149f256..31f0a4b6 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -1,20 +1,8 @@ # Builds the client module -# In Qt4, we still have some minor deps to QtUi: QItemSelectionModel, QSortFilterProxyModel +# In Qt4, we still have some minor deps to QtGui: QItemSelectionModel, QSortFilterProxyModel # Still in Qt5: QAbstractItemView in BufferModel -set(_modules ) - -if(WITH_QT5) - list(APPEND _modules Widgets) -endif(WITH_QT5) - -if(HAVE_DBUS) - list(APPEND _modules DBus) -endif(HAVE_DBUS) - -setup_qt_variables(Gui Network ${_modules}) - set(SOURCES abstractmessageprocessor.cpp backlogrequester.cpp @@ -50,9 +38,14 @@ set(SOURCES clientcoreinfo.h ) -include_directories(${CMAKE_SOURCE_DIR}/src/common ${QUASSEL_QT_INCLUDES}) +if (WITH_QT5) + list(APPEND qt_modules Widgets) +endif() + +if (HAVE_DBUS) + list(APPEND qt_modules DBus) +endif() add_library(mod_client STATIC ${SOURCES}) +qt_use_modules(mod_client Network Core Gui ${qt_modules}) add_dependencies(mod_client mod_common) - -set_target_properties(mod_client PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}") diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 8690625e..46835e50 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,7 +1,5 @@ # Builds the common module -setup_qt_variables(Core Network) - set(SOURCES aliasmanager.cpp authhandler.cpp @@ -67,10 +65,8 @@ if(CMAKE_HOST_UNIX) set(SOURCES ${SOURCES} logbacktrace_unix.cpp) endif(CMAKE_HOST_UNIX) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${QUASSEL_QT_INCLUDES}) # for version.inc and version.gen - add_library(mod_common STATIC ${SOURCES}) -set_target_properties(mod_common PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}") +qt_use_modules(mod_common Core Network) if(APPLE) target_link_libraries(mod_common "-framework CoreServices" "-framework CoreFoundation") diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a167d8f2..25e14884 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,7 +1,5 @@ # Builds the core module -setup_qt_variables(Network Sql Script) - set(SOURCES abstractsqlstorage.cpp core.cpp @@ -52,13 +50,14 @@ if(HAVE_QCA2) include_directories(${QCA2_INCLUDE_DIR}) endif(HAVE_QCA2) -include_directories(${CMAKE_SOURCE_DIR}/src/common ${QUASSEL_QT_INCLUDES}) +include_directories(${CMAKE_SOURCE_DIR}/src/common) set(CORE_RCS ${CORE_RCS} core/sql.qrc PARENT_SCOPE) add_library(mod_core STATIC ${SOURCES}) +qt_use_modules(mod_core Core Network Script Sql) + add_dependencies(mod_core mod_common) -set_target_properties(mod_core PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}") if(HAVE_QCA2) target_link_libraries(mod_core ${QCA2_LIBRARIES}) diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt index 311931e9..e2f7eb06 100644 --- a/src/qtui/CMakeLists.txt +++ b/src/qtui/CMakeLists.txt @@ -1,21 +1,5 @@ # Builds the qtui module -set(_modules ) - -if(WITH_QT5) - list(APPEND _modules Widgets) -endif(WITH_QT5) - -if(HAVE_DBUS) - list(APPEND _modules DBus) -endif(HAVE_DBUS) - -if(HAVE_WEBKIT) - list(APPEND _modules Webkit XmlPatterns) -endif(HAVE_WEBKIT) - -setup_qt_variables(Gui Network ${_modules}) - set(SOURCES aboutdlg.cpp awaylogfilter.cpp @@ -107,18 +91,11 @@ else(HAVE_KDE) endif(HAVE_PHONON) endif(HAVE_KDE) -if(HAVE_DBUS) - set(SOURCES ${SOURCES} statusnotifieritem.cpp statusnotifieritemdbus.cpp dockmanagernotificationbackend.cpp) - set(FORMS ${FORMS}) - if(WITH_QT5) - qt5_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher) - qt5_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient) - qt5_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus) - else(WITH_QT5) - qt4_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher) - qt4_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient) - qt4_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus) - endif(WITH_QT5) +if (HAVE_DBUS) + set(SOURCES ${SOURCES} statusnotifieritem.cpp statusnotifieritemdbus.cpp dockmanagernotificationbackend.cpp) + qt_add_dbus_interface(DBUS ../../interfaces/org.kde.StatusNotifierWatcher.xml statusnotifierwatcher) + qt_add_dbus_interface(DBUS ../../interfaces/org.freedesktop.Notifications.xml notificationsclient) + qt_add_dbus_adaptor(DBUS ../../interfaces/org.kde.StatusNotifierItem.xml statusnotifieritemdbus.h StatusNotifierItemDBus) endif(HAVE_DBUS) if(HAVE_SSL) @@ -158,15 +135,24 @@ include_directories(${CMAKE_SOURCE_DIR}/src/common ${CMAKE_SOURCE_DIR}/src/qtui ${CMAKE_SOURCE_DIR}/src/qtui/settingspages ${CMAKE_SOURCE_DIR}/src/uisupport - ${CMAKE_CURRENT_BINARY_DIR} - ${QUASSEL_QT_INCLUDES}) -if(WITH_QT5) - qt5_wrap_ui(UI ${FORMPATH} ${SPFRM}) -else(WITH_QT5) - qt4_wrap_ui(UI ${FORMPATH} ${SPFRM}) -endif(WITH_QT5) +) + +qt_wrap_ui(UI ${FORMPATH} ${SPFRM}) + +if (WITH_QT5) + list(APPEND qt_modules Widgets) +endif() + +if (HAVE_DBUS) + list(APPEND qt_modules DBus) +endif() + +if (HAVE_WEBKIT) + list(APPEND qt_modules Webkit XmlPatterns) +endif() add_library(mod_qtui STATIC ${SOURCES} ${SPSRC} ${DBUS} ${UI}) +qt_use_modules(mod_qtui Core Gui Network ${qt_modules}) + add_dependencies(mod_qtui mod_common mod_client mod_uisupport) -set_target_properties(mod_qtui PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}") diff --git a/src/uisupport/CMakeLists.txt b/src/uisupport/CMakeLists.txt index 1b4f1769..0505d92a 100644 --- a/src/uisupport/CMakeLists.txt +++ b/src/uisupport/CMakeLists.txt @@ -1,11 +1,5 @@ # Builds the uisupport module -if(WITH_QT5) - setup_qt_variables(Widgets Network) -else(WITH_QT5) - setup_qt_variables(Gui Network) -endif(WITH_QT5) - set(SOURCES abstractbuffercontainer.cpp abstractitemview.cpp @@ -48,12 +42,17 @@ endif(HAVE_KDE) include_directories(${CMAKE_SOURCE_DIR}/src/common ${CMAKE_SOURCE_DIR}/src/client - ${QUASSEL_QT_INCLUDES}) +) if(HAVE_QCA2) include_directories(${QCA2_INCLUDE_DIR}) endif(HAVE_QCA2) +if (WITH_QT5) + list(APPEND qt_modules Widgets) +endif() + add_library(mod_uisupport STATIC ${SOURCES}) +qt_use_modules(mod_uisupport Core Gui Network ${qt_modules}) + add_dependencies(mod_uisupport mod_common mod_client) -set_target_properties(mod_uisupport PROPERTIES COMPILE_FLAGS "${QUASSEL_QT_COMPILEFLAGS}") -- 2.20.1