From 2fe1f2d78fd853351a294070ad59bff5bc134983 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Nov 2025 11:42:37 +0100 Subject: [PATCH 1/5] CMake: add initial CMake support This is strongly influenced by Olivier CHURLAUD's PR that tried to add CMake support to the mhaller "upstream" in 2016, but modernised for the current CMake and KDE ECM scene. Versions required are based on what is available in Debian 12. Builds against whatever Qt versions (5 or 6 or both) are available. --- CMakeLists.txt | 72 +++++++++++++++++++++++++++++++++++++ qwebdavlib/CMakeLists.txt | 75 ++++++++++++++++++++++----------------- 2 files changed, 114 insertions(+), 33 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..dd4adf1 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) + +project(QWebdav + VERSION 1.0 + DESCRIPTION "WebDAV server access" + HOMEPAGE_URL "https://github.com/fredldotme/qwebdavlib" + LANGUAGES CXX +) + +### Find ECM up-front and complain otherwise +# +# +include(FeatureSummary) +find_package(ECM 5.103.0 NO_MODULE) +set_package_properties(ECM + PROPERTIES + TYPE REQUIRED + DESCRIPTION "Extra modules and scripts for CMake" + URL "https://invent.kde.org/frameworks/extra-cmake-modules" +) +feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) + +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) + +include(KDEInstallDirs) +include(KDECMakeSettings) + +include(GenerateExportHeader) + +include(ECMSetupVersion) +include(ECMGenerateHeaders) + +### Find available Qt build types +# +# +set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) +find_package(Qt6 6.5.0 CONFIG COMPONENTS Core Network Xml) +find_package(Qt5 5.15.0 CONFIG COMPONENTS Core Network Xml) + +if(TARGET Qt5::Core) + message(STATUS "Building Qt5 version of ${PROJECT_NAME}") +endif() +if(TARGET Qt6::Core) + message(STATUS "Building Qt6 version of ${PROJECT_NAME}") +endif() +if(NOT TARGET Qt5::Core AND NOT TARGET Qt6::Core) + # If neither is found, complain about Qt5 because then the + # error message says ">= 5.15.0" which reads most naturally. + set_package_properties(Qt5 + PROPERTIES + TYPE REQUIRED + DESCRIPTION "Qt libraries (version 5 or 6)" + URL "https://qt.io/" + ) +endif() + +### QWebdav version header is independent of build type +# +# +ecm_setup_version(${PROJECT_VERSION} + VARIABLE_PREFIX QWebdav + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/qwebdav_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/QWebdavConfigVersion.cmake" + SOVERSION 1 +) + +### Build +# +# +add_subdirectory(qwebdavlib) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/qwebdavlib/CMakeLists.txt b/qwebdavlib/CMakeLists.txt index a597b3b..af6420a 100644 --- a/qwebdavlib/CMakeLists.txt +++ b/qwebdavlib/CMakeLists.txt @@ -1,39 +1,48 @@ -# Generated from qwebdavlib.pro. +# Boilerplate for building the library against a given Qt version +function(add_qwebdav_library QT_VERSION) + add_library(QWebdav-qt${QT_VERSION}) + target_sources(QWebdav-qt${QT_VERSION} + PRIVATE + qnaturalsort.cpp + qwebdav.cpp + qwebdavdirparser.cpp + qwebdavitem.cpp + ) -##################################################################### -## qwebdav Generic Library: -##################################################################### + target_compile_definitions(QWebdav-qt${QT_VERSION} + PRIVATE + QWEBDAV_LIBRARY=1 + QWEBDAVITEM_EXTENDED_PROPERTIES=1 + ) + if(CMAKE_BUILD_TYPE STREQUAL Release) + target_compile_definitions(QWebdav-qt${QT_VERSION} + PRIVATE + QT_NO_DEBUG_OUTPUT=1 + ) + endif() -qt_internal_add_cmake_library(qwebdav - SOURCES - qnaturalsort.cpp qnaturalsort.h - qwebdav.cpp qwebdav.h - qwebdav_global.h - qwebdavdirparser.cpp qwebdavdirparser.h - qwebdavitem.cpp qwebdavitem.h - DEFINES - QWEBDAVITEM_EXTENDED_PROPERTIES - QWEBDAV_LIBRARY - PUBLIC_LIBRARIES - Qt::Core - Qt::Network - Qt::Xml - COMPILE_OPTIONS - -Wno-overloaded-virtual -) + target_compile_options(QWebdav-qt${QT_VERSION} + PRIVATE + -Wno-overloaded-virtual + ) -#### Keys ignored in scope 1:.:.:qwebdavlib.pro:: -# INSTALLS = "target" -# OTHER_FILES = "CHANGES" "LICENSE" "README" -# TEMPLATE = "lib" + target_include_directories(QWebdav-qt${QT_VERSION} + INTERFACE + "$" + ) -## Scopes: -##################################################################### + target_link_libraries(QWebdav-qt${QT_VERSION} + PUBLIC + Qt${QT_VERSION}::Core + Qt${QT_VERSION}::Network + Qt${QT_VERSION}::Xml + ) +endfunction() -qt_internal_extend_target(qwebdav CONDITION CMAKE_BUILD_TYPE STREQUAL Release - DEFINES - QT_NO_DEBUG_OUTPUT -) +if(TARGET Qt5::Core) + add_qwebdav_library(5) +endif() +if(TARGET Qt6::Core) + add_qwebdav_library(6) +endif() -#### Keys ignored in scope 2:.:.:qwebdavlib.pro:(CMAKE_BUILD_TYPE STREQUAL Release): -# QMAKE_POST_LINK = "$(STRIP)" "$(TARGET)" From 903699f1b70a158cc9f6017c677159bbdfd6cf15 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Nov 2025 12:52:54 +0100 Subject: [PATCH 2/5] CMake: install libraries and headers --- qwebdavlib/CMakeLists.txt | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/qwebdavlib/CMakeLists.txt b/qwebdavlib/CMakeLists.txt index af6420a..dd64bc0 100644 --- a/qwebdavlib/CMakeLists.txt +++ b/qwebdavlib/CMakeLists.txt @@ -37,12 +37,44 @@ function(add_qwebdav_library QT_VERSION) Qt${QT_VERSION}::Network Qt${QT_VERSION}::Xml ) + + set_target_properties(QWebdav-qt${QT_VERSION} + PROPERTIES + VERSION ${QWebdav_VERSION} + SOVERSION ${QWebdav_SOVERSION} + EXPORT_NAME "QWebdav-qt${QT_VERSION}" + ) + + install( + TARGETS QWebdav-qt${QT_VERSION} + EXPORT QWebdavTargets + ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} + ) endfunction() if(TARGET Qt5::Core) add_qwebdav_library(5) + add_library(QWebdav ALIAS QWebdav-qt5) endif() if(TARGET Qt6::Core) add_qwebdav_library(6) + if(NOT TARGET QWebdav) + add_library(QWebdav ALIAS QWebdav-qt6) + endif() endif() +# Only one export header, regardless of which libraries are built +generate_export_header(QWebdav) + +# Only one copy of the headers, regardless of which libraries are built +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/qwebdav_export.h + qnaturalsort.h + qwebdav.h + qwebdav_global.h + qwebdavdirparser.h + qwebdavitem.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR}/QWebdav + COMPONENT devel +) From d5d5c2b8a6c539c0674eb13e183f2dcc593afce2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Nov 2025 13:57:34 +0100 Subject: [PATCH 3/5] CMake: install CMake support for finding QWebdav --- CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++++-- QWebdavConfig.cmake.in | 29 +++++++++++++++++++++++++++++ qwebdavlib/CMakeLists.txt | 4 ++-- 3 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 QWebdavConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index dd4adf1..b326f7f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,19 +29,26 @@ include(GenerateExportHeader) include(ECMSetupVersion) include(ECMGenerateHeaders) +include(CMakePackageConfigHelpers) ### Find available Qt build types # # set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) -find_package(Qt6 6.5.0 CONFIG COMPONENTS Core Network Xml) -find_package(Qt5 5.15.0 CONFIG COMPONENTS Core Network Xml) +set(QT5_REQUIRED_VERSION 5.15.0) +set(QT6_REQUIRED_VERSION 6.5.0) +find_package(Qt6 ${QT6_REQUIRED_VERSION} CONFIG COMPONENTS Core Network Xml) +find_package(Qt5 ${QT5_REQUIRED_VERSION} CONFIG COMPONENTS Core Network Xml) +set(WITH_QT5 FALSE) # Used when creating the Config.cmake file +set(WITH_QT6 FALSE) if(TARGET Qt5::Core) message(STATUS "Building Qt5 version of ${PROJECT_NAME}") + set(WITH_QT5 TRUE) endif() if(TARGET Qt6::Core) message(STATUS "Building Qt6 version of ${PROJECT_NAME}") + set(WITH_QT6 TRUE) endif() if(NOT TARGET Qt5::Core AND NOT TARGET Qt6::Core) # If neither is found, complain about Qt5 because then the @@ -63,10 +70,37 @@ ecm_setup_version(${PROJECT_VERSION} PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/QWebdavConfigVersion.cmake" SOVERSION 1 ) +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/qwebdav_version.h" + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/QWebdav + COMPONENT devel +) ### Build # # add_subdirectory(qwebdavlib) +### CMake Configuration Files +# +# +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/QWebdavConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/QWebdavConfig.cmake" + INSTALL_DESTINATION ${KDE_INSTALL_CMAKEPACKAGEDIR}/QWebdav +) +install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/QWebdavConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/QWebdavConfigVersion.cmake" + DESTINATION "${KDE_INSTALL_CMAKEPACKAGEDIR}/QWebdav" + COMPONENT devel +) +install( + EXPORT QWebdavTargets + DESTINATION "${KDE_INSTALL_CMAKEPACKAGEDIR}/QWebdav" + FILE QWebdavTargets.cmake +) + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/QWebdavConfig.cmake.in b/QWebdavConfig.cmake.in new file mode 100644 index 0000000..67f404d --- /dev/null +++ b/QWebdavConfig.cmake.in @@ -0,0 +1,29 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) + +set(_qwebdav_WITH_QT5 @WITH_QT5@) +set(_qwebdav_WITH_QT6 @WITH_QT6@) + +set(QT_NO_CREATE_VERSIONLESS_TARGETS ON) + +if(_qwebdav_WITH_QT5) + find_dependency(Qt5Core @QT5_REQUIRED_VERSION@) + find_dependency(Qt5Network @QT5_REQUIRED_VERSION@) + find_dependency(Qt5Xml @QT5_REQUIRED_VERSION@) +endif() + +if(_qwebdav_WITH_QT6) + find_dependency(Qt6Core @QT6_REQUIRED_VERSION@) + find_dependency(Qt6Network @QT6_REQUIRED_VERSION@) + find_dependency(Qt6Xml @QT6_REQUIRED_VERSION@) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/QWebdavTargets.cmake") + +# Versionless alias, prefer Qt6 over Qt5 +if(_qwebdav_WITH_QT6) + add_library(QWebdav ALIAS QWebdav-qt6) +else() + add_library(QWebdav ALIAS QWebdav-qt5) +endif() diff --git a/qwebdavlib/CMakeLists.txt b/qwebdavlib/CMakeLists.txt index dd64bc0..a1d3652 100644 --- a/qwebdavlib/CMakeLists.txt +++ b/qwebdavlib/CMakeLists.txt @@ -52,11 +52,11 @@ function(add_qwebdav_library QT_VERSION) ) endfunction() -if(TARGET Qt5::Core) +if(WITH_QT5) add_qwebdav_library(5) add_library(QWebdav ALIAS QWebdav-qt5) endif() -if(TARGET Qt6::Core) +if(WITH_QT6) add_qwebdav_library(6) if(NOT TARGET QWebdav) add_library(QWebdav ALIAS QWebdav-qt6) From a662c2f243141b272101ef3b7d5f75b3c6fb084a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Nov 2025 14:16:57 +0100 Subject: [PATCH 4/5] CMake: install pkgconfig files as well If everyone used CMake this wouldn't be necessary, but consumers that expect the older pkg-config solution should still be able to do their usual thing. --- CMakeLists.txt | 30 ++++++++++++++++++++++++++++++ qwebdavlib/qwebdav-qt5.cmake.pc.in | 12 ++++++++++++ qwebdavlib/qwebdav-qt6.cmake.pc.in | 12 ++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 qwebdavlib/qwebdav-qt5.cmake.pc.in create mode 100644 qwebdavlib/qwebdav-qt6.cmake.pc.in diff --git a/CMakeLists.txt b/CMakeLists.txt index b326f7f..b74bdf1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,4 +103,34 @@ install( FILE QWebdavTargets.cmake ) +### PackageConfig files +# +# These are slightly different from the qmake-produced +# ones because the naming of the library is different +# and the installation-directories are, also. +if(WITH_QT5) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/qwebdavlib/qwebdav-qt5.cmake.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/qwebdav-qt5.pc" + @ONLY + ) + install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/qwebdav-qt5.pc" + DESTINATION ${KDE_INSTALL_LIBDIR}/pkgconfig + ) +endif() +if(WITH_QT6) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/qwebdavlib/qwebdav-qt6.cmake.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/qwebdav-qt6.pc" + @ONLY + ) + install( + FILES + "${CMAKE_CURRENT_BINARY_DIR}/qwebdav-qt6.pc" + DESTINATION ${KDE_INSTALL_LIBDIR}/pkgconfig + ) +endif() + feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/qwebdavlib/qwebdav-qt5.cmake.pc.in b/qwebdavlib/qwebdav-qt5.cmake.pc.in new file mode 100644 index 0000000..ffccb51 --- /dev/null +++ b/qwebdavlib/qwebdav-qt5.cmake.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@CMAKE_INSTALL_PREFIX@/@KDE_INSTALL_LIBDIR@ +includedir=${prefix}/include/QWebdav + +Name: libqwebdav-qt5 +Description: Qt WebDAV library +Version: $$VERSION +Libs: -L${libdir} -lQWebdav-qt5 +Requires: Qt5Core Qt5Network Qt5Xml +Cflags: -I${includedir} + diff --git a/qwebdavlib/qwebdav-qt6.cmake.pc.in b/qwebdavlib/qwebdav-qt6.cmake.pc.in new file mode 100644 index 0000000..5ea22c8 --- /dev/null +++ b/qwebdavlib/qwebdav-qt6.cmake.pc.in @@ -0,0 +1,12 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@CMAKE_INSTALL_PREFIX@/@KDE_INSTALL_LIBDIR@ +includedir=${prefix}/include/QWebdav + +Name: libqwebdav-qt6 +Description: Qt WebDAV library +Version: $$VERSION +Libs: -L${libdir} -lQWebdav-qt6 +Requires: Qt6Core Qt6Network Qt6Xml +Cflags: -I${includedir} + From d560ed1662297c0599cb354143874e014d196ed7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Nov 2025 15:18:40 +0100 Subject: [PATCH 5/5] CMake: build the example as a seperate project --- qwebdavlibExample/CMakeLists.txt | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 qwebdavlibExample/CMakeLists.txt diff --git a/qwebdavlibExample/CMakeLists.txt b/qwebdavlibExample/CMakeLists.txt new file mode 100644 index 0000000..4c5b5de --- /dev/null +++ b/qwebdavlibExample/CMakeLists.txt @@ -0,0 +1,26 @@ +# QWebdav example application +# +# This example shows how to find QWebdav after is has been built and installed. +cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR) + +project(QWebdavExample + VERSION 1.0 + DESCRIPTION "QWebDAV Example" + HOMEPAGE_URL "https://github.com/fredldotme/qwebdavlib" + LANGUAGES CXX +) + +set(CMAKE_AUTOMOC ON) + +find_package(QWebdav REQUIRED) + +add_executable(QWebdavExample) +target_sources(QWebdavExample + PRIVATE + main.cpp + qexample.cpp +) +target_link_libraries(QWebdavExample + PRIVATE + QWebdav +)