diff --git a/CMakeLists.txt b/CMakeLists.txt index 35ae849b6..40b1bc4bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -183,11 +183,9 @@ find_package(Threads REQUIRED) message(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}") +# Find Qt, min version is defined in that .cmake file include(FindQtRuntime) -# Qt is located through normal CMake package discovery -find_package(Qt6 6.4 REQUIRED) - set(CMAKE_AUTOMOC TRUE) ## Find other needed libraries diff --git a/cmake/FindQtRuntime.cmake b/cmake/FindQtRuntime.cmake index c0e94df68..c549d9c25 100644 --- a/cmake/FindQtRuntime.cmake +++ b/cmake/FindQtRuntime.cmake @@ -1,21 +1,32 @@ +# FindQtRuntime.cmake +# # Find a compatible Qt version -# Inputs: WITH_SERVER, WITH_CLIENT, WITH_ORACLE -# Optional Input: QT6_DIR -- Hint as to where Qt6 lives on the system -# Output: COCKATRICE_QT_VERSION_NAME -- Example values: Qt6 -# Output: SERVATRICE_QT_MODULES -# Output: COCKATRICE_QT_MODULES -# Output: ORACLE_QT_MODULES -# Output: TEST_QT_MODULES +# +# Inputs: +# WITH_SERVER +# WITH_CLIENT +# WITH_ORACLE +# TEST +# +# Outputs: +# COCKATRICE_QT_VERSION_NAME +# QT_CORE_MODULE +# SERVATRICE_QT_MODULES +# COCKATRICE_QT_MODULES +# ORACLE_QT_MODULES +# TEST_QT_MODULES +# QT_LIBRARY_DIR +# QT_PLUGINS_DIR -set(REQUIRED_QT_COMPONENTS Core) +set(COCKATRICE_QT_VERSION_NAME Qt6) -if(WITH_SERVER) - list(APPEND REQUIRED_QT_COMPONENTS Network Sql WebSockets) -endif() -if(WITH_CLIENT) - list( - APPEND - REQUIRED_QT_COMPONENTS +# --------------------------------------------------------------------------- +# Define the Qt components required by each target +# --------------------------------------------------------------------------- + +set(SERVATRICE_QT_COMPONENTS Network Sql WebSockets) + +set(COCKATRICE_QT_COMPONENTS Concurrent Gui Multimedia @@ -28,60 +39,142 @@ if(WITH_CLIENT) Xml Quick QuickWidgets - ) +) + +set(ORACLE_QT_COMPONENTS Concurrent Network Svg Widgets) + +set(TEST_QT_COMPONENTS Concurrent Network Svg Widgets) + +# --------------------------------------------------------------------------- +# Determine which Qt components are required for this build +# --------------------------------------------------------------------------- + +set(REQUIRED_QT_COMPONENTS Core) + +if(WITH_SERVER) + list(APPEND REQUIRED_QT_COMPONENTS ${SERVATRICE_QT_COMPONENTS}) endif() + +if(WITH_CLIENT) + list(APPEND REQUIRED_QT_COMPONENTS ${COCKATRICE_QT_COMPONENTS}) +endif() + if(WITH_ORACLE) - list(APPEND REQUIRED_QT_COMPONENTS Concurrent Network Svg Widgets) + list(APPEND REQUIRED_QT_COMPONENTS ${ORACLE_QT_COMPONENTS}) endif() + if(TEST) - # Union of Qt modules required across all test targets (independent of application targets). - # When adding a new test that needs additional Qt modules, add them here rather than in the test's CMakeLists.txt - list(APPEND REQUIRED_QT_COMPONENTS Concurrent Network Svg Widgets) + list(APPEND REQUIRED_QT_COMPONENTS ${TEST_QT_COMPONENTS}) endif() list(REMOVE_DUPLICATES REQUIRED_QT_COMPONENTS) -# Find Qt and all required components including Linguist -find_package(Qt6 REQUIRED COMPONENTS ${REQUIRED_QT_COMPONENTS} Linguist) -message(STATUS "Qt6_VERSION = ${Qt6_VERSION}") -message(STATUS "Qt6_DIR = ${Qt6_DIR}") -message(STATUS "Qt6Core_DIR = ${Qt6Core_DIR}") -message(STATUS "TEST=${TEST}") -message(STATUS "TEST_QT_MODULES=${TEST_QT_MODULES}") +# --------------------------------------------------------------------------- +# Find Qt and define minimum version centrally +# --------------------------------------------------------------------------- -set(COCKATRICE_QT_VERSION_NAME Qt6) +find_package(Qt6 6.4 REQUIRED COMPONENTS ${REQUIRED_QT_COMPONENTS} Linguist) -list(FIND Qt6LinguistTools_TARGETS Qt6::lrelease QT6_LRELEASE_INDEX) -if(QT6_LRELEASE_INDEX EQUAL -1) +# --------------------------------------------------------------------------- +# Convert a component list such as: +# Network;Sql;WebSockets +# into: +# Qt6::Network;Qt6::Sql;Qt6::WebSockets +# --------------------------------------------------------------------------- + +function(_qt_components_to_targets COMPONENTS OUTPUT_VARIABLE) + set(TARGETS) + + foreach(COMPONENT IN LISTS COMPONENTS) + list(APPEND TARGETS "${COCKATRICE_QT_VERSION_NAME}::${COMPONENT}") + endforeach() + + set(${OUTPUT_VARIABLE} + "${TARGETS}" + PARENT_SCOPE + ) +endfunction() + +# --------------------------------------------------------------------------- +# Export Qt target lists for the individual targets +# --------------------------------------------------------------------------- + +if(WITH_SERVER) + _qt_components_to_targets("${SERVATRICE_QT_COMPONENTS}" SERVATRICE_QT_MODULES) +endif() + +if(WITH_CLIENT) + _qt_components_to_targets("${COCKATRICE_QT_COMPONENTS}" COCKATRICE_QT_MODULES) +endif() + +if(WITH_ORACLE) + _qt_components_to_targets("${ORACLE_QT_COMPONENTS}" ORACLE_QT_MODULES) +endif() + +if(TEST) + _qt_components_to_targets("${TEST_QT_COMPONENTS}" TEST_QT_MODULES) +endif() + +# Core-only export (useful for headless libraries) +set(QT_CORE_MODULE "${COCKATRICE_QT_VERSION_NAME}::Core") + +# --------------------------------------------------------------------------- +# Qt Linguist tools +# --------------------------------------------------------------------------- + +if(TARGET Qt6::lrelease) + set(QT6_LRELEASE_INDEX 0) +else() message(WARNING "Qt6 lrelease not found.") endif() -list(FIND Qt6LinguistTools_TARGETS Qt6::lupdate QT6_LUPDATE_INDEX) -if(QT6_LUPDATE_INDEX EQUAL -1) +if(TARGET Qt6::lupdate) + set(QT6_LUPDATE_INDEX 0) +else() message(WARNING "Qt6 lupdate not found.") endif() +# --------------------------------------------------------------------------- +# Qt runtime/plugin paths +# --------------------------------------------------------------------------- + set(CMAKE_POSITION_INDEPENDENT_CODE ON) -# Establish Qt Plugins directory & Library directories -get_target_property(QT_LIBRARY_DIR ${COCKATRICE_QT_VERSION_NAME}::Core LOCATION) -get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} DIRECTORY) +if(NOT TARGET Qt6::Core) + message(FATAL_ERROR "Qt6::Core target is not available") +endif() + +get_target_property(QT_LIBRARY_DIR Qt6::Core LOCATION) +get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}" DIRECTORY) get_filename_component(QT_PLUGINS_DIR "${Qt6Core_DIR}/../../../${QT6_INSTALL_PLUGINS}" ABSOLUTE) get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/../../.." ABSOLUTE) + if(UNIX AND APPLE) - # Mac needs a bit more help finding all necessary components + # macOS needs a bit more help finding all necessary components. list(APPEND QT_LIBRARY_DIR "/usr/local/lib") endif() + +# --------------------------------------------------------------------------- +# Debug information +# --------------------------------------------------------------------------- + message(DEBUG "QT_PLUGINS_DIR = ${QT_PLUGINS_DIR}") message(DEBUG "QT_LIBRARY_DIR = ${QT_LIBRARY_DIR}") -# Establish exports -string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" SERVATRICE_QT_MODULES "${_SERVATRICE_NEEDED}") -string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" COCKATRICE_QT_MODULES "${_COCKATRICE_NEEDED}") -string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MODULES "${_ORACLE_NEEDED}") -string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}") +message(STATUS "Qt6_VERSION = ${Qt6_VERSION}") +message(STATUS "Qt6_DIR = ${Qt6_DIR}") +message(STATUS "Qt6Core_DIR = ${Qt6Core_DIR}") +message(STATUS "REQUIRED_QT_COMPONENTS = ${REQUIRED_QT_COMPONENTS}") -# Core-only export (useful for headless libs) -set(QT_CORE_MODULE "${COCKATRICE_QT_VERSION_NAME}::Core") - -message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}") +if(WITH_CLIENT) + message(STATUS "COCKATRICE_QT_MODULES = ${COCKATRICE_QT_MODULES}") +endif() +if(WITH_ORACLE) + message(STATUS "ORACLE_QT_MODULES = ${ORACLE_QT_MODULES}") +endif() +if(WITH_SERVER) + message(STATUS "SERVATRICE_QT_MODULES = ${SERVATRICE_QT_MODULES}") +endif() +if(TEST) + message(STATUS "TEST_QT_MODULES = ${TEST_QT_MODULES}") +endif()