1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
|
cmake_minimum_required(VERSION 3.8)
#
# Here we check whether frozen is being configured in isolation or as a component
# of a larger proeject. To do so, we query whether the `PROJECT_NAME` CMake
# variable has been defined. In the case it has, we can conclude frozen is a
# subproject.
#
# This convention has been borrowed from the Catch C++ unit testing library.
#
if(DEFINED PROJECT_NAME)
set(subproject ON)
set(INSTALL_SUBPROJECTS ON CACHE BOOL "Install subproject dependencies")
else()
set(subproject OFF)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()
project(frozen VERSION 1.1.0 LANGUAGES CXX)
include(CMakeDependentOption)
include(CMakePackageConfigHelpers) # provides `write_basic_package_version_file`
include(CTest)
include(GNUInstallDirs)
include(cmake/detect_cxx_version.cmake)
#
# The `frozen.testing`, `frozen.benchmark`, and `frozen.coverage` options
# only appear as cmake-gui and ccmake options iff frozen is the highest
# level project. In the case that frozen is a subproject, these options are
# hidden from the user interface and set to `OFF`
#
CMAKE_DEPENDENT_OPTION(frozen.tests
"Build the frozen tests and integrate with ctest"
${BUILD_TESTING} "NOT subproject" OFF)
CMAKE_DEPENDENT_OPTION(frozen.benchmark
"Build the frozen benchmark"
OFF "NOT subproject" OFF)
CMAKE_DEPENDENT_OPTION(frozen.coverage
"Enable test coverage collection of frozen tests"
OFF "NOT subproject" OFF)
#
# When the end user is consuming frozen as a nested subproject, an option
# is provided such that the user may exlude frozen from the set of installed
# cmake projects. This accomodates end users building executables or
# compiled libraries which privately link to frozen, but wish to only ship their
# artifacts in an installation
#
CMAKE_DEPENDENT_OPTION(frozen.installation
"Include frozen in the install set"
"${INSTALL_SUBPROJECTS}" "subproject" ON)
mark_as_advanced(frozen.installation)
#
# frozen has no compiled components. As such, we declare it as an `INTERFACE`
# library, which denotes a collection of target properties to be applied
# transitively to linking targets. In our case, this amounts to an include
# directory and project header files.
#
add_library(frozen INTERFACE)
add_library(frozen::frozen ALIAS frozen)
add_library(frozen-headers INTERFACE)
add_library(frozen::frozen-headers ALIAS frozen-headers)
target_link_libraries(frozen-headers INTERFACE frozen::frozen)
#
# frozen requires C++ 14 support, at a minimum. Setting the `cxx_std_14` compile
# features ensures that the corresponding C++ standard flag is populated in
# targets linking to frozen
#
target_compile_features(frozen INTERFACE cxx_std_14)
#
# The include directory for frozen can be expected to vary between build
# and installaion. Here we use a CMake generator expression to dispatch
# on how the configuration under which this library is being consumed.
#
string(CONCAT prefix
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_include_directories(frozen INTERFACE ${prefix})
add_subdirectory(include/frozen)
if(frozen.tests)
add_subdirectory(tests)
add_subdirectory(examples)
endif()
if(frozen.benchmark)
add_subdirectory(benchmarks)
endif()
if(frozen.installation)
#
# As a header-only library, there are no target components to be installed
# directly (the PUBLIC_HEADER property is not white listed for INTERFACE
# targets for some reason).
#
# However, it is worthwhile export our target description in order to later
# generate a CMake configuration file for consumption by CMake's `find_package`
# intrinsic
#
install(TARGETS frozen frozen-headers EXPORT frozenConfig)
#
# Non-testing header files (preserving relative paths) are installed to the
# `include` subdirectory of the `$INSTALL_DIR/${CMAKE_INSTALL_PREFIX}`
# directory. Source file permissions preserved.
#
install(DIRECTORY include/
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
USE_SOURCE_PERMISSIONS
FILES_MATCHING PATTERN "*.h")
#
# As a header-only library, there are no target components to be installed
# directly (the PUBLIC_HEADER property is not white listed for INTERFACE
# targets for some reason).
#
# However, it is worthwhile export our target description in order to later
# generate a CMake configuration file for consumption by CMake's `find_package`
# intrinsic
#
if(${CMAKE_VERSION} VERSION_GREATER "3.14")
set(OPTIONAL_ARCH_INDEPENDENT "ARCH_INDEPENDENT")
endif()
write_basic_package_version_file("frozenConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
${OPTIONAL_ARCH_INDEPENDENT})
install(FILES "${PROJECT_BINARY_DIR}/frozenConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/frozen")
install(EXPORT frozenConfig
FILE frozenConfig.cmake
NAMESPACE frozen::
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/frozen")
#
# Rudimentary CPack support.
#
# CPack provides a mechanism to generate installation packaging for a project,
# e.g., self-extracting shell scripts, compressed tarballs, Debian Package files,
# RPM Package Manager files, Windows NSIS installation wizards,
# Apple Disk Images (.dmg), etc.
#
# A packaged installation can be generated by calling
#
# ```sh
# cpack -G <packaging type> --config CPackConfig.cmake
# ```
#
# See `cpack --help` or the CPack documentation for more information.
#
if(NOT subproject)
set(CPACK_PACKAGE_VENDOR "Quarkslab")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "a C++14 header-only, constexpr alternative to gperf")
set(CMAKE_PROJECT_HOMEPAGE_URL "https://blog.quarkslab.com/frozen-an-header-only-constexpr-alternative-to-gperf-for-c14-users.html")
include(CPack)
endif()
endif()
|