diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d40175a..8759821 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -29,6 +29,19 @@ jobs: with: cmake-version: 3.18.4 + - name: install PackageProject.cmake and test it + run: | + cmake -S . -B build/install -DPackageProject.cmake_INSTALL=ON + cmake --install build/install --prefix ./install_dir + CMAKE_PREFIX_PATH=./install_dir cmake -S test -B build/test_installed_prefix -DTEST_INSTALLED_VERSION_PACKAGEPROJECT=ON + cmake --build build/test_installed_prefix + cmake --build build/test_installed_prefix --target test + sudo cmake --install build/install + cmake -S test -B build/test_installed -DTEST_INSTALLED_VERSION_PACKAGEPROJECT=ON + cmake --build build/test_installed + cmake --build build/test_installed --target test + sudo cmake --install build/test_installed + - name: test and install local build run: | cmake -S test -B build/local diff --git a/.gitignore b/.gitignore index 0b84e72..1068f65 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ /.cache /compile_commands.json /install_dir +/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake +/cmake/PackageProject.cmake/PackageProject.cmakeConfigVersion.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index c2b844e..1da7ae5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,234 +1,64 @@ cmake_minimum_required(VERSION 3.14) -set(PACKAGE_PROJECT_ROOT_PATH - "${CMAKE_CURRENT_LIST_DIR}" - CACHE INTERNAL "The path to the PackageProject directory" -) - -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" - ${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() +project(PackageProject.cmake VERSION 13.0.5) - if(DEFINED PROJECT_VERSION_HEADER OR DEFINED PROJECT_EXPORT_HEADER) - set(PROJECT_VERSION_INCLUDE_DIR ${PROJECT_BINARY_DIR}/PackageProjectInclude) +option(${PROJECT_NAME}_INSTALL "Install the script for local system?" NO) - 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() +set(PACKAGE_PROJECT_ROOT_PATH_DEFAULT_VALUE "\$\{CMAKE_CURRENT_LIST_DIR\}/PackageProjectFiles") - 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() +set(PACKAGE_PROJECT_ROOT_PATH + "${PACKAGE_PROJECT_ROOT_PATH_DEFAULT_VALUE}" + CACHE + PATH + "The path to the PackageProject directory in which will be Config.cmake.in and version.h.in" +) - write_basic_package_version_file( - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY ${PROJECT_COMPATIBILITY} ${wbpvf_extra_args} - ) +include(CMakePackageConfigHelpers) - # set default runtime install subdirectory (RUNTIME_DESTINATION) - if(NOT DEFINED PROJECT_RUNTIME_DESTINATION) - set(PROJECT_RUNTIME_DESTINATION ${PROJECT_NAME}${PROJECT_VERSION_SUFFIX}) - endif() +include(GNUInstallDirs) - 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" - INCLUDES - DESTINATION "${PROJECT_INCLUDE_DESTINATION}" - ) +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake.in + ${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_DATADIR}/cmake/PackageProject.cmake +) - 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" - ) +write_basic_package_version_file( + ${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfigVersion.cmake + VERSION ${PackageProject.cmake_VERSION} + COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT +) - mark_as_advanced("${PROJECT_NAME}_INSTALL_CMAKEDIR") +if(${PackageProject.cmake_INSTALL}) - configure_file( - ${PACKAGE_PROJECT_ROOT_PATH}/Config.cmake.in - "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" @ONLY + set(CMAKEDIR + ${CMAKE_INSTALL_DATADIR}/cmake/PackageProject.cmake/ + CACHE + PATH + "Path to a folder to which install the script PackageProjectConfig.cmake . By default: ${CMAKE_INSTALL_DATADIR}/cmake/PackageProject.cmake/" ) install( - EXPORT ${PROJECT_NAME}Targets - DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKEDIR}" - NAMESPACE ${PROJECT_NAMESPACE} - COMPONENT "${PROJECT_NAME}_Development" + FILES "${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake" + DESTINATION "${CMAKEDIR}" ) 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" + FILES + "${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfigVersion.cmake" + DESTINATION "${CMAKEDIR}" ) - - 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}" + if("${PACKAGE_PROJECT_ROOT_PATH_DEFAULT_VALUE}" STREQUAL "${PACKAGE_PROJECT_ROOT_PATH}") + install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProjectFiles" + DESTINATION "${CMAKEDIR}" + ) + else() + install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProjectFiles" + DESTINATION "${PACKAGE_PROJECT_ROOT_PATH}/../" ) endif() - set(${PROJECT_NAME}_VERSION - ${PROJECT_VERSION} - CACHE INTERNAL "" - ) + message(STATUS "Use `find_package(PackageProject.cmake)` to use it.") +endif() - 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() +include(${CMAKE_CURRENT_LIST_DIR}/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake) diff --git a/Config.cmake.in b/Config.cmake.in deleted file mode 100644 index 15f626a..0000000 --- a/Config.cmake.in +++ /dev/null @@ -1,10 +0,0 @@ -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/PackageProject.cmakeConfig.cmake.in b/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake.in new file mode 100644 index 0000000..f26ae64 --- /dev/null +++ b/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake.in @@ -0,0 +1,253 @@ +set(PackageProject.cmake_VERSION @PackageProject.cmake_VERSION@) + +set(PACKAGE_PROJECT_ROOT_PATH + "@PACKAGE_PROJECT_ROOT_PATH@" + CACHE INTERNAL "The path to the PackageProject directory" +) + +@PACKAGE_INIT@ + +function(packageProject) + include(CMakePackageConfigHelpers) + include(GNUInstallDirs) + + cmake_parse_arguments( + PACKAGEPROJECTLOCALVAR + "" + "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" + ${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(PACKAGEPROJECTLOCALVAR_DISABLE_VERSION_SUFFIX) + unset(PACKAGEPROJECTLOCALVAR_VERSION_SUFFIX) + else() + set(PACKAGEPROJECTLOCALVAR_VERSION_SUFFIX -${PACKAGEPROJECTLOCALVAR_VERSION}) + endif() + + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_COMPATIBILITY) + set(PACKAGEPROJECTLOCALVAR_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 PACKAGEPROJECTLOCALVAR_NAMESPACE) + if(PACKAGEPROJECTLOCALVAR_CPACK) + set(CPACK_PACKAGE_NAMESPACE ${PACKAGEPROJECTLOCALVAR_NAMESPACE}) + endif() + set(PACKAGEPROJECTLOCALVAR_NAMESPACE ${PACKAGEPROJECTLOCALVAR_NAMESPACE}::) + add_library( + ${PACKAGEPROJECTLOCALVAR_NAMESPACE}${PACKAGEPROJECTLOCALVAR_NAME} ALIAS + ${PACKAGEPROJECTLOCALVAR_NAME} + ) + endif() + + if(DEFINED PACKAGEPROJECTLOCALVAR_VERSION_HEADER OR DEFINED PACKAGEPROJECTLOCALVAR_EXPORT_HEADER) + set(PACKAGEPROJECTLOCALVAR_VERSION_INCLUDE_DIR + ${PACKAGEPROJECTLOCALVAR_BINARY_DIR}/PackageProjectInclude + ) + + if(DEFINED PACKAGEPROJECTLOCALVAR_EXPORT_HEADER) + include(GenerateExportHeader) + generate_export_header( + ${PACKAGEPROJECTLOCALVAR_NAME} EXPORT_FILE_NAME + ${PACKAGEPROJECTLOCALVAR_VERSION_INCLUDE_DIR}/${PACKAGEPROJECTLOCALVAR_EXPORT_HEADER} + ) + endif() + + if(DEFINED PACKAGEPROJECTLOCALVAR_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]+))?$" _ + "${PACKAGEPROJECTLOCALVAR_VERSION}" + ) + + set(PACKAGEPROJECTLOCALVAR_VERSION_MAJOR ${CMAKE_MATCH_1}) + set(PACKAGEPROJECTLOCALVAR_VERSION_MINOR ${CMAKE_MATCH_3}) + set(PACKAGEPROJECTLOCALVAR_VERSION_PATCH ${CMAKE_MATCH_5}) + set(PACKAGEPROJECTLOCALVAR_VERSION_TWEAK ${CMAKE_MATCH_7}) + + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_VERSION_MAJOR) + set(PACKAGEPROJECTLOCALVAR_VERSION_MAJOR "0") + endif() + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_VERSION_MINOR) + set(PACKAGEPROJECTLOCALVAR_VERSION_MINOR "0") + endif() + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_VERSION_PATCH) + set(PACKAGEPROJECTLOCALVAR_VERSION_PATCH "0") + endif() + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_VERSION_TWEAK) + set(PACKAGEPROJECTLOCALVAR_VERSION_TWEAK "0") + endif() + + string(TOUPPER ${PACKAGEPROJECTLOCALVAR_NAME} UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME) + # ensure that the generated macro does not include invalid characters + string(REGEX REPLACE [^a-zA-Z0-9] _ UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME + ${UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME} + ) + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/version.h.in + ${PACKAGEPROJECTLOCALVAR_VERSION_INCLUDE_DIR}/${PACKAGEPROJECTLOCALVAR_VERSION_HEADER} + @ONLY + ) + endif() + + get_target_property(target_type ${PACKAGEPROJECTLOCALVAR_NAME} TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(VISIBILITY INTERFACE) + else() + set(VISIBILITY PUBLIC) + endif() + target_include_directories( + ${PACKAGEPROJECTLOCALVAR_NAME} ${VISIBILITY} + "$" + ) + install( + DIRECTORY ${PACKAGEPROJECTLOCALVAR_VERSION_INCLUDE_DIR}/ + DESTINATION ${PACKAGEPROJECTLOCALVAR_INCLUDE_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + ) + endif() + + set(wbpvf_extra_args "") + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_ARCH_INDEPENDENT) + get_target_property(target_type "${PACKAGEPROJECTLOCALVAR_NAME}" TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + set(PACKAGEPROJECTLOCALVAR_ARCH_INDEPENDENT YES) + endif() + endif() + + if(PACKAGEPROJECTLOCALVAR_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( + "${PACKAGEPROJECTLOCALVAR_BINARY_DIR}/${PACKAGEPROJECTLOCALVAR_NAME}ConfigVersion.cmake" + VERSION ${PACKAGEPROJECTLOCALVAR_VERSION} + COMPATIBILITY ${PACKAGEPROJECTLOCALVAR_COMPATIBILITY} ${wbpvf_extra_args} + ) + + # set default runtime install subdirectory (RUNTIME_DESTINATION) + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION) + set(PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION + ${PACKAGEPROJECTLOCALVAR_NAME}${PACKAGEPROJECTLOCALVAR_VERSION_SUFFIX} + ) + endif() + + install( + TARGETS ${PACKAGEPROJECTLOCALVAR_NAME} + EXPORT ${PACKAGEPROJECTLOCALVAR_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Runtime" + NAMELINK_COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}/${PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Runtime" + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}/${PACKAGEPROJECTLOCALVAR_RUNTIME_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Runtime" + PUBLIC_HEADER DESTINATION ${PACKAGEPROJECTLOCALVAR_INCLUDE_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + INCLUDES + DESTINATION "${PACKAGEPROJECTLOCALVAR_INCLUDE_DESTINATION}" + ) + + set("${PACKAGEPROJECTLOCALVAR_NAME}_INSTALL_CMAKEDIR" + "${INSTALL_DIR_FOR_CMAKE_CONFIGS}/cmake/${PACKAGEPROJECTLOCALVAR_NAME}${PACKAGEPROJECTLOCALVAR_VERSION_SUFFIX}" + CACHE PATH "CMake package config location relative to the install prefix" + ) + + mark_as_advanced("${PACKAGEPROJECTLOCALVAR_NAME}_INSTALL_CMAKEDIR") + + configure_file( + ${PACKAGE_PROJECT_ROOT_PATH}/Config.cmake.in + "${PACKAGEPROJECTLOCALVAR_BINARY_DIR}/${PACKAGEPROJECTLOCALVAR_NAME}Config.cmake" @ONLY + ) + + install( + EXPORT ${PACKAGEPROJECTLOCALVAR_NAME}Targets + DESTINATION "${${PACKAGEPROJECTLOCALVAR_NAME}_INSTALL_CMAKEDIR}" + NAMESPACE ${PACKAGEPROJECTLOCALVAR_NAMESPACE} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + ) + + install( + FILES "${PACKAGEPROJECTLOCALVAR_BINARY_DIR}/${PACKAGEPROJECTLOCALVAR_NAME}ConfigVersion.cmake" + "${PACKAGEPROJECTLOCALVAR_BINARY_DIR}/${PACKAGEPROJECTLOCALVAR_NAME}Config.cmake" + DESTINATION "${${PACKAGEPROJECTLOCALVAR_NAME}_INSTALL_CMAKEDIR}" + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + ) + + if(NOT DEFINED PACKAGEPROJECTLOCALVAR_INCLUDE_HEADER_PATTERN) + set(PACKAGEPROJECTLOCALVAR_INCLUDE_HEADER_PATTERN "*") + endif() + + if(PACKAGEPROJECTLOCALVAR_INCLUDE_DESTINATION AND PACKAGEPROJECTLOCALVAR_INCLUDE_DIR) + install( + DIRECTORY ${PACKAGEPROJECTLOCALVAR_INCLUDE_DIR}/ + DESTINATION ${PACKAGEPROJECTLOCALVAR_INCLUDE_DESTINATION} + COMPONENT "${PACKAGEPROJECTLOCALVAR_NAME}_Development" + FILES_MATCHING + PATTERN "${PACKAGEPROJECTLOCALVAR_INCLUDE_HEADER_PATTERN}" + ) + endif() + + set(${PACKAGEPROJECTLOCALVAR_NAME}_VERSION + ${PACKAGEPROJECTLOCALVAR_VERSION} + CACHE INTERNAL "" + ) + + if(PACKAGEPROJECTLOCALVAR_CPACK) + if(CPACK_PACKAGE_NAMESPACE) + set(CPACK_PACKAGE_NAME ${CPACK_PACKAGE_NAMESPACE}-${PACKAGEPROJECTLOCALVAR_NAME}) + else() + set(CPACK_PACKAGE_NAME ${PACKAGEPROJECTLOCALVAR_NAME}) + endif() + if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) + if(DEFINED PACKAGEPROJECTLOCALVAR_DESCRIPTION) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PACKAGEPROJECTLOCALVAR_DESCRIPTION}") + else() + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${${PACKAGEPROJECTLOCALVAR_NAME}_DESCRIPTION}") + endif() + endif() + if(NOT CPACK_PACKAGE_HOMEPAGE_URL) + set(CPACK_PACKAGE_HOMEPAGE_URL "${PACKAGEPROJECTLOCALVAR_HOMEPAGE_URL}") + endif() + set(CPACK_VERBATIM_VARIABLES YES) + set(CPACK_THREADS 0) + set(CPACK_PACKAGE_VERSION_MAJOR ${PACKAGEPROJECTLOCALVAR_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${PACKAGEPROJECTLOCALVAR_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${PACKAGEPROJECTLOCALVAR_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/PackageProject.cmake/PackageProjectFiles/Config.cmake.in b/cmake/PackageProject.cmake/PackageProjectFiles/Config.cmake.in new file mode 100644 index 0000000..a729c0e --- /dev/null +++ b/cmake/PackageProject.cmake/PackageProjectFiles/Config.cmake.in @@ -0,0 +1,10 @@ +include(CMakeFindDependencyMacro) + +string(REGEX MATCHALL "[^;]+" SEPARATE_DEPENDENCIES "@PACKAGEPROJECTLOCALVAR_DEPENDENCIES@") + +foreach(dependency ${SEPARATE_DEPENDENCIES}) + string(REPLACE " " ";" args "${dependency}") + find_dependency(${args}) +endforeach() + +include("${CMAKE_CURRENT_LIST_DIR}/@PACKAGEPROJECTLOCALVAR_NAME@Targets.cmake") diff --git a/cmake/PackageProject.cmake/PackageProjectFiles/version.h.in b/cmake/PackageProject.cmake/PackageProjectFiles/version.h.in new file mode 100644 index 0000000..71867e5 --- /dev/null +++ b/cmake/PackageProject.cmake/PackageProjectFiles/version.h.in @@ -0,0 +1,8 @@ +#pragma once + +#define @UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME@_VERSION "@PACKAGEPROJECTLOCALVAR_VERSION@" + +#define @UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME@_VERSION_MAJOR @PACKAGEPROJECTLOCALVAR_VERSION_MAJOR@ +#define @UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME@_VERSION_MINOR @PACKAGEPROJECTLOCALVAR_VERSION_MINOR@ +#define @UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME@_VERSION_PATCH @PACKAGEPROJECTLOCALVAR_VERSION_PATCH@ +#define @UPPERCASE_PACKAGEPROJECTLOCALVAR_NAME@_VERSION_TWEAK @PACKAGEPROJECTLOCALVAR_VERSION_TWEAK@ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8fcacf4..63fe223 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.14...3.22) option(TEST_INSTALLED_VERSION "Test the version found by find_package" OFF) +option(TEST_INSTALLED_VERSION_PACKAGEPROJECT + "Test the version of PackageProject.cmake found via `include(PackageProject)`" OFF +) + project( PackageProjectTest VERSION 1.0 diff --git a/test/dependency/CMakeLists.txt b/test/dependency/CMakeLists.txt index ad0821d..1b9fa24 100644 --- a/test/dependency/CMakeLists.txt +++ b/test/dependency/CMakeLists.txt @@ -14,7 +14,11 @@ target_include_directories( $ ) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +if(${TEST_INSTALLED_VERSION_PACKAGEPROJECT}) + find_package(PackageProject.cmake 13.0.3) +else() + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +endif() packageProject( NAME ${PROJECT_NAME} diff --git a/test/header_only/CMakeLists.txt b/test/header_only/CMakeLists.txt index 1ea9aac..8a307a1 100644 --- a/test/header_only/CMakeLists.txt +++ b/test/header_only/CMakeLists.txt @@ -14,7 +14,11 @@ target_include_directories( $ ) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +if(${TEST_INSTALLED_VERSION_PACKAGEPROJECT}) + find_package(PackageProject.cmake) +else() + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +endif() packageProject( NAME ${PROJECT_NAME} diff --git a/test/namespaced_dependency/CMakeLists.txt b/test/namespaced_dependency/CMakeLists.txt index 77d3c29..fa59d9d 100644 --- a/test/namespaced_dependency/CMakeLists.txt +++ b/test/namespaced_dependency/CMakeLists.txt @@ -17,7 +17,11 @@ target_include_directories( $ ) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +if(${TEST_INSTALLED_VERSION_PACKAGEPROJECT}) + find_package(PackageProject.cmake) +else() + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +endif() packageProject( NAME ${PROJECT_NAME} diff --git a/test/runtime_destination_dependency/CMakeLists.txt b/test/runtime_destination_dependency/CMakeLists.txt index 8e67fc1..543d178 100644 --- a/test/runtime_destination_dependency/CMakeLists.txt +++ b/test/runtime_destination_dependency/CMakeLists.txt @@ -15,7 +15,11 @@ target_include_directories( $ ) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +if(${TEST_INSTALLED_VERSION_PACKAGEPROJECT}) + find_package(PackageProject.cmake) +else() + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +endif() packageProject( NAME ${PROJECT_NAME} diff --git a/test/transitive_dependency/CMakeLists.txt b/test/transitive_dependency/CMakeLists.txt index fd09118..d84adca 100644 --- a/test/transitive_dependency/CMakeLists.txt +++ b/test/transitive_dependency/CMakeLists.txt @@ -19,8 +19,8 @@ CPMAddPackage( CPMAddPackage( NAME cxxopts GITHUB_REPOSITORY jarro2783/cxxopts - VERSION 2.2.0 - OPTIONS "CXXOPTS_BUILD_EXAMPLES Off" "CXXOPTS_BUILD_TESTS Off" + VERSION 3.0.0 + OPTIONS "CXXOPTS_BUILD_EXAMPLES Off" "CXXOPTS_BUILD_TESTS Off" "CXXOPTS_ENABLE_INSTALL 1" ) # Set default visibility to hidden for all targets @@ -29,14 +29,18 @@ set(CMAKE_VISIBILITY_INLINES_HIDDEN YES) add_library(${PROJECT_NAME} SHARED source/transitive_dependency.cpp) target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17) -target_link_libraries(${PROJECT_NAME} PUBLIC fmt::fmt-header-only cxxopts) +target_link_libraries(${PROJECT_NAME} PUBLIC fmt::fmt-header-only cxxopts::cxxopts) target_include_directories( transitive_dependency PUBLIC $ $ ) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +if(${TEST_INSTALLED_VERSION_PACKAGEPROJECT}) + find_package(PackageProject.cmake) +else() + add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../.. PackageProject) +endif() packageProject( NAME ${PROJECT_NAME} diff --git a/test/transitive_dependency/cmake/CPM.cmake b/test/transitive_dependency/cmake/CPM.cmake index bc06845..6aaeca7 100644 --- a/test/transitive_dependency/cmake/CPM.cmake +++ b/test/transitive_dependency/cmake/CPM.cmake @@ -1,13 +1,17 @@ -set(CPM_DOWNLOAD_VERSION 0.35.0) +if(NOT DEFINED CPM_DOWNLOAD_LOCATION) + + set(CPM_DOWNLOAD_VERSION 0.35.0) + + if(CPM_SOURCE_CACHE) + # Expand relative path. This is important if the provided path contains a tilde (~) + get_filename_component(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE} ABSOLUTE) + set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") + elseif(DEFINED ENV{CPM_SOURCE_CACHE}) + set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") + else() + set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") + endif() -if(CPM_SOURCE_CACHE) - # Expand relative path. This is important if the provided path contains a tilde (~) - get_filename_component(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE} ABSOLUTE) - set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") -elseif(DEFINED ENV{CPM_SOURCE_CACHE}) - set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") -else() - set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") endif() if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) diff --git a/version.h.in b/version.h.in deleted file mode 100644 index e74e3eb..0000000 --- a/version.h.in +++ /dev/null @@ -1,8 +0,0 @@ -#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@