From 53f41c40c0388a35d53a15aea874c9533c24ae65 Mon Sep 17 00:00:00 2001 From: Rafael Palomar Date: Sat, 13 Jan 2024 13:16:42 +0100 Subject: [PATCH 1/3] ENH: Refactor CMake project infrastructure - Removed old configuration and use CMake files in favor of`qRestAPIConfig.cmake.in` - Enable install configuration through implementation of qRestAPIInstallConfig.cmake.in - Enabled installation of development files. --- CMake/GenerateqRestAPIConfig.cmake | 20 ----- CMake/UseqRestAPI.cmake.in | 16 ---- CMake/qRestAPIConfig.cmake.in | 14 ---- CMakeLists.txt | 118 ++++++++++++++++++++++++++++- qRestAPIConfig.cmake.in | 5 ++ qRestAPIInstallConfig.cmake.in | 3 + 6 files changed, 124 insertions(+), 52 deletions(-) delete mode 100644 CMake/GenerateqRestAPIConfig.cmake delete mode 100644 CMake/UseqRestAPI.cmake.in delete mode 100644 CMake/qRestAPIConfig.cmake.in create mode 100644 qRestAPIConfig.cmake.in create mode 100644 qRestAPIInstallConfig.cmake.in diff --git a/CMake/GenerateqRestAPIConfig.cmake b/CMake/GenerateqRestAPIConfig.cmake deleted file mode 100644 index d82da7a..0000000 --- a/CMake/GenerateqRestAPIConfig.cmake +++ /dev/null @@ -1,20 +0,0 @@ - -configure_file( - ${qRestAPI_SOURCE_DIR}/CMake/UseqRestAPI.cmake.in - ${qRestAPI_BINARY_DIR}/UseqRestAPI.cmake COPYONLY) - -# Include directories -set(qRestAPI_INCLUDE_DIRS_CONFIG ${qRestAPI_INCLUDE_DIRS}) - -# Library directories -set(qRestAPI_LIBRARY_DIRS_CONFIG ${qRestAPI_BINARY_DIR}) - -# UseqRestAPI file -set(qRestAPI_USE_FILE_CONFIG ${qRestAPI_BINARY_DIR}/UseqRestAPI.cmake) - -export(TARGETS qRestAPI FILE ${qRestAPI_BINARY_DIR}/qRestAPIExports.cmake) - -# Configure qRestAPIConfig.cmake -configure_file( - ${qRestAPI_SOURCE_DIR}/CMake/qRestAPIConfig.cmake.in - ${qRestAPI_BINARY_DIR}/qRestAPIConfig.cmake @ONLY) diff --git a/CMake/UseqRestAPI.cmake.in b/CMake/UseqRestAPI.cmake.in deleted file mode 100644 index 4275caa..0000000 --- a/CMake/UseqRestAPI.cmake.in +++ /dev/null @@ -1,16 +0,0 @@ -# -# This module is provided as qCDashAPI_USE_FILE by qCDashAPIConfig.cmake. It can -# be INCLUDED in a project to load the needed compiler and linker -# settings to use qRestAPI. -# - -if(NOT qRestAPI_USE_FILE_INCLUDED) - set(qRestAPI_USE_FILE_INCLUDED 1) - - # Add include directories needed to use qRestAPI. - include_directories(${qRestAPI_INCLUDE_DIRS}) - - # Add link directories needed to use qRestAPI. - link_directories(${qRestAPI_LIBRARY_DIRS}) - -endif() diff --git a/CMake/qRestAPIConfig.cmake.in b/CMake/qRestAPIConfig.cmake.in deleted file mode 100644 index ee15dd2..0000000 --- a/CMake/qRestAPIConfig.cmake.in +++ /dev/null @@ -1,14 +0,0 @@ - -# Import qRestAPI targets -if(NOT qRestAPI_EXPORTS_INCLUDED) - include("@qRestAPI_BINARY_DIR@/qRestAPIExports.cmake") - set(qRestAPI_EXPORTS_INCLUDED 1) -endif() - -set(qRestAPI_LIBRARIES "qRestAPI") - -set(qRestAPI_INCLUDE_DIRS "@qRestAPI_INCLUDE_DIRS_CONFIG@") -set(qRestAPI_LIBRARY_DIRS "@qRestAPI_LIBRARY_DIRS_CONFIG@") - -# The location of the UseqRestAPI.cmake file. -set(qRestAPI_USE_FILE "@qRestAPI_USE_FILE_CONFIG@") diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c3e905..29fe52b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,13 +2,45 @@ cmake_minimum_required(VERSION 3.5.0) project(qRestAPI) +# -------------------------------------------------------------------------- +# CMake variables +# -------------------------------------------------------------------------- set(CMAKE_INCLUDE_CURRENT_DIR 1) set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE 1) set(CMAKE_POSITION_INDEPENDENT_CODE 1) +# -------------------------------------------------------------------------- +# Directories +# -------------------------------------------------------------------------- +# +# CMake +# +set(${PROJECT_NAME}_CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/CMake) +set(CMAKE_MODULE_PATH ${qRestAPI_CMAKE_DIR} ${CMAKE_MODULE_PATH}) +# +# Include +# +set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + CACHE INTERNAL "${PROJECT_NAME} include dirs" FORCE) +# +# Library +# +set(${PROJECT_NAME}_LIBRARY_DIRS ${CMAKE_CURRENT_BINARY_DIR} + CACHE INTERNAL "${PROJECT_NAME} library dirs" FORCE) + +# -------------------------------------------------------------------------- +# Options +# -------------------------------------------------------------------------- option(BUILD_SHARED_LIBS "Build shared library" ON) option(BUILD_TESTING "Test the project" ON) +# -------------------------------------------------------------------------- +# Dependencies +# -------------------------------------------------------------------------- + +# +# Qt +# set(qRestAPI_QT_VERSION "4" CACHE STRING "Expected Qt version") mark_as_advanced(qRestAPI_QT_VERSION) set_property(CACHE qRestAPI_QT_VERSION PROPERTY STRINGS 4 5 6) @@ -36,6 +68,9 @@ else() set(qRestAPI_STATIC ON) endif() +# -------------------------------------------------------------------------- +# Configure headers +# -------------------------------------------------------------------------- configure_file( qRestAPI_Export.h.in ${CMAKE_CURRENT_BINARY_DIR}/qRestAPI_Export.h @@ -53,6 +88,34 @@ set(KIT_SRCS qRestResult.h ) +# -------------------------------------------------------------------------- +# Install headers +# -------------------------------------------------------------------------- +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) + set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON) +endif() + +if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) + + if(NOT DEFINED ${PROJECT_NAME}_INSTALL_INCLUDE_DIR) + set(${PROJECT_NAME}_INSTALL_INCLUDE_DIR include/${PROJECT_NAME}) + endif() + + file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + install( + FILES ${headers} + DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) + + file(GLOB headers "${CMAKE_CURRENT_BINARY_DIR}/*.h") + install( + FILES ${headers} + DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) +endif() + +# -------------------------------------------------------------------------- +# Sources +# -------------------------------------------------------------------------- + set(KIT_MOC_SRCS qGirderAPI.h qMidasAPI.h @@ -69,6 +132,9 @@ else() QT4_WRAP_CPP(KIT_MOC_OUTPUT ${KIT_MOC_SRCS}) endif() +# -------------------------------------------------------------------------- +# Build qRestAPI library +# -------------------------------------------------------------------------- add_library(${PROJECT_NAME} ${KIT_SRCS} ${KIT_MOC_OUTPUT}) if(qRestAPI_QT_VERSION VERSION_GREATER "4") target_link_libraries(${PROJECT_NAME} Qt${qRestAPI_QT_VERSION}::Gui Qt${qRestAPI_QT_VERSION}::Network Qt${qRestAPI_QT_VERSION}::Qml) @@ -76,9 +142,57 @@ else() target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES}) endif() -include(CTest) +# -------------------------------------------------------------------------- +# Install library +# -------------------------------------------------------------------------- +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_BIN_DIR) + set(${PROJECT_NAME}_INSTALL_BIN_DIR bin) +endif() +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_LIB_DIR) + set(${PROJECT_NAME}_INSTALL_LIB_DIR lib/${PROJECT_NAME}) +endif() + +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION ${${PROJECT_NAME}_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries + LIBRARY DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries + ARCHIVE DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT Development + ) + +# -------------------------------------------------------------------------- +# Configure support files +# -------------------------------------------------------------------------- +# Set qRestAPI_INSTALL_CMAKE_DIR +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_CMAKE_DIR) + set(${PROJECT_NAME}_INSTALL_CMAKE_DIR cmake/${PROJECT_NAME}) +endif() + +export(TARGETS qRestAPI FILE ${qRestAPI_BINARY_DIR}/qRestAPIExports.cmake) + +# Configure qRestAPIConfig.cmake +configure_file( + ${qRestAPI_SOURCE_DIR}/qRestAPIConfig.cmake.in + ${qRestAPI_BINARY_DIR}/qRestAPIConfig.cmake @ONLY) + +# Configure qRestAPIConfig.cmake +configure_file( + ${qRestAPI_SOURCE_DIR}/qRestAPIInstallConfig.cmake.in + ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake @ONLY) + +# -------------------------------------------------------------------------- +# Install configuration files +# -------------------------------------------------------------------------- + +# Install qRestAPIConfig cmake files +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/install/qRestAPIConfig.cmake + DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} COMPONENT Development + ) + +# -------------------------------------------------------------------------- +# Testing if(BUILD_TESTING) +include(CTest) add_subdirectory(Testing) endif() -include(CMake/GenerateqRestAPIConfig.cmake) diff --git a/qRestAPIConfig.cmake.in b/qRestAPIConfig.cmake.in new file mode 100644 index 0000000..627aca1 --- /dev/null +++ b/qRestAPIConfig.cmake.in @@ -0,0 +1,5 @@ +include("${CMAKE_CURRENT_BINARY_DIR}/qRestAPIExports.cmake") + +set(qRestAPI_CMAKE_DIR "@qRestAPI_CMAKE_DIR@") +set(qRestAPI_INCLUDE_DIRS "@qRestAPI_INCLUDE_DIRS@") +set(qRestAPI_LIBRARY_DIRS "@qRestAPI_LIBRARY_DIRS@") diff --git a/qRestAPIInstallConfig.cmake.in b/qRestAPIInstallConfig.cmake.in new file mode 100644 index 0000000..87be75d --- /dev/null +++ b/qRestAPIInstallConfig.cmake.in @@ -0,0 +1,3 @@ +set(qRestAPI_CMAKE_DIR "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_CMAKE_DIR@") +set(qRestAPI_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_INCLUDE_DIR@") +set(qRestAPI_LIB_DIR "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_LIB_DIR@") From cc96cad3dfcdf489dfeb642f2a0d703f38e4a96d Mon Sep 17 00:00:00 2001 From: Rafael Palomar Date: Mon, 13 Jul 2026 10:04:50 +0200 Subject: [PATCH 2/3] ENH: Adopt vtkAddon-level packaging (imported target, relocatable install) Export an imported qRestAPI target for both build and install trees via install(EXPORT), and generate the install-tree package config with configure_package_config_file() so the install is relocatable (no absolute CMAKE_INSTALL_PREFIX baked in). Declare include directories as PUBLIC usage requirements with BUILD_INTERFACE/INSTALL_INTERFACE and link Qt with explicit PUBLIC visibility. Legacy path variables (qRestAPI_INCLUDE_DIRS, qRestAPI_LIBRARY_DIRS, qRestAPI_LIBRARIES) are kept for backward compatibility. Config templates remain at the project root, matching the vtkAddon convention. --- CMakeLists.txt | 153 +++++++++++++++++++-------------- README.md | 26 ++++++ qRestAPIConfig.cmake.in | 16 +++- qRestAPIInstallConfig.cmake.in | 29 ++++++- 4 files changed, 156 insertions(+), 68 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29fe52b..e3708d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,6 @@ project(qRestAPI) # CMake variables # -------------------------------------------------------------------------- set(CMAKE_INCLUDE_CURRENT_DIR 1) -set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE 1) set(CMAKE_POSITION_INDEPENDENT_CODE 1) # -------------------------------------------------------------------------- @@ -20,7 +19,7 @@ set(CMAKE_MODULE_PATH ${qRestAPI_CMAKE_DIR} ${CMAKE_MODULE_PATH}) # # Include # -set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} +set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "${PROJECT_NAME} include dirs" FORCE) # # Library @@ -34,6 +33,31 @@ set(${PROJECT_NAME}_LIBRARY_DIRS ${CMAKE_CURRENT_BINARY_DIR} option(BUILD_SHARED_LIBS "Build shared library" ON) option(BUILD_TESTING "Test the project" ON) +# -------------------------------------------------------------------------- +# Install directories +# -------------------------------------------------------------------------- +# These may be set by a parent project (e.g. a superbuild) before this project +# is added. When not set, sensible standalone defaults are used. +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_BIN_DIR) + set(${PROJECT_NAME}_INSTALL_BIN_DIR bin) +endif() +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_LIB_DIR) + set(${PROJECT_NAME}_INSTALL_LIB_DIR lib/${PROJECT_NAME}) +endif() +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_INCLUDE_DIR) + set(${PROJECT_NAME}_INSTALL_INCLUDE_DIR include/${PROJECT_NAME}) +endif() +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_CMAKE_DIR) + set(${PROJECT_NAME}_INSTALL_CMAKE_DIR cmake/${PROJECT_NAME}) +endif() + +# By default only runtime files are installed. Set to OFF to also install the +# development files (headers, CMake package config, exported targets), e.g. when +# creating a package or a standalone install tree. +if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) + set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON) +endif() + # -------------------------------------------------------------------------- # Dependencies # -------------------------------------------------------------------------- @@ -53,9 +77,13 @@ if(qRestAPI_QT_VERSION VERSION_GREATER "4") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT${qRestAPI_QT_VERSION}_INSTALL_PREFIX}) endif() +# Qt components used through the public interface of the library. They are +# recorded here so the generated package config can re-resolve them through +# find_dependency() for downstream consumers. +set(qRestAPI_QT_COMPONENTS Gui Network Qml) + if(qRestAPI_QT_VERSION VERSION_GREATER "4") - set(qRestAPI_QT${qRestAPI_QT_VERSION}_COMPONENTS Core Gui Network Qml Test) - find_package(Qt${qRestAPI_QT_VERSION} COMPONENTS ${qRestAPI_QT${qRestAPI_QT_VERSION}_COMPONENTS} REQUIRED) + find_package(Qt${qRestAPI_QT_VERSION} COMPONENTS Core ${qRestAPI_QT_COMPONENTS} Test REQUIRED) else() # HACK: QtXml is required because of "http://www.richelbilderbeek.nl/CppLinkErrorUndefinedReferenceToQListData.htm" find_package(Qt4 4.6.2 COMPONENTS QtCore QtGui QtNetwork QtScript QtXml QtTest REQUIRED) @@ -88,34 +116,6 @@ set(KIT_SRCS qRestResult.h ) -# -------------------------------------------------------------------------- -# Install headers -# -------------------------------------------------------------------------- -if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) - set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON) -endif() - -if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) - - if(NOT DEFINED ${PROJECT_NAME}_INSTALL_INCLUDE_DIR) - set(${PROJECT_NAME}_INSTALL_INCLUDE_DIR include/${PROJECT_NAME}) - endif() - - file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") - install( - FILES ${headers} - DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) - - file(GLOB headers "${CMAKE_CURRENT_BINARY_DIR}/*.h") - install( - FILES ${headers} - DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) -endif() - -# -------------------------------------------------------------------------- -# Sources -# -------------------------------------------------------------------------- - set(KIT_MOC_SRCS qGirderAPI.h qMidasAPI.h @@ -136,63 +136,88 @@ endif() # Build qRestAPI library # -------------------------------------------------------------------------- add_library(${PROJECT_NAME} ${KIT_SRCS} ${KIT_MOC_OUTPUT}) + +# Public usage requirements: consumers get the include directories through the +# imported target, resolved differently for the build tree and the install tree. +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + $ + ) + if(qRestAPI_QT_VERSION VERSION_GREATER "4") - target_link_libraries(${PROJECT_NAME} Qt${qRestAPI_QT_VERSION}::Gui Qt${qRestAPI_QT_VERSION}::Network Qt${qRestAPI_QT_VERSION}::Qml) + target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${qRestAPI_QT_VERSION}::Gui + Qt${qRestAPI_QT_VERSION}::Network + Qt${qRestAPI_QT_VERSION}::Qml) else() - target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES}) + target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_LIBRARIES}) endif() # -------------------------------------------------------------------------- -# Install library +# Export targets for a build tree # -------------------------------------------------------------------------- -if(NOT DEFINED ${PROJECT_NAME}_INSTALL_BIN_DIR) - set(${PROJECT_NAME}_INSTALL_BIN_DIR bin) -endif() -if(NOT DEFINED ${PROJECT_NAME}_INSTALL_LIB_DIR) - set(${PROJECT_NAME}_INSTALL_LIB_DIR lib/${PROJECT_NAME}) -endif() +export(TARGETS ${PROJECT_NAME} + FILE ${qRestAPI_BINARY_DIR}/qRestAPITargets.cmake) +# -------------------------------------------------------------------------- +# Install library +# -------------------------------------------------------------------------- install(TARGETS ${PROJECT_NAME} + EXPORT qRestAPITargets RUNTIME DESTINATION ${${PROJECT_NAME}_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries LIBRARY DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT Development ) # -------------------------------------------------------------------------- -# Configure support files +# Configure package config file for the build tree # -------------------------------------------------------------------------- -# Set qRestAPI_INSTALL_CMAKE_DIR -if(NOT DEFINED ${PROJECT_NAME}_INSTALL_CMAKE_DIR) - set(${PROJECT_NAME}_INSTALL_CMAKE_DIR cmake/${PROJECT_NAME}) -endif() - -export(TARGETS qRestAPI FILE ${qRestAPI_BINARY_DIR}/qRestAPIExports.cmake) - -# Configure qRestAPIConfig.cmake configure_file( ${qRestAPI_SOURCE_DIR}/qRestAPIConfig.cmake.in ${qRestAPI_BINARY_DIR}/qRestAPIConfig.cmake @ONLY) -# Configure qRestAPIConfig.cmake -configure_file( - ${qRestAPI_SOURCE_DIR}/qRestAPIInstallConfig.cmake.in - ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake @ONLY) - # -------------------------------------------------------------------------- -# Install configuration files +# Install development files # -------------------------------------------------------------------------- +if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) -# Install qRestAPIConfig cmake files -install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/install/qRestAPIConfig.cmake - DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} COMPONENT Development - ) + # Headers + file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + install( + FILES ${headers} + DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) + + file(GLOB headers "${CMAKE_CURRENT_BINARY_DIR}/*.h") + install( + FILES ${headers} + DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) + + # Relocatable package config file for the install tree + include(CMakePackageConfigHelpers) + configure_package_config_file( + ${qRestAPI_SOURCE_DIR}/qRestAPIInstallConfig.cmake.in + ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake + INSTALL_DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} + PATH_VARS ${PROJECT_NAME}_INSTALL_INCLUDE_DIR ${PROJECT_NAME}_INSTALL_LIB_DIR + ) + + install( + FILES ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake + DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} COMPONENT Development) + + # Exported targets for the install tree + install( + EXPORT qRestAPITargets + FILE qRestAPITargets.cmake + DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} COMPONENT Development) + +endif() # -------------------------------------------------------------------------- # Testing +# -------------------------------------------------------------------------- if(BUILD_TESTING) -include(CTest) + include(CTest) add_subdirectory(Testing) endif() - diff --git a/README.md b/README.md index d1ec6a1..0db1192 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,32 @@ It provides the following interfaces: cmake -DQT6_INSTALL_PREFIX:PATH=/path/to/QtX.Y.Z/X.Y.Z/gcc_64 ../qRestAPI make -j4 +## Installing / packaging + +By default only the runtime library is installed. To also install the +development files (headers, exported CMake targets and the package config +file) — e.g. when building a package or a standalone install tree — set +`qRestAPI_INSTALL_NO_DEVELOPMENT` to `OFF`: + + cmake -DqRestAPI_INSTALL_NO_DEVELOPMENT=OFF -DCMAKE_INSTALL_PREFIX=/path/to/prefix ../qRestAPI + make install + +The install tree is relocatable. Downstream projects consume it with: + + find_package(qRestAPI REQUIRED) + target_link_libraries(MyTarget PRIVATE qRestAPI) + +The following variables let a parent project (typically a superbuild) override +the install layout; each defaults to a standalone-friendly value when unset: + +| Variable | Default | +|-----------------------------------|----------------------| +| `qRestAPI_INSTALL_NO_DEVELOPMENT` | `ON` | +| `qRestAPI_INSTALL_BIN_DIR` | `bin` | +| `qRestAPI_INSTALL_LIB_DIR` | `lib/qRestAPI` | +| `qRestAPI_INSTALL_INCLUDE_DIR` | `include/qRestAPI` | +| `qRestAPI_INSTALL_CMAKE_DIR` | `cmake/qRestAPI` | + ## Testing To run tests checking that queries can successfully be executed. diff --git a/qRestAPIConfig.cmake.in b/qRestAPIConfig.cmake.in index 627aca1..8692698 100644 --- a/qRestAPIConfig.cmake.in +++ b/qRestAPIConfig.cmake.in @@ -1,5 +1,19 @@ -include("${CMAKE_CURRENT_BINARY_DIR}/qRestAPIExports.cmake") +# qRestAPI package configuration file for use from a build tree. + +include("@CMAKE_CURRENT_BINARY_DIR@/qRestAPITargets.cmake") + +# Re-resolve the Qt dependency so the imported target is usable downstream. +include(CMakeFindDependencyMacro) +if("@qRestAPI_QT_VERSION@" VERSION_GREATER "4") + find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) +else() + find_dependency(Qt4 COMPONENTS QtGui QtNetwork) +endif() set(qRestAPI_CMAKE_DIR "@qRestAPI_CMAKE_DIR@") + +# Legacy variables (kept for backward compatibility; prefer the imported +# qRestAPI target). +set(qRestAPI_LIBRARIES qRestAPI) set(qRestAPI_INCLUDE_DIRS "@qRestAPI_INCLUDE_DIRS@") set(qRestAPI_LIBRARY_DIRS "@qRestAPI_LIBRARY_DIRS@") diff --git a/qRestAPIInstallConfig.cmake.in b/qRestAPIInstallConfig.cmake.in index 87be75d..d77fa4d 100644 --- a/qRestAPIInstallConfig.cmake.in +++ b/qRestAPIInstallConfig.cmake.in @@ -1,3 +1,26 @@ -set(qRestAPI_CMAKE_DIR "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_CMAKE_DIR@") -set(qRestAPI_INCLUDE_DIRS "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_INCLUDE_DIR@") -set(qRestAPI_LIB_DIR "@CMAKE_INSTALL_PREFIX@/@qRestAPI_INSTALL_LIB_DIR@") +# qRestAPI package configuration file for use from an install tree. +# +# Generated with configure_package_config_file(): PACKAGE_PREFIX_DIR is computed +# at load time from the location of this file, so the install tree is +# relocatable (no absolute paths are baked in). +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/qRestAPITargets.cmake") + +# Re-resolve the Qt dependency so the imported target is usable downstream. +include(CMakeFindDependencyMacro) +if("@qRestAPI_QT_VERSION@" VERSION_GREATER "4") + find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) +else() + find_dependency(Qt4 COMPONENTS QtGui QtNetwork) +endif() + +set(qRestAPI_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}") + +# Legacy variables (kept for backward compatibility; prefer the imported +# qRestAPI target). +set(qRestAPI_LIBRARIES qRestAPI) +set_and_check(qRestAPI_INCLUDE_DIRS "@PACKAGE_qRestAPI_INSTALL_INCLUDE_DIR@") +set_and_check(qRestAPI_LIBRARY_DIRS "@PACKAGE_qRestAPI_INSTALL_LIB_DIR@") + +check_required_components(qRestAPI) From ae388db284d4484e500d8709a9a5104b3be46acc Mon Sep 17 00:00:00 2001 From: Rafael Palomar Date: Tue, 28 Jul 2026 09:24:01 +0200 Subject: [PATCH 3/3] COMP: Address review feedback (@lassoan) - Make qRestAPI_INSTALL_DEVELOPMENT a proper option() (default OFF), replacing the double-negative if(NOT DEFINED ..._INSTALL_NO_DEVELOPMENT); bump cmake_minimum_required to 3.16.3 so CMP0077 is NEW (option() honors a parent-set value). The deprecated ..._INSTALL_NO_DEVELOPMENT is still honored with a deprecation warning. - Move the *Config.cmake.in templates under CMake/ (gives the directory a reason to exist) and drop the now-pointless CMAKE_MODULE_PATH prepend. - In both config templates, call find_dependency(Qt...) before including the targets file (canonical ordering). - Exclude private *_p.h headers from the development install. - Drop Qt4 support (EOL; not relocatable in the install tree and its find_dependency component list didn't match the linked libraries). - Require the Qt Test component only when BUILD_TESTING is on (Testing/CMakeLists.txt), not as an unconditional dependency. - Use ${PROJECT_NAME}_ spellings consistently. --- .../qRestAPIConfig.cmake.in | 13 +-- .../qRestAPIInstallConfig.cmake.in | 13 +-- CMakeLists.txt | 97 +++++++++---------- README.md | 30 +++--- Testing/CMakeLists.txt | 13 ++- 5 files changed, 75 insertions(+), 91 deletions(-) rename qRestAPIConfig.cmake.in => CMake/qRestAPIConfig.cmake.in (62%) rename qRestAPIInstallConfig.cmake.in => CMake/qRestAPIInstallConfig.cmake.in (73%) diff --git a/qRestAPIConfig.cmake.in b/CMake/qRestAPIConfig.cmake.in similarity index 62% rename from qRestAPIConfig.cmake.in rename to CMake/qRestAPIConfig.cmake.in index 8692698..f64c0c5 100644 --- a/qRestAPIConfig.cmake.in +++ b/CMake/qRestAPIConfig.cmake.in @@ -1,14 +1,11 @@ # qRestAPI package configuration file for use from a build tree. -include("@CMAKE_CURRENT_BINARY_DIR@/qRestAPITargets.cmake") - -# Re-resolve the Qt dependency so the imported target is usable downstream. +# Re-resolve the Qt dependency first, so the imported target's link interface +# is satisfied for downstream consumers. include(CMakeFindDependencyMacro) -if("@qRestAPI_QT_VERSION@" VERSION_GREATER "4") - find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) -else() - find_dependency(Qt4 COMPONENTS QtGui QtNetwork) -endif() +find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) + +include("@CMAKE_CURRENT_BINARY_DIR@/qRestAPITargets.cmake") set(qRestAPI_CMAKE_DIR "@qRestAPI_CMAKE_DIR@") diff --git a/qRestAPIInstallConfig.cmake.in b/CMake/qRestAPIInstallConfig.cmake.in similarity index 73% rename from qRestAPIInstallConfig.cmake.in rename to CMake/qRestAPIInstallConfig.cmake.in index d77fa4d..57bdd70 100644 --- a/qRestAPIInstallConfig.cmake.in +++ b/CMake/qRestAPIInstallConfig.cmake.in @@ -5,15 +5,12 @@ # relocatable (no absolute paths are baked in). @PACKAGE_INIT@ -include("${CMAKE_CURRENT_LIST_DIR}/qRestAPITargets.cmake") - -# Re-resolve the Qt dependency so the imported target is usable downstream. +# Re-resolve the Qt dependency first, so the imported target's link interface +# is satisfied for downstream consumers. include(CMakeFindDependencyMacro) -if("@qRestAPI_QT_VERSION@" VERSION_GREATER "4") - find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) -else() - find_dependency(Qt4 COMPONENTS QtGui QtNetwork) -endif() +find_dependency(Qt@qRestAPI_QT_VERSION@ COMPONENTS @qRestAPI_QT_COMPONENTS@) + +include("${CMAKE_CURRENT_LIST_DIR}/qRestAPITargets.cmake") set(qRestAPI_CMAKE_DIR "${CMAKE_CURRENT_LIST_DIR}") diff --git a/CMakeLists.txt b/CMakeLists.txt index e3708d5..e85a0db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5.0) +cmake_minimum_required(VERSION 3.16.3) project(qRestAPI) @@ -12,10 +12,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE 1) # Directories # -------------------------------------------------------------------------- # -# CMake +# CMake: holds the package-config templates (*Config.cmake.in). # set(${PROJECT_NAME}_CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/CMake) -set(CMAKE_MODULE_PATH ${qRestAPI_CMAKE_DIR} ${CMAKE_MODULE_PATH}) # # Include # @@ -51,11 +50,24 @@ if(NOT DEFINED ${PROJECT_NAME}_INSTALL_CMAKE_DIR) set(${PROJECT_NAME}_INSTALL_CMAKE_DIR cmake/${PROJECT_NAME}) endif() -# By default only runtime files are installed. Set to OFF to also install the -# development files (headers, CMake package config, exported targets), e.g. when -# creating a package or a standalone install tree. -if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) - set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON) +# Install the development files (headers, CMake package config, exported +# targets) in addition to the runtime library. OFF by default so a plain +# install ships only the runtime; turn ON for packaging / standalone install +# trees. (CMP0077 is NEW at this cmake_minimum_required, so a parent project may +# still override this before add_subdirectory().) +option(${PROJECT_NAME}_INSTALL_DEVELOPMENT + "Install ${PROJECT_NAME} development files (headers, CMake package config, exported targets)" OFF) + +# Backward compatibility: honor the deprecated, inverted +# ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT if a consumer still sets it. +if(DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) + message(DEPRECATION + "${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT is deprecated; use ${PROJECT_NAME}_INSTALL_DEVELOPMENT (inverted value).") + if(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) + set(${PROJECT_NAME}_INSTALL_DEVELOPMENT OFF CACHE BOOL "" FORCE) + else() + set(${PROJECT_NAME}_INSTALL_DEVELOPMENT ON CACHE BOOL "" FORCE) + endif() endif() # -------------------------------------------------------------------------- @@ -65,35 +77,27 @@ endif() # # Qt # -set(qRestAPI_QT_VERSION "4" CACHE STRING "Expected Qt version") -mark_as_advanced(qRestAPI_QT_VERSION) -set_property(CACHE qRestAPI_QT_VERSION PROPERTY STRINGS 4 5 6) -if(NOT (qRestAPI_QT_VERSION VERSION_EQUAL "4" OR qRestAPI_QT_VERSION VERSION_EQUAL "5" OR qRestAPI_QT_VERSION VERSION_EQUAL "6")) - message(FATAL_ERROR "Expected value for qRestAPI_QT_VERSION is either '4', '5' or '6'") +set(${PROJECT_NAME}_QT_VERSION "5" CACHE STRING "Expected Qt version (5 or 6)") +mark_as_advanced(${PROJECT_NAME}_QT_VERSION) +set_property(CACHE ${PROJECT_NAME}_QT_VERSION PROPERTY STRINGS 5 6) +if(NOT (${PROJECT_NAME}_QT_VERSION VERSION_EQUAL "5" OR ${PROJECT_NAME}_QT_VERSION VERSION_EQUAL "6")) + message(FATAL_ERROR "Expected value for ${PROJECT_NAME}_QT_VERSION is either '5' or '6'") endif() -if(qRestAPI_QT_VERSION VERSION_GREATER "4") - set(QT${qRestAPI_QT_VERSION}_INSTALL_PREFIX "" CACHE PATH "The install location of Qt${qRestAPI_QT_VERSION}") - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT${qRestAPI_QT_VERSION}_INSTALL_PREFIX}) -endif() +set(QT${${PROJECT_NAME}_QT_VERSION}_INSTALL_PREFIX "" CACHE PATH "The install location of Qt${${PROJECT_NAME}_QT_VERSION}") +set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT${${PROJECT_NAME}_QT_VERSION}_INSTALL_PREFIX}) # Qt components used through the public interface of the library. They are # recorded here so the generated package config can re-resolve them through -# find_dependency() for downstream consumers. -set(qRestAPI_QT_COMPONENTS Gui Network Qml) - -if(qRestAPI_QT_VERSION VERSION_GREATER "4") - find_package(Qt${qRestAPI_QT_VERSION} COMPONENTS Core ${qRestAPI_QT_COMPONENTS} Test REQUIRED) -else() - # HACK: QtXml is required because of "http://www.richelbilderbeek.nl/CppLinkErrorUndefinedReferenceToQListData.htm" - find_package(Qt4 4.6.2 COMPONENTS QtCore QtGui QtNetwork QtScript QtXml QtTest REQUIRED) - include(${QT_USE_FILE}) -endif() +# find_dependency() for downstream consumers. The Test component is required +# only when building the tests (see Testing/CMakeLists.txt). +set(${PROJECT_NAME}_QT_COMPONENTS Gui Network Qml) +find_package(Qt${${PROJECT_NAME}_QT_VERSION} COMPONENTS Core ${${PROJECT_NAME}_QT_COMPONENTS} REQUIRED) if(BUILD_SHARED_LIBS) - set(qRestAPI_STATIC OFF) + set(${PROJECT_NAME}_STATIC OFF) else() - set(qRestAPI_STATIC ON) + set(${PROJECT_NAME}_STATIC ON) endif() # -------------------------------------------------------------------------- @@ -124,12 +128,10 @@ set(KIT_MOC_SRCS qRestResult.h ) -if(qRestAPI_QT_VERSION VERSION_GREATER "5") +if(${PROJECT_NAME}_QT_VERSION VERSION_GREATER "5") qt_wrap_cpp(KIT_MOC_OUTPUT ${KIT_MOC_SRCS}) -elseif(qRestAPI_QT_VERSION VERSION_GREATER "4") - qt5_wrap_cpp(KIT_MOC_OUTPUT ${KIT_MOC_SRCS}) else() - QT4_WRAP_CPP(KIT_MOC_OUTPUT ${KIT_MOC_SRCS}) + qt5_wrap_cpp(KIT_MOC_OUTPUT ${KIT_MOC_SRCS}) endif() # -------------------------------------------------------------------------- @@ -145,20 +147,16 @@ target_include_directories(${PROJECT_NAME} PUBLIC $ ) -if(qRestAPI_QT_VERSION VERSION_GREATER "4") - target_link_libraries(${PROJECT_NAME} PUBLIC - Qt${qRestAPI_QT_VERSION}::Gui - Qt${qRestAPI_QT_VERSION}::Network - Qt${qRestAPI_QT_VERSION}::Qml) -else() - target_link_libraries(${PROJECT_NAME} PUBLIC ${QT_LIBRARIES}) -endif() +target_link_libraries(${PROJECT_NAME} PUBLIC + Qt${${PROJECT_NAME}_QT_VERSION}::Gui + Qt${${PROJECT_NAME}_QT_VERSION}::Network + Qt${${PROJECT_NAME}_QT_VERSION}::Qml) # -------------------------------------------------------------------------- # Export targets for a build tree # -------------------------------------------------------------------------- export(TARGETS ${PROJECT_NAME} - FILE ${qRestAPI_BINARY_DIR}/qRestAPITargets.cmake) + FILE ${CMAKE_CURRENT_BINARY_DIR}/qRestAPITargets.cmake) # -------------------------------------------------------------------------- # Install library @@ -174,16 +172,17 @@ install(TARGETS ${PROJECT_NAME} # Configure package config file for the build tree # -------------------------------------------------------------------------- configure_file( - ${qRestAPI_SOURCE_DIR}/qRestAPIConfig.cmake.in - ${qRestAPI_BINARY_DIR}/qRestAPIConfig.cmake @ONLY) + ${${PROJECT_NAME}_CMAKE_DIR}/qRestAPIConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/qRestAPIConfig.cmake @ONLY) # -------------------------------------------------------------------------- # Install development files # -------------------------------------------------------------------------- -if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) +if(${PROJECT_NAME}_INSTALL_DEVELOPMENT) - # Headers + # Public headers (exclude private *_p.h headers) file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + list(FILTER headers EXCLUDE REGEX "_p\\.h$") install( FILES ${headers} DESTINATION ${${PROJECT_NAME}_INSTALL_INCLUDE_DIR} COMPONENT Development) @@ -196,14 +195,14 @@ if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT) # Relocatable package config file for the install tree include(CMakePackageConfigHelpers) configure_package_config_file( - ${qRestAPI_SOURCE_DIR}/qRestAPIInstallConfig.cmake.in - ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake + ${${PROJECT_NAME}_CMAKE_DIR}/qRestAPIInstallConfig.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/install/qRestAPIConfig.cmake INSTALL_DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} PATH_VARS ${PROJECT_NAME}_INSTALL_INCLUDE_DIR ${PROJECT_NAME}_INSTALL_LIB_DIR ) install( - FILES ${qRestAPI_BINARY_DIR}/install/qRestAPIConfig.cmake + FILES ${CMAKE_CURRENT_BINARY_DIR}/install/qRestAPIConfig.cmake DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKE_DIR} COMPONENT Development) # Exported targets for the install tree diff --git a/README.md b/README.md index 0db1192..0d108b5 100644 --- a/README.md +++ b/README.md @@ -16,17 +16,9 @@ It provides the following interfaces: ## Prerequisites - * [Qt](https://www.qt.io/) 4.x, 5.x, or 6.x + * [Qt](https://www.qt.io/) 5.x or 6.x * [CMake](http://www.cmake.org) -## How to build using Qt 4.x - - git clone git://github.com/commontk/qRestAPI.git - mkdir qRestAPI-build - cd qRestAPI-build - cmake -DQT_QMAKE_EXECUTABLE:FILEPATH=/path/to/qmake ../qRestAPI - make -j4 - ## How to build using Qt 5.x git clone git://github.com/commontk/qRestAPI.git @@ -47,10 +39,10 @@ It provides the following interfaces: By default only the runtime library is installed. To also install the development files (headers, exported CMake targets and the package config -file) — e.g. when building a package or a standalone install tree — set -`qRestAPI_INSTALL_NO_DEVELOPMENT` to `OFF`: +file) — e.g. when building a package or a standalone install tree — turn on +`qRestAPI_INSTALL_DEVELOPMENT`: - cmake -DqRestAPI_INSTALL_NO_DEVELOPMENT=OFF -DCMAKE_INSTALL_PREFIX=/path/to/prefix ../qRestAPI + cmake -DqRestAPI_INSTALL_DEVELOPMENT=ON -DCMAKE_INSTALL_PREFIX=/path/to/prefix ../qRestAPI make install The install tree is relocatable. Downstream projects consume it with: @@ -61,13 +53,13 @@ The install tree is relocatable. Downstream projects consume it with: The following variables let a parent project (typically a superbuild) override the install layout; each defaults to a standalone-friendly value when unset: -| Variable | Default | -|-----------------------------------|----------------------| -| `qRestAPI_INSTALL_NO_DEVELOPMENT` | `ON` | -| `qRestAPI_INSTALL_BIN_DIR` | `bin` | -| `qRestAPI_INSTALL_LIB_DIR` | `lib/qRestAPI` | -| `qRestAPI_INSTALL_INCLUDE_DIR` | `include/qRestAPI` | -| `qRestAPI_INSTALL_CMAKE_DIR` | `cmake/qRestAPI` | +| Variable | Default | +|--------------------------------|--------------------| +| `qRestAPI_INSTALL_DEVELOPMENT` | `OFF` | +| `qRestAPI_INSTALL_BIN_DIR` | `bin` | +| `qRestAPI_INSTALL_LIB_DIR` | `lib/qRestAPI` | +| `qRestAPI_INSTALL_INCLUDE_DIR` | `include/qRestAPI` | +| `qRestAPI_INSTALL_CMAKE_DIR` | `cmake/qRestAPI` | ## Testing diff --git a/Testing/CMakeLists.txt b/Testing/CMakeLists.txt index c41b5e8..6e9647d 100644 --- a/Testing/CMakeLists.txt +++ b/Testing/CMakeLists.txt @@ -18,21 +18,20 @@ foreach(file IN LISTS KIT_TEST_GENERATE_MOC_SRCS) set(moc_file ${CMAKE_CURRENT_BINARY_DIR}/moc_${source_name}.cpp) if(qRestAPI_QT_VERSION VERSION_GREATER "5") QT_GENERATE_MOC(${abs_file} ${moc_file}) - elseif(qRestAPI_QT_VERSION VERSION_GREATER "4") - QT5_GENERATE_MOC(${abs_file} ${moc_file}) else() - QT4_GENERATE_MOC(${abs_file} ${moc_file}) + QT5_GENERATE_MOC(${abs_file} ${moc_file}) endif() macro_add_file_dependencies(${abs_file} ${moc_file}) endforeach() add_definitions(-D_CRT_SECURE_NO_DEPRECATE) +# The Qt Test component is needed only for the tests, so it is resolved here +# rather than as an unconditional dependency of the library. +find_package(Qt${qRestAPI_QT_VERSION} COMPONENTS Test REQUIRED) + add_executable(qRestAPITests ${KIT_TESTDRIVER_SRCS}) -target_link_libraries(qRestAPITests qRestAPI) -if(qRestAPI_QT_VERSION VERSION_GREATER "4") - target_link_libraries(qRestAPITests Qt${qRestAPI_QT_VERSION}::Test) -endif() +target_link_libraries(qRestAPITests qRestAPI Qt${qRestAPI_QT_VERSION}::Test) macro(SIMPLE_TEST TESTNAME) add_test(NAME ${TESTNAME} COMMAND qRestAPITests ${TESTNAME})