Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
/.cache
/compile_commands.json
/install_dir
/cmake/PackageProject.cmake/PackageProject.cmakeConfig.cmake
/cmake/PackageProject.cmake/PackageProject.cmakeConfigVersion.cmake
254 changes: 42 additions & 212 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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} "$<BUILD_INTERFACE:${PROJECT_VERSION_INCLUDE_DIR}>"
)
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)
10 changes: 0 additions & 10 deletions Config.cmake.in

This file was deleted.

Loading
Loading