From 771c14b7720023b581ad85c851c39059f10a37d2 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 7 Nov 2025 10:30:38 -0500 Subject: [PATCH 1/4] COMP: Generalize macros to support Qt6 based on CTK_QT_VERSION This change updates various CMake macros to handle Qt6 by using CTK_QT_VERSION. It replaces hardcoded Qt5 references with version-agnostic code where possible. --- CMake/ctkFunctionGeneratePluginManifest.cmake | 2 +- CMake/ctkMacroBuildPlugin.cmake | 2 +- CMake/ctkMacroBuildQtPlugin.cmake | 20 ++++++++----------- CMake/ctkMacroSetupPlugins.cmake | 8 ++++---- CMake/ctkMacroSetupQt.cmake | 2 +- .../Snippets/EventAdmin-Intro/files.cmake | 2 +- Libs/Widgets/CMakeLists.txt | 6 +++++- Libs/Widgets/Testing/Cpp/CMakeLists.txt | 4 ++-- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/CMake/ctkFunctionGeneratePluginManifest.cmake b/CMake/ctkFunctionGeneratePluginManifest.cmake index 1dbdd62361..6b2404163e 100644 --- a/CMake/ctkFunctionGeneratePluginManifest.cmake +++ b/CMake/ctkFunctionGeneratePluginManifest.cmake @@ -105,7 +105,7 @@ function(ctkFunctionGeneratePluginManifest MANIFEST_QRC_FILEPATH_VAR) set(${MANIFEST_QRC_FILEPATH_VAR} ${_manifest_qrc_filepath} PARENT_SCOPE) else() if(CTK_QT_VERSION VERSION_EQUAL "5") - QT5_ADD_RESOURCES(_qrc_src ${_manifest_qrc_filepath}) + qt_add_resources(_qrc_src ${_manifest_qrc_filepath}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() diff --git a/CMake/ctkMacroBuildPlugin.cmake b/CMake/ctkMacroBuildPlugin.cmake index b3ce6e4eb7..af214566e3 100644 --- a/CMake/ctkMacroBuildPlugin.cmake +++ b/CMake/ctkMacroBuildPlugin.cmake @@ -194,7 +194,7 @@ macro(ctkMacroBuildPlugin) set_source_files_properties(${MY_TRANSLATIONS} PROPERTIES OUTPUT_LOCATION ${_translations_dir}) if(CTK_QT_VERSION VERSION_EQUAL "5") - qt5_create_translation(_plugin_qm_files ${MY_SRCS} ${MY_UI_FORMS} ${MY_TRANSLATIONS}) + qt_create_translation(_plugin_qm_files ${MY_SRCS} ${MY_UI_FORMS} ${MY_TRANSLATIONS}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() diff --git a/CMake/ctkMacroBuildQtPlugin.cmake b/CMake/ctkMacroBuildQtPlugin.cmake index ae6319f4fd..704216130f 100644 --- a/CMake/ctkMacroBuildQtPlugin.cmake +++ b/CMake/ctkMacroBuildQtPlugin.cmake @@ -172,8 +172,8 @@ macro(ctkMacroBuildQtPlugin) endmacro() macro(ctkMacroBuildQtDesignerPlugin) + find_package(Qt${CTK_QT_VERSION} COMPONENTS Designer REQUIRED) if(CTK_QT_VERSION VERSION_EQUAL "5") - find_package(Qt5 COMPONENTS Designer REQUIRED) add_definitions(${Qt5Designer_DEFINITIONS}) include_directories(${Qt5Designer_INCLUDE_DIRS}) else() @@ -182,17 +182,13 @@ macro(ctkMacroBuildQtDesignerPlugin) ctkMacroBuildQtPlugin( PLUGIN_DIR designer ${ARGN}) - if(CTK_QT_VERSION VERSION_EQUAL "5") - cmake_parse_arguments(MY - "" # no options - "NAME;EXPORT_DIRECTIVE;FOLDER;PLUGIN_DIR" # one value args - "SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES" # multi value args - ${ARGN} - ) - target_link_libraries(${MY_NAME} Qt5::Designer) - else() - message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") - endif() + cmake_parse_arguments(MY + "" # no options + "NAME;EXPORT_DIRECTIVE;FOLDER;PLUGIN_DIR" # one value args + "SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES" # multi value args + ${ARGN} + ) + target_link_libraries(${MY_NAME} Qt${CTK_QT_VERSION}::Designer) endmacro() macro(ctkMacroBuildQtIconEnginesPlugin) diff --git a/CMake/ctkMacroSetupPlugins.cmake b/CMake/ctkMacroSetupPlugins.cmake index db1eb9a9b5..37c6f8e8b6 100644 --- a/CMake/ctkMacroSetupPlugins.cmake +++ b/CMake/ctkMacroSetupPlugins.cmake @@ -105,11 +105,11 @@ macro(ctkMacroSetupPlugins ) # Qt shared libraries if(CTK_QT_VERSION VERSION_EQUAL "5") if(WIN32) - get_target_property(_qt5_moc_executable Qt5::moc LOCATION) - get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt5_moc_executable} PATH) + get_target_property(_qt_moc_executable Qt${CTK_QT_VERSION}::moc LOCATION) + get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt_moc_executable} PATH) else() - get_target_property(_qt5_core_lib Qt5::Core LOCATION) - get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt5_core_lib} PATH) + get_target_property(_qt_core_lib Qt${CTK_QT_VERSION}::Core LOCATION) + get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt_core_lib} PATH) endif() else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") diff --git a/CMake/ctkMacroSetupQt.cmake b/CMake/ctkMacroSetupQt.cmake index ec45ff5f9b..91e467a4cb 100644 --- a/CMake/ctkMacroSetupQt.cmake +++ b/CMake/ctkMacroSetupQt.cmake @@ -23,7 +23,7 @@ macro(ctkMacroSetupQt) if(CTK_QT_VERSION VERSION_EQUAL "5") cmake_minimum_required(VERSION 3.20.6) - find_package(Qt5 COMPONENTS Core) + find_package(Qt${CTK_QT_VERSION} COMPONENTS Core) set(CTK_QT_COMPONENTS Core) diff --git a/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake b/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake index 867e25b96f..a55ebd6527 100644 --- a/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake +++ b/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake @@ -9,7 +9,7 @@ set(_moc_files foreach(_moc_file ${_moc_files}) if(CTK_QT_VERSION VERSION_EQUAL "5") - QT5_WRAP_CPP(snippet_src_files EventAdmin-Intro/${_moc_file} + qt_wrap_cpp(snippet_src_files EventAdmin-Intro/${_moc_file} OPTIONS -f${CMAKE_CURRENT_SOURCE_DIR}/EventAdmin-Intro/${_moc_file}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") diff --git a/Libs/Widgets/CMakeLists.txt b/Libs/Widgets/CMakeLists.txt index 70eeafaac3..8287e032ed 100644 --- a/Libs/Widgets/CMakeLists.txt +++ b/Libs/Widgets/CMakeLists.txt @@ -242,7 +242,11 @@ set(KIT_resources # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) - list(APPEND KIT_target_libraries Qt5::Widgets Qt5::Xml Qt5::OpenGL) +list(APPEND KIT_target_libraries + Qt${CTK_QT_VERSION}::Widgets + Qt${CTK_QT_VERSION}::Xml + Qt${CTK_QT_VERSION}::OpenGL + ) # A player and a translator must be added for custom Qt widgets if(CTK_USE_QTTESTING) diff --git a/Libs/Widgets/Testing/Cpp/CMakeLists.txt b/Libs/Widgets/Testing/Cpp/CMakeLists.txt index 364fc7dbad..2828a56413 100644 --- a/Libs/Widgets/Testing/Cpp/CMakeLists.txt +++ b/Libs/Widgets/Testing/Cpp/CMakeLists.txt @@ -225,9 +225,9 @@ set_target_properties(${KIT}CppTests PROPERTIES ) if(CTK_QT_VERSION VERSION_EQUAL "5") - list(APPEND KIT_target_libraries Qt5::Test) + list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Test) if(CTK_USE_QTTESTING) - list(APPEND KIT_target_libraries Qt5::Xml Qt5::XmlPatterns) + list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Xml Qt${CTK_QT_VERSION}::XmlPatterns) endif() target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) else() From b55bb8f7c2d45b8ad5c4a736e0515b8d25919d94 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Fri, 7 Nov 2025 11:02:03 -0500 Subject: [PATCH 2/4] COMP: Clarify Qt Designer plugin handling for Qt5 and newer Qt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Qt5’s `Qt5Designer_DEFINITIONS` and related variables may contain generator expressions that are not compatible with direct `add_definitions()` usage. This change documents why we continue using `add_definitions()` and `include_directories()` for Qt5, and relies on target usage requirements for newer Qt versions instead of failing with a fatal error. --- CMake/ctkMacroBuildQtPlugin.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CMake/ctkMacroBuildQtPlugin.cmake b/CMake/ctkMacroBuildQtPlugin.cmake index 704216130f..0e1307bf1b 100644 --- a/CMake/ctkMacroBuildQtPlugin.cmake +++ b/CMake/ctkMacroBuildQtPlugin.cmake @@ -174,10 +174,16 @@ endmacro() macro(ctkMacroBuildQtDesignerPlugin) find_package(Qt${CTK_QT_VERSION} COMPONENTS Designer REQUIRED) if(CTK_QT_VERSION VERSION_EQUAL "5") + # Variables like Qt*_DEFINITIONS may include generator expressions (genex) in newer Qt versions, + # which cannot be directly passed to "add_definitions()". For example, the list may include elements + # like "$<$>:QDESIGNER_EXPORT_WIDGETS>". Stripping these using + # "string(GENEX_STRIP ...)" would result in an incomplete set of definitions. + # Therefore, we maintain the use of add_definitions()/include_directories() for Qt5 and encourage + # developers to rely on target usage requirements for newer versions. add_definitions(${Qt5Designer_DEFINITIONS}) include_directories(${Qt5Designer_INCLUDE_DIRS}) else() - message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") + # For newer Qt versions, use target usage requirements to handle definitions and include directories. endif() ctkMacroBuildQtPlugin( PLUGIN_DIR designer From 68ca0649d64d01f05f4c0c860e7ed052d0d3af11 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Sat, 8 Nov 2025 20:17:29 -0500 Subject: [PATCH 3/4] COMP: Add CMake configuration for Qt6 alongside Qt5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable building CTK with either Qt 5 or Qt 6 by updating CMake configuration and Qt component selection: * Allow `CTK_QT_VERSION` to be 5 or 6 (defaulting to 6 when `Qt6_DIR` is defined, otherwise 5), and validate its value. * Use common Qt APIs for both Qt 5 and Qt 6 where available (e.g. `qt_add_resources`, `qt_create_translation`, `qt_wrap_cpp`, plugin setup helpers). * Add required Qt 6 components when building with Qt 6, including `Core5Compat`, `StateMachine`, and `OpenGLWidgets`, while preserving existing Qt 5 behavior. * Restrict use of deprecated or Qt 5–only components: * Require `XmlPatterns` only with Qt 5. * Force `CTK_USE_QTTESTING` OFF with Qt 6, since QtTesting depends on `XmlPatterns`. * Disable CommandLine Modules components and applications that depend on `XmlPatterns` for Qt 6 builds. * Disable DICOM Application Hosting plug-ins and example applications that depend on QtSOAP for Qt 6 builds. * Update core, widgets, VTK widgets, and test CMakeLists to link against the appropriate Qt 5/Qt 6 targets based on `CTK_QT_VERSION`. Co-authored-by: Stefan Dinkelacker Co-authored-by: jporcher Co-authored-by: Hans Johnson --- CMake/ctkFunctionGeneratePluginManifest.cmake | 2 +- CMake/ctkMacroBuildPlugin.cmake | 2 +- CMake/ctkMacroBuildQtPlugin.cmake | 2 + CMake/ctkMacroSetupPlugins.cmake | 2 +- CMake/ctkMacroSetupQt.cmake | 41 ++++++++++--- CMakeLists.txt | 61 ++++++++++++++++++- Libs/Core/CMakeLists.txt | 6 ++ .../Snippets/EventAdmin-Intro/files.cmake | 2 +- .../VTK/Widgets/target_libraries.cmake | 3 + Libs/Widgets/CMakeLists.txt | 5 ++ Libs/Widgets/Testing/Cpp/CMakeLists.txt | 9 ++- 11 files changed, 120 insertions(+), 15 deletions(-) diff --git a/CMake/ctkFunctionGeneratePluginManifest.cmake b/CMake/ctkFunctionGeneratePluginManifest.cmake index 6b2404163e..2fe748bf2f 100644 --- a/CMake/ctkFunctionGeneratePluginManifest.cmake +++ b/CMake/ctkFunctionGeneratePluginManifest.cmake @@ -104,7 +104,7 @@ function(ctkFunctionGeneratePluginManifest MANIFEST_QRC_FILEPATH_VAR) if(MY_SKIP_QT5_ADD_RESOURCES) set(${MANIFEST_QRC_FILEPATH_VAR} ${_manifest_qrc_filepath} PARENT_SCOPE) else() - if(CTK_QT_VERSION VERSION_EQUAL "5") + if(CTK_QT_VERSION MATCHES "^(5|6)$") qt_add_resources(_qrc_src ${_manifest_qrc_filepath}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") diff --git a/CMake/ctkMacroBuildPlugin.cmake b/CMake/ctkMacroBuildPlugin.cmake index af214566e3..0ac79b4736 100644 --- a/CMake/ctkMacroBuildPlugin.cmake +++ b/CMake/ctkMacroBuildPlugin.cmake @@ -193,7 +193,7 @@ macro(ctkMacroBuildPlugin) if(MY_TRANSLATIONS) set_source_files_properties(${MY_TRANSLATIONS} PROPERTIES OUTPUT_LOCATION ${_translations_dir}) - if(CTK_QT_VERSION VERSION_EQUAL "5") + if(CTK_QT_VERSION MATCHES "^(5|6)$") qt_create_translation(_plugin_qm_files ${MY_SRCS} ${MY_UI_FORMS} ${MY_TRANSLATIONS}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") diff --git a/CMake/ctkMacroBuildQtPlugin.cmake b/CMake/ctkMacroBuildQtPlugin.cmake index 0e1307bf1b..b4dcc973b7 100644 --- a/CMake/ctkMacroBuildQtPlugin.cmake +++ b/CMake/ctkMacroBuildQtPlugin.cmake @@ -119,6 +119,8 @@ macro(ctkMacroBuildQtPlugin) set(compile_flags "-DQT_PLUGIN") if(CTK_QT_VERSION VERSION_EQUAL "5") set(compile_flags "${compile_flags} -DHAVE_QT5") + elseif(CTK_QT_VERSION VERSION_EQUAL "6") + set(compile_flags "${compile_flags} -DHAVE_QT6") else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() diff --git a/CMake/ctkMacroSetupPlugins.cmake b/CMake/ctkMacroSetupPlugins.cmake index 37c6f8e8b6..24b74eab4f 100644 --- a/CMake/ctkMacroSetupPlugins.cmake +++ b/CMake/ctkMacroSetupPlugins.cmake @@ -103,7 +103,7 @@ macro(ctkMacroSetupPlugins ) # Set the variable QT_INSTALLED_LIBRARY_DIR that contains all # Qt shared libraries - if(CTK_QT_VERSION VERSION_EQUAL "5") + if(CTK_QT_VERSION MATCHES "^(5|6)$") if(WIN32) get_target_property(_qt_moc_executable Qt${CTK_QT_VERSION}::moc LOCATION) get_filename_component(QT_INSTALLED_LIBRARY_DIR ${_qt_moc_executable} PATH) diff --git a/CMake/ctkMacroSetupQt.cmake b/CMake/ctkMacroSetupQt.cmake index 91e467a4cb..86760febb4 100644 --- a/CMake/ctkMacroSetupQt.cmake +++ b/CMake/ctkMacroSetupQt.cmake @@ -21,12 +21,19 @@ #! \ingroup CMakeUtilities macro(ctkMacroSetupQt) - if(CTK_QT_VERSION VERSION_EQUAL "5") + if(CTK_QT_VERSION MATCHES "^(5|6)$") cmake_minimum_required(VERSION 3.20.6) find_package(Qt${CTK_QT_VERSION} COMPONENTS Core) set(CTK_QT_COMPONENTS Core) + if(CTK_QT_VERSION VERSION_GREATER "5") + list(APPEND CTK_QT_COMPONENTS + Core5Compat # For QRegExp used in "ctkCommandLineParser.cpp" + StateMachine # For QAbstractTransition used in "ctkWorkflowTransitions.h" + ) + endif() + # See https://github.com/commontk/CTK/wiki/Maintenance#updates-of-required-qt-components if(CTK_LIB_Widgets @@ -46,7 +53,9 @@ macro(ctkMacroSetupQt) OR CTK_LIB_CommandLineModules/Core OR CTK_LIB_Scripting/Python/Core_PYTHONQT_WRAP_QTXMLPATTERNS ) - list(APPEND CTK_QT_COMPONENTS XmlPatterns) + if(CTK_QT_VERSION VERSION_EQUAL "5") + list(APPEND CTK_QT_COMPONENTS XmlPatterns) + endif() endif() if(CTK_APP_ctkCommandLineModuleExplorer @@ -82,6 +91,10 @@ macro(ctkMacroSetupQt) if(CTK_LIB_Widgets) list(APPEND CTK_QT_COMPONENTS OpenGL) + + if(CTK_QT_VERSION VERSION_GREATER "5") + list(APPEND CTK_QT_COMPONENTS OpenGLWidgets) + endif() endif() if(CTK_APP_ctkCommandLineModuleExplorer @@ -108,6 +121,10 @@ macro(ctkMacroSetupQt) if(CTK_BUILD_QTDESIGNER_PLUGINS) list(APPEND CTK_QT_COMPONENTS Designer) + + if(CTK_QT_VERSION VERSION_GREATER "5") + list(APPEND CTK_QT_COMPONENTS DesignerComponentsPrivate) + endif() endif() if(CTK_LIB_XNAT/Core @@ -118,18 +135,28 @@ macro(ctkMacroSetupQt) list(APPEND CTK_QT_COMPONENTS Network) endif() - find_package(Qt5 COMPONENTS ${CTK_QT_COMPONENTS} REQUIRED) + if(CTK_QT_VERSION VERSION_EQUAL "5") + find_package(Qt5 COMPONENTS ${CTK_QT_COMPONENTS} REQUIRED) + mark_as_superbuild(Qt5_DIR) # Qt 5 + + set(_major ${Qt5_VERSION_MAJOR}) + set(_minor ${Qt5_VERSION_MINOR}) + set(_patch ${Qt5_VERSION_PATCH}) - mark_as_superbuild(Qt5_DIR) # Qt 5 + elseif(CTK_QT_VERSION VERSION_EQUAL "6") + find_package(Qt6 COMPONENTS ${CTK_QT_COMPONENTS} REQUIRED) + mark_as_superbuild(Qt6_DIR) # Qt 6 + + set(_major ${Qt6_VERSION_MAJOR}) + set(_minor ${Qt6_VERSION_MINOR}) + set(_patch ${Qt6_VERSION_PATCH}) + endif() # XXX Backward compatible way if(DEFINED CMAKE_PREFIX_PATH) mark_as_superbuild(CMAKE_PREFIX_PATH) # Qt 5 endif() - set(_major ${Qt5_VERSION_MAJOR}) - set(_minor ${Qt5_VERSION_MINOR}) - set(_patch ${Qt5_VERSION_PATCH}) ctk_list_to_string(", " "${CTK_QT_COMPONENTS}" comma_separated_module_list) message(STATUS "Configuring CTK with Qt ${_major}.${_minor}.${_patch} (using modules: ${comma_separated_module_list})") diff --git a/CMakeLists.txt b/CMakeLists.txt index afc2fd5ef1..75403ff736 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,10 +105,18 @@ mark_as_advanced(CTK_SUPERBUILD) #----------------------------------------------------------------------------- # Qt version # -set(CTK_QT_VERSION "5" CACHE STRING "Expected Qt version") +if(DEFINED Qt6_DIR) + set(_default_qt_major_version "6") +else() + set(_default_qt_major_version "5") +endif() +set(CTK_QT_VERSION "${_default_qt_major_version}" CACHE STRING "Expected major Qt version") mark_as_advanced(CTK_QT_VERSION) -set_property(CACHE CTK_QT_VERSION PROPERTY STRINGS 5) +set_property(CACHE CTK_QT_VERSION PROPERTY STRINGS 5 6) mark_as_superbuild(CTK_QT_VERSION) +if(NOT "${CTK_QT_VERSION}" MATCHES "^(5|6)$") + message(FATAL_ERROR "CTK_QT_VERSION must be 5 or 6.") +endif() #----------------------------------------------------------------------------- # Output directories. @@ -321,6 +329,14 @@ endif() # option(CTK_USE_QTTESTING "Enable/Disable QtTesting" OFF) mark_as_advanced(CTK_USE_QTTESTING) +if(NOT CTK_QT_VERSION VERSION_EQUAL "5") + # Forcing to OFF as "QtTesting" depends on XmlPatterns Qt component not available with Qt 6 + if(DEFINED CTK_USE_QTTESTING AND CTK_USE_QTTESTING) + unset(CTK_USE_QTTESTING CACHE) + set(CTK_USE_QTTESTING OFF) + message(WARNING "Forcing option [CTK_USE_QTTESTING] to OFF as QtTesting depends on XmlPatterns Qt component not available with Qt ${CTK_QT_VERSION}") + endif() +endif() mark_as_superbuild(CTK_USE_QTTESTING) #----------------------------------------------------------------------------- @@ -503,6 +519,7 @@ ctk_lib_option(Visualization/VTK/Core ctk_lib_option(Visualization/VTK/Widgets "Build the VTK Widgets library" OFF) +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_lib_option(CommandLineModules/Core "Build the Command Line Module core library" OFF) @@ -521,6 +538,16 @@ ctk_lib_option(CommandLineModules/Backend/LocalProcess ctk_lib_option(CommandLineModules/Backend/FunctionPointer "Build the Command Line Module back-end for function pointers" OFF) +else() + # "CommandLineModules/Core" depends on XmlPatterns Qt component not available with Qt 6 + set(CTK_LIB_CommandLineModules/Core OFF) + set(CTK_LIB_CommandLineModules/Frontend/QtWebKit OFF) + set(CTK_LIB_CommandLineModules/Frontend/QtGui OFF) + set(CTK_LIB_CommandLineModules/Backend/XMLChecker OFF) + set(CTK_LIB_CommandLineModules/Backend/LocalProcess OFF) + set(CTK_LIB_CommandLineModules/Backend/FunctionPointer OFF) +endif() + ctk_lib_option(XNAT/Core "Build the XNAT Core library" OFF) @@ -574,6 +601,7 @@ ctk_app_option(ctkDICOMQueryRetrieve "Build the DICOM example application" OFF CTK_ENABLE_DICOM AND CTK_BUILD_EXAMPLES) +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_app_option(ctkDICOMHost "Build the DICOM application host example application" OFF CTK_ENABLE_DICOMApplicationHosting AND CTK_BUILD_EXAMPLES) @@ -585,6 +613,12 @@ ctk_app_option(ctkExampleHost ctk_app_option(ctkExampleHostedApp "Build the DICOM example application" OFF CTK_ENABLE_DICOMApplicationHosting AND CTK_BUILD_EXAMPLES) +else() + # Host apps depends on "org.commontk.dah.core" which depends on QtSOAP not available with Qt 6 + set(CTK_APP_ctkDICOMHost OFF) + set(CTK_APP_ctkExampleHost OFF) + set(CTK_APP_ctkExampleHostedApp OFF) +endif() if(FALSE) # Since EventBusDemo depends on qxmlrpc that is lacking Qt5 support, it is excluded. @@ -593,9 +627,14 @@ ctk_app_option(ctkEventBusDemo CTK_ENABLE_PluginFramework AND CTK_BUILD_EXAMPLES) endif() +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_app_option(ctkCommandLineModuleExplorer "Build the Command Line Module Explorer" OFF CTK_BUILD_EXAMPLES) +else() + # "ctkCommandLineModuleExplorer" depends on "CommandLineModules/Core" which depends on XmlPatterns Qt component not available with Qt 6 + set(CTK_APP_ctkCommandLineModuleExplorer OFF) +endif() # We use the CTKWidgets library together with the Qt Designer plug-in # in ctkCommandLineModuleExplorer, so enabling the options here. @@ -672,6 +711,7 @@ ctk_plugin_option(org.commontk.plugingenerator.ui CTK_APP_ctkPluginGenerator) # Plug-ins related to DICOM WG23 (Application Hosting) +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_plugin_option(org.commontk.dah.core "Build the org.commontk.dah.core plugin." OFF) ctk_plugin_option(org.commontk.dah.hostedapp "Build the org.commontk.dah.hostedapp plugin." OFF CTK_ENABLE_DICOMApplicationHosting) @@ -681,14 +721,31 @@ ctk_plugin_option(org.commontk.dah.host "Build the org.commontk.dah.host plugin. ctk_plugin_option(org.commontk.dah.exampleapp "Build the org.commontk.dah.exampleapp plugin." OFF CTK_APP_ctkExampleHostedApp) +else() + # "org.commontk.dah.core" and its dependent plugins depend on QtSOAP not available with Qt 6 + set(CTK_PLUGIN_org.commontk.dah.core OFF) + set(CTK_PLUGIN_org.commontk.dah.hostedapp OFF) + set(CTK_PLUGIN_org.commontk.dah.host OFF) + set(CTK_PLUGIN_org.commontk.dah.exampleapp OFF) +endif() +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_plugin_option(org.commontk.dah.cmdlinemoduleapp "Build the org.commontk.dah.cmdlinemoduleapp plugin." OFF CTK_APP_ctkCommandLineModuleApp) +else() + # "org.commontk.dah.cmdlinemoduleapp" depends on "CommandLineModules/Core" which depends on XmlPatterns Qt component not available with Qt 6 + set(CTK_PLUGIN_org.commontk.dah.cmdlinemoduleapp OFF) +endif() +if(CTK_QT_VERSION VERSION_EQUAL "5") ctk_plugin_option(org.commontk.dah.examplehost "Build the org.commontk.dah.examplehost plugin." OFF CTK_APP_ctkExampleHost) +else() + # "org.commontk.dah.examplehost" depends on "org.commontk.dah.core" which depends on QtSOAP not available with Qt 6 + set(CTK_PLUGIN_org.commontk.dah.examplehost OFF) +endif() # Plug-ins related to the EventBus demo application if(FALSE) diff --git a/Libs/Core/CMakeLists.txt b/Libs/Core/CMakeLists.txt index 80c7de71c7..a16b50ecd6 100644 --- a/Libs/Core/CMakeLists.txt +++ b/Libs/Core/CMakeLists.txt @@ -129,6 +129,12 @@ set(KIT_target_libraries) ctkFunctionGetTargetLibraries(KIT_target_libraries) list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Core) +if(CTK_QT_VERSION VERSION_GREATER "5") + list(APPEND KIT_target_libraries + Qt${CTK_QT_VERSION}::Core5Compat # For QRegExp + Qt${CTK_QT_VERSION}::StateMachine # For QAbstractTransition used in "ctkWorkflow" classes + ) +endif() ctkMacroBuildLib( NAME ${PROJECT_NAME} diff --git a/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake b/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake index a55ebd6527..6dc13d5180 100644 --- a/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake +++ b/Libs/PluginFramework/Documentation/Snippets/EventAdmin-Intro/files.cmake @@ -8,7 +8,7 @@ set(_moc_files ) foreach(_moc_file ${_moc_files}) - if(CTK_QT_VERSION VERSION_EQUAL "5") + if(CTK_QT_VERSION MATCHES "^(5|6)$") qt_wrap_cpp(snippet_src_files EventAdmin-Intro/${_moc_file} OPTIONS -f${CMAKE_CURRENT_SOURCE_DIR}/EventAdmin-Intro/${_moc_file}) else() diff --git a/Libs/Visualization/VTK/Widgets/target_libraries.cmake b/Libs/Visualization/VTK/Widgets/target_libraries.cmake index f77af74df8..a3bae76d37 100644 --- a/Libs/Visualization/VTK/Widgets/target_libraries.cmake +++ b/Libs/Visualization/VTK/Widgets/target_libraries.cmake @@ -11,6 +11,9 @@ set(target_libraries ) if(CTK_QT_VERSION VERSION_EQUAL "5") list(APPEND target_libraries Qt5Network_LIBRARIES Qt5WebKit_LIBRARIES) +elseif(CTK_QT_VERSION VERSION_EQUAL "6") + # Skip workaround originally introduced to support Qt5. + # See 47b34216 ("Add support for Qt5", 2013-09-20) else() message(FATAL_ERROR "Support for this Qt is not implemented") endif() diff --git a/Libs/Widgets/CMakeLists.txt b/Libs/Widgets/CMakeLists.txt index 8287e032ed..3d8b079670 100644 --- a/Libs/Widgets/CMakeLists.txt +++ b/Libs/Widgets/CMakeLists.txt @@ -247,6 +247,11 @@ list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Xml Qt${CTK_QT_VERSION}::OpenGL ) +if(CTK_QT_VERSION VERSION_GREATER "5") + list(APPEND KIT_target_libraries + Qt${CTK_QT_VERSION}::OpenGLWidgets + ) +endif() # A player and a translator must be added for custom Qt widgets if(CTK_USE_QTTESTING) diff --git a/Libs/Widgets/Testing/Cpp/CMakeLists.txt b/Libs/Widgets/Testing/Cpp/CMakeLists.txt index 2828a56413..88b998cc69 100644 --- a/Libs/Widgets/Testing/Cpp/CMakeLists.txt +++ b/Libs/Widgets/Testing/Cpp/CMakeLists.txt @@ -224,10 +224,15 @@ set_target_properties(${KIT}CppTests PROPERTIES AUTOUIC_SEARCH_PATHS "${uic_search_paths}" ) -if(CTK_QT_VERSION VERSION_EQUAL "5") +if(CTK_QT_VERSION MATCHES "^(5|6)$") list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Test) if(CTK_USE_QTTESTING) - list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Xml Qt${CTK_QT_VERSION}::XmlPatterns) + list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Xml) + # XmlPatterns is not available in Qt 6. CTK_USE_QTTESTING is forced OFF for Qt 6 + # in the main CMakeLists.txt, but we add a version check here for robustness. + if(CTK_QT_VERSION VERSION_EQUAL "5") + list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::XmlPatterns) + endif() endif() target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) else() From d2aa1cc4cf11d8d7250b8de19945b916bd36f2c8 Mon Sep 17 00:00:00 2001 From: Jean-Christophe Fillion-Robin Date: Sun, 9 Nov 2025 00:29:55 -0500 Subject: [PATCH 4/4] ENH: Add Qt6 build to CI workflow - Extend matrix with qt-major-version (5, 6) to exercise both Qt versions. - Split Qt install into Qt 5 and Qt 6 steps conditioned on qt-major-version. - Keep using system VTK only for Qt 5 builds; disable it for Qt 6 builds. - Derive CTK_QT_VERSION from qt-major-version in the configure step. - Update diagnostic step to print both Qt5_DIR and Qt6_DIR from CMake cache. --- .github/workflows/ci.yml | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c7769ddc4f..5902fac015 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,6 +21,7 @@ jobs: fail-fast: false matrix: runs-on: ["ubuntu-latest"] + qt-major-version: [5, 6] steps: - uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -36,7 +37,8 @@ jobs: - name: Retrieve new lists of APT packages run: sudo apt-get update - - name: Install Qt + - name: Install Qt 5 + if: ${{ matrix.qt-major-version == 5 }} run: | sudo apt-get install -y \ qtbase5-dev \ @@ -50,17 +52,33 @@ jobs: libqt5x11extras5-dev \ libxt-dev - - name: Install VTK - if: matrix.runs-on == 'ubuntu-latest' + - name: Install VTK (Qt 5) + if: ${{ matrix.runs-on == 'ubuntu-latest' && matrix.qt-major-version == 5 }} run: | sudo apt-get install -y \ libvtk9-dev \ libvtk9-qt-dev + - name: Install Qt 6 + if: ${{ matrix.qt-major-version == 6 }} + run: | + sudo apt-get install -y \ + qt6-base-dev \ + qt6-base-private-dev \ + qt6-5compat-dev \ + qt6-multimedia-dev \ + qt6-scxml-dev \ + qt6-tools-dev \ + qt6-tools-dev-tools \ + qt6-svg-dev \ + qt6-webengine-dev \ + libqt6openglwidgets6 \ + libxt-dev + - name: Configure CTK run: | cmake \ - -DCTK_QT_VERSION:STRING=5 \ + -DCTK_QT_VERSION:STRING=${{ matrix.qt-major-version }} \ -DCTK_ENABLE_Widgets:BOOL=ON \ -DCTK_USE_SYSTEM_VTK:BOOL=$CTK_USE_VTK \ -DCTK_LIB_Visualization/VTK/Widgets:BOOL=$CTK_USE_VTK \ @@ -81,11 +99,14 @@ jobs: -B CTK-build \ -S . env: - CTK_USE_VTK: "${{ matrix.runs-on == 'ubuntu-latest' && 'ON' || 'OFF' }}" + CTK_USE_VTK: "${{ matrix.runs-on == 'ubuntu-latest' && matrix.qt-major-version == 5 && 'ON' || 'OFF' }}" - - name: Display Qt5_DIR + - name: Display Qt_DIR run: | - cat CTK-build/CMakeCache.txt | grep ^Qt5_DIR + echo "Qt5_DIR:" + cat CTK-build/CMakeCache.txt | grep '^Qt5_DIR' || true + echo "Qt6_DIR:" + cat CTK-build/CMakeCache.txt | grep '^Qt6_DIR' || true - name: Build CTK run: |