From a3bc9331755dd8386c1d75fd01dd3b2617550674 Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Thu, 6 Mar 2025 07:00:40 +0100 Subject: [PATCH 1/2] Modernize cmake project files Fix install target Update cmake-format config file Format all cmake files. Update CPM.cmake version. Use FILE_SET HEADER to verify and install the header files. Prevent build problems caused by CPM_USE_LOCAL_PACKAGES Prevent problems with doctest if local found --- .cmake-format | 6 + .github/workflows/install.yml | 1 + .gitignore | 3 +- CMakeLists.txt | 55 ++++++-- README.md | 6 +- all/CMakeLists.txt | 2 +- cmake/AddUninstallTarget.cmake | 101 ++++++++++++++ cmake/CPM.cmake | 4 +- cmake/Config.cmake.in | 10 ++ cmake/PackageProject.cmake | 244 +++++++++++++++++++++++++++++++++ cmake/version.h.in | 8 ++ documentation/CMakeLists.txt | 2 +- standalone/CMakeLists.txt | 10 +- test/CMakeLists.txt | 21 ++- 14 files changed, 441 insertions(+), 32 deletions(-) create mode 100644 cmake/AddUninstallTarget.cmake create mode 100644 cmake/Config.cmake.in create mode 100644 cmake/PackageProject.cmake create mode 100644 cmake/version.h.in diff --git a/.cmake-format b/.cmake-format index 8c355cf..f1260a6 100644 --- a/.cmake-format +++ b/.cmake-format @@ -51,7 +51,13 @@ parse: NAMESPACE: 1 INCLUDE_DIR: 1 INCLUDE_DESTINATION: 1 + INCLUDE_HEADER_PATTERN: 1 BINARY_DIR: 1 COMPATIBILITY: 1 VERSION_HEADER: 1 + EXPORT_HEADER: 1 + DISABLE_VERSION_SUFFIX: 1 + CPACK: 1 + RUNTIME_DESTINATION: 1 DEPENDENCIES: + + HEADER_SETS: + diff --git a/.github/workflows/install.yml b/.github/workflows/install.yml index f10b6dd..a7e1aa7 100644 --- a/.github/workflows/install.yml +++ b/.github/workflows/install.yml @@ -29,6 +29,7 @@ jobs: - name: build and install library run: | cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release + cmake --build build --target all_verify_interface_header_sets sudo cmake --build build --target install rm -rf build diff --git a/.gitignore b/.gitignore index d54a4f4..a6c811e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ +build/ /build* /.vscode /cpm_modules -.DS_Store \ No newline at end of file +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 31cf517..0799cb9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14...3.22) +cmake_minimum_required(VERSION 3.24...3.31) # ---- Project ---- @@ -24,15 +24,20 @@ endif() include(cmake/CPM.cmake) # PackageProject.cmake will be used to make our target installable -CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.8.0") +include(cmake/PackageProject.cmake) +# XXX # CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.13.0") + +# XXX set(CMAKE_SKIP_INSTALL_RULES YES) CPMAddPackage( NAME fmt - GIT_TAG 10.2.1 + GIT_TAG 11.1.4 GITHUB_REPOSITORY fmtlib/fmt OPTIONS "FMT_INSTALL YES" # create an installable target ) +set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL}) + # ---- Add source files ---- # Note: globbing sources is considered bad practice as CMake's generators may not detect new files @@ -42,9 +47,27 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/ # ---- Create library ---- +# the location where the project's version header will be placed should match the project's regular +# header paths +string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION) + # Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface # target: add_library(${PROJECT_NAME} INTERFACE) -add_library(${PROJECT_NAME} ${headers} ${sources}) +add_library(${PROJECT_NAME}) +target_sources( + ${PROJECT_NAME} + PRIVATE ${sources} + PUBLIC FILE_SET + public_headers + TYPE + HEADERS + BASE_DIRS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR} + FILES + ${headers} + ${CMAKE_CURRENT_BINARY_DIR}/${VERSION_HEADER_LOCATION} +) set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17) # being a cross-platform target, we enforce standards conformance on MSVC @@ -53,26 +76,28 @@ target_compile_options(${PROJECT_NAME} PUBLIC "$<$ # Link dependencies target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt) -target_include_directories( - ${PROJECT_NAME} PUBLIC $ - $ -) +set(GREETER_VERSION \"${PROJECT_VERSION}\") +string(TOUPPER ${PROJECT_NAME} UPPERCASE_PROJECT_NAME) +configure_file(${PACKAGE_PROJECT_ROOT_PATH}/version.h.in ${VERSION_HEADER_LOCATION} @ONLY) + +if(CMAKE_SKIP_INSTALL_RULES) + add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + return() +endif() # ---- Create an installable target ---- # this allows users to install and find the library via `find_package()`. -# the location where the project's version header will be placed should match the project's regular -# header paths -string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION) +include(cmake/AddUninstallTarget.cmake) packageProject( NAME ${PROJECT_NAME} VERSION ${PROJECT_VERSION} NAMESPACE ${PROJECT_NAME} BINARY_DIR ${PROJECT_BINARY_DIR} - INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include - INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION} - VERSION_HEADER "${VERSION_HEADER_LOCATION}" + # Not used! INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include COMPATIBILITY SameMajorVersion - DEPENDENCIES "fmt 10.2.1" + RUNTIME_DESTINATION / + DEPENDENCIES "fmt 11.1.4" + HEADER_SETS public_headers ) diff --git a/README.md b/README.md index 46b6226..b4c561c 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ This template is the result of learnings from many previous projects and should Eventually, you can remove any unused files, such as the standalone directory or irrelevant github workflows for your project. Feel free to replace the License with one suited for your project. -To cleanly separate the library and subproject code, the outer `CMakeList.txt` only defines the library itself while the tests and other subprojects are self-contained in their own directories. +To cleanly separate the library and subproject code, the outer `CMakeList.txt` only defines the library itself while the tests and other subprojects are self-contained in their own directories. During development it is usually convenient to [build all subprojects at once](#build-everything-at-once). ### Build and run the standalone target @@ -66,7 +66,7 @@ cmake -S test -B build/test cmake --build build/test CTEST_OUTPUT_ON_FAILURE=1 cmake --build build/test --target test -# or simply call the executable: +# or simply call the executable: ./build/test/GreeterTests ``` @@ -91,7 +91,7 @@ See [Format.cmake](https://github.com/TheLartians/Format.cmake) for details. These dependencies can be easily installed using pip. ```bash -pip install clang-format==14.0.6 cmake_format==0.6.11 pyyaml +pip install cmake clang-format cmake_format==0.6.11 pyyaml ``` ### Build the documentation diff --git a/all/CMakeLists.txt b/all/CMakeLists.txt index 8092382..431390f 100644 --- a/all/CMakeLists.txt +++ b/all/CMakeLists.txt @@ -1,7 +1,7 @@ # this script adds all subprojects to a single build to allow IDEs understand the full project # structure. -cmake_minimum_required(VERSION 3.14...3.22) +cmake_minimum_required(VERSION 3.24...3.31) project(BuildAll LANGUAGES CXX) diff --git a/cmake/AddUninstallTarget.cmake b/cmake/AddUninstallTarget.cmake new file mode 100644 index 0000000..c539c0d --- /dev/null +++ b/cmake/AddUninstallTarget.cmake @@ -0,0 +1,101 @@ +# SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT) SPDX-FileCopyrightText: +# 2008-2013 Kitware Inc. SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +AddUninstallTarget +------------------ + +Add the "uninstall" target for your project:: + + include(AddUninstallTarget) + + +will create a file ``cmake_uninstall.cmake`` in the build directory and add a +custom target ``uninstall`` (or ``UNINSTALL`` on Visual Studio and Xcode) that +will remove the files installed by your package (using +``install_manifest.txt``). +See also +https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake + +The :module:`AddUninstallTarget` module must be included in your main +``CMakeLists.txt``. If included in a subdirectory it does nothing. +This allows you to use it safely in your main ``CMakeLists.txt`` and include +your project using ``add_subdirectory`` (for example when using it with +:cmake:module:`FetchContent`). + +If the ``uninstall`` target already exists, the module does nothing. +#]=======================================================================] + +# AddUninstallTarget works only when included in the main CMakeLists.txt +if(NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") + return() +endif() + +# The name of the target is uppercase in MSVC and Xcode (for coherence with the other standard +# targets) +if("${CMAKE_GENERATOR}" MATCHES "^(Visual Studio|Xcode)") + set(_uninstall "UNINSTALL") +else() + set(_uninstall "uninstall") +endif() + +# If target is already defined don't do anything +if(TARGET ${_uninstall}) + return() +endif() + +set(_filename cmake_uninstall.cmake) + +file( + WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_filename}" + "if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\") + message(WARNING \"Cannot find install manifest: \\\"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\\\"\") + return() +endif() + +file(READ \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\" files) +string(STRIP \"\${files}\" files) +string(REGEX REPLACE \"\\n\" \";\" files \"\${files}\") +list(REVERSE files) +foreach(file \${files}) + if(IS_SYMLINK \"\$ENV{DESTDIR}\${file}\" OR EXISTS \"\$ENV{DESTDIR}\${file}\") + message(STATUS \"Uninstalling: \$ENV{DESTDIR}\${file}\") + execute_process( + COMMAND \${CMAKE_COMMAND} -E remove \"\$ENV{DESTDIR}\${file}\" + OUTPUT_VARIABLE rm_out + RESULT_VARIABLE rm_retval) + if(NOT \"\${rm_retval}\" EQUAL 0) + message(FATAL_ERROR \"Problem when removing \\\"\$ENV{DESTDIR}\${file}\\\"\") + endif() + else() + message(STATUS \"Not-found: \$ENV{DESTDIR}\${file}\") + endif() +endforeach(file) +" +) + +set(_desc "Uninstall the project...") +if(CMAKE_GENERATOR STREQUAL "Unix Makefiles") + set(_comment + COMMAND + \$\(CMAKE_COMMAND\) + -E + cmake_echo_color + --switch=$\(COLOR\) + --cyan + "${_desc}" + ) +else() + set(_comment COMMENT "${_desc}") +endif() +add_custom_target( + ${_uninstall} + ${_comment} + COMMAND ${CMAKE_COMMAND} -P ${_filename} + USES_TERMINAL + BYPRODUCTS uninstall_byproduct + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) +set_property(SOURCE uninstall_byproduct PROPERTY SYMBOLIC 1) + +set_property(TARGET ${_uninstall} PROPERTY FOLDER "CMakePredefinedTargets") diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index baf2d8c..9d87d01 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -2,8 +2,8 @@ # # SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors -set(CPM_DOWNLOAD_VERSION 0.40.2) -set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d") +set(CPM_DOWNLOAD_VERSION 0.40.7) +set(CPM_HASH_SUM "c0fc82149e00c43a21febe7b2ca57b2ffea2b8e88ab867022c21d6b81937eb50") if(CPM_SOURCE_CACHE) set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 0000000..15f626a --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,10 @@ +include(CMakeFindDependencyMacro) + +string(REGEX MATCHALL "[^;]+" SEPARATE_DEPENDENCIES "@PROJECT_DEPENDENCIES@") + +foreach(dependency ${SEPARATE_DEPENDENCIES}) + string(REPLACE " " ";" args "${dependency}") + find_dependency(${args}) +endforeach() + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/cmake/PackageProject.cmake b/cmake/PackageProject.cmake new file mode 100644 index 0000000..4ae36d5 --- /dev/null +++ b/cmake/PackageProject.cmake @@ -0,0 +1,244 @@ +cmake_minimum_required(VERSION 3.14...3.31) + +set(PACKAGE_PROJECT_ROOT_PATH + "${CMAKE_CURRENT_LIST_DIR}" + CACHE INTERNAL "The path to the PackageProject directory" +) + +# if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.31.0") cmake_policy(SET CMP0177 NEW) endif() + +function(packageProject) + include(CMakePackageConfigHelpers) + include(GNUInstallDirs) + + cmake_parse_arguments( + PROJECT + "" + "NAME;VERSION;INCLUDE_DIR;INCLUDE_DESTINATION;BINARY_DIR;COMPATIBILITY;EXPORT_HEADER;VERSION_HEADER;NAMESPACE;DISABLE_VERSION_SUFFIX;ARCH_INDEPENDENT;INCLUDE_HEADER_PATTERN;CPACK;RUNTIME_DESTINATION" + "DEPENDENCIES;HEADER_SETS" + ${ARGN} + ) + + # optional feature: TRUE or FALSE or UNDEFINED! These variables will then hold the respective + # value from the argument list or be undefined if the associated one_value_keyword could not be + # found. + if(PROJECT_DISABLE_VERSION_SUFFIX) + unset(PROJECT_VERSION_SUFFIX) + else() + set(PROJECT_VERSION_SUFFIX -${PROJECT_VERSION}) + endif() + + if(NOT DEFINED PROJECT_COMPATIBILITY) + set(PROJECT_COMPATIBILITY AnyNewerVersion) + endif() + + # we want to automatically add :: to our namespace, so only append if a namespace was given in the + # first place we also provide an alias to ensure that local and installed versions have the same + # name + if(DEFINED PROJECT_NAMESPACE) + if(PROJECT_CPACK) + set(CPACK_PACKAGE_NAMESPACE ${PROJECT_NAMESPACE}) + endif() + set(PROJECT_NAMESPACE ${PROJECT_NAMESPACE}::) + add_library(${PROJECT_NAMESPACE}${PROJECT_NAME} ALIAS ${PROJECT_NAME}) + endif() + + if(DEFINED PROJECT_VERSION_HEADER OR DEFINED PROJECT_EXPORT_HEADER) + set(PROJECT_VERSION_INCLUDE_DIR ${PROJECT_BINARY_DIR}/PackageProjectInclude) + + if(DEFINED PROJECT_EXPORT_HEADER) + include(GenerateExportHeader) + generate_export_header( + ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_VERSION_INCLUDE_DIR}/${PROJECT_EXPORT_HEADER} + ) + endif() + + if(DEFINED PROJECT_VERSION_HEADER) + # clear previous matches + unset(CMAKE_MATCH_1) + unset(CMAKE_MATCH_3) + unset(CMAKE_MATCH_5) + unset(CMAKE_MATCH_7) + + string(REGEX MATCH "^([0-9]+)(\\.([0-9]+))?(\\.([0-9]+))?(\\.([0-9]+))?$" _ + "${PROJECT_VERSION}" + ) + + set(PROJECT_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(PROJECT_VERSION_MINOR ${CMAKE_MATCH_3}) + set(PROJECT_VERSION_PATCH ${CMAKE_MATCH_5}) + set(PROJECT_VERSION_TWEAK ${CMAKE_MATCH_7}) + + if(NOT DEFINED PROJECT_VERSION_MAJOR) + set(PROJECT_VERSION_MAJOR "0") + endif() + if(NOT DEFINED PROJECT_VERSION_MINOR) + set(PROJECT_VERSION_MINOR "0") + endif() + if(NOT DEFINED PROJECT_VERSION_PATCH) + set(PROJECT_VERSION_PATCH "0") + endif() + if(NOT DEFINED PROJECT_VERSION_TWEAK) + set(PROJECT_VERSION_TWEAK "0") + endif() + + string(TOUPPER ${PROJECT_NAME} UPPERCASE_PROJECT_NAME) + # ensure that the generated macro does not include invalid characters + string(REGEX REPLACE [^a-zA-Z0-9] _ UPPERCASE_PROJECT_NAME ${UPPERCASE_PROJECT_NAME}) + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/version.h.in + ${PROJECT_VERSION_INCLUDE_DIR}/${PROJECT_VERSION_HEADER} @ONLY + ) + endif() + + get_target_property(target_type ${PROJECT_NAME} TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(VISIBILITY INTERFACE) + else() + set(VISIBILITY PUBLIC) + endif() + target_include_directories( + ${PROJECT_NAME} ${VISIBILITY} "$" + ) + install( + DIRECTORY ${PROJECT_VERSION_INCLUDE_DIR}/ + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + ) + endif() + + set(wbpvf_extra_args "") + if(NOT DEFINED PROJECT_ARCH_INDEPENDENT) + get_target_property(target_type "${PROJECT_NAME}" TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(PROJECT_ARCH_INDEPENDENT YES) + endif() + endif() + + if(PROJECT_ARCH_INDEPENDENT) + set(wbpvf_extra_args ARCH_INDEPENDENT) + # install to architecture independent (share) directory + set(INSTALL_DIR_FOR_CMAKE_CONFIGS ${CMAKE_INSTALL_DATADIR}) + else() + # if x32 or multilib->x32 , install to (lib) directory. if x64, install to (lib64) directory + set(INSTALL_DIR_FOR_CMAKE_CONFIGS ${CMAKE_INSTALL_LIBDIR}) + endif() + + write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY ${PROJECT_COMPATIBILITY} ${wbpvf_extra_args} + ) + + # set default runtime install subdirectory (RUNTIME_DESTINATION) + if(NOT DEFINED PROJECT_RUNTIME_DESTINATION) + set(PROJECT_RUNTIME_DESTINATION ${PROJECT_NAME}${PROJECT_VERSION_SUFFIX}) + endif() + + if(PROJECT_HEADER_SETS) + # required to install if use in project target since CMake 3.23 + set(FILE_SET_ARGS "FILE_SET" "${PROJECT_HEADER_SETS}") + endif() + + install( + TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + NAMELINK_COMPONENT "${PROJECT_NAME}_Development" + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_RUNTIME_DESTINATION} + COMPONENT "${PROJECT_NAME}_Runtime" + PUBLIC_HEADER + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + ${FILE_SET_ARGS} + INCLUDES + DESTINATION "${PROJECT_INCLUDE_DESTINATION}" + ) + + set("${PROJECT_NAME}_INSTALL_CMAKEDIR" + "${INSTALL_DIR_FOR_CMAKE_CONFIGS}/cmake/${PROJECT_NAME}${PROJECT_VERSION_SUFFIX}" + CACHE PATH "CMake package config location relative to the install prefix" + ) + + mark_as_advanced("${PROJECT_NAME}_INSTALL_CMAKEDIR") + + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/Config.cmake.in + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY + ) + + install( + EXPORT ${PROJECT_NAME}Targets + DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" + NAMESPACE ${PROJECT_NAMESPACE} + COMPONENT "${PROJECT_NAME}_Development" + ) + + install( + FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" + COMPONENT "${PROJECT_NAME}_Development" + ) + + if(NOT DEFINED PROJECT_INCLUDE_HEADER_PATTERN) + set(PROJECT_INCLUDE_HEADER_PATTERN "*") + endif() + + if(PROJECT_INCLUDE_DESTINATION AND PROJECT_INCLUDE_DIR) + install( + DIRECTORY ${PROJECT_INCLUDE_DIR}/ + DESTINATION ${PROJECT_INCLUDE_DESTINATION} + COMPONENT "${PROJECT_NAME}_Development" + FILES_MATCHING + PATTERN "${PROJECT_INCLUDE_HEADER_PATTERN}" + ) + endif() + + set(${PROJECT_NAME}_VERSION + ${PROJECT_VERSION} + CACHE INTERNAL "" + ) + + if(PROJECT_CPACK) + if(CPACK_PACKAGE_NAMESPACE) + set(CPACK_PACKAGE_NAME ${CPACK_PACKAGE_NAMESPACE}-${PROJECT_NAME}) + else() + set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) + endif() + if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}") + endif() + if(NOT CPACK_PACKAGE_HOMEPAGE_URL) + set(CPACK_PACKAGE_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}") + endif() + set(CPACK_VERBATIM_VARIABLES YES) + set(CPACK_THREADS 0) + set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) + + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + endif() + + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS + OWNER_READ + OWNER_WRITE + OWNER_EXECUTE + GROUP_READ + GROUP_EXECUTE + WORLD_READ + WORLD_EXECUTE + ) + + include(CPack) + endif() +endfunction() diff --git a/cmake/version.h.in b/cmake/version.h.in new file mode 100644 index 0000000..e74e3eb --- /dev/null +++ b/cmake/version.h.in @@ -0,0 +1,8 @@ +#pragma once + +#define @UPPERCASE_PROJECT_NAME@_VERSION "@PROJECT_VERSION@" + +#define @UPPERCASE_PROJECT_NAME@_VERSION_MAJOR @PROJECT_VERSION_MAJOR@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_MINOR @PROJECT_VERSION_MINOR@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_PATCH @PROJECT_VERSION_PATCH@ +#define @UPPERCASE_PROJECT_NAME@_VERSION_TWEAK @PROJECT_VERSION_TWEAK@ diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index edc3f62..ea39bb9 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14...3.22) +cmake_minimum_required(VERSION 3.24...3.31) project(GreeterDocs) diff --git a/standalone/CMakeLists.txt b/standalone/CMakeLists.txt index a932149..3858d6f 100644 --- a/standalone/CMakeLists.txt +++ b/standalone/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14...3.22) +cmake_minimum_required(VERSION 3.24...3.31) project(GreeterStandalone LANGUAGES CXX) @@ -12,11 +12,15 @@ include(../cmake/CPM.cmake) CPMAddPackage( GITHUB_REPOSITORY jarro2783/cxxopts - VERSION 3.0.0 + VERSION 3.2.1 OPTIONS "CXXOPTS_BUILD_EXAMPLES NO" "CXXOPTS_BUILD_TESTS NO" "CXXOPTS_ENABLE_INSTALL YES" ) -CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) +CPMAddPackage( + NAME Greeter + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. + FORCE ON +) # ---- Create standalone executable ---- diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 74cd08d..eaa807b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.14...3.22) +cmake_minimum_required(VERSION 3.24...3.31) project(GreeterTests LANGUAGES CXX) @@ -15,13 +15,17 @@ include(../cmake/tools.cmake) include(../cmake/CPM.cmake) -CPMAddPackage("gh:doctest/doctest@2.4.9") -CPMAddPackage("gh:TheLartians/Format.cmake@1.7.3") +CPMAddPackage("gh:doctest/doctest@2.4.11") +CPMAddPackage("gh:TheLartians/Format.cmake@1.8.3") if(TEST_INSTALLED_VERSION) find_package(Greeter REQUIRED) else() - CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) + CPMAddPackage( + NAME Greeter + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. + FORCE ON + ) endif() # ---- Create binary ---- @@ -49,8 +53,13 @@ enable_testing() # testing frameworks add the tests target instead: add_test(NAME ${PROJECT_NAME} COMMAND # ${PROJECT_NAME}) -include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) -doctest_discover_tests(${PROJECT_NAME}) +# prevent problems if CPM_USE_LOCAL_PACKAGES is set: +if(EXISTS ${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) + include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) + doctest_discover_tests(${PROJECT_NAME}) +else() + add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) +endif # ---- code coverage ---- From 95470160d81b4be3ea327de24e0f614ddf9595f8 Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Thu, 6 Mar 2025 07:14:51 +0100 Subject: [PATCH 2/2] Set CMAKE_EXPORT_COMPILE_COMMANDS too --- cmake/tools.cmake | 2 ++ test/CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/tools.cmake b/cmake/tools.cmake index e884c36..31922d4 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -6,6 +6,8 @@ if(NOT PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) return() endif() +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) # enables sanitizers support using the the `USE_SANITIZER` flag available values are: Address, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index eaa807b..353ecfd 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -59,7 +59,7 @@ if(EXISTS ${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) doctest_discover_tests(${PROJECT_NAME}) else() add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) -endif +endif() # ---- code coverage ----