1# Copyright Louis Dionne 2013-2017 2# Distributed under the Boost Software License, Version 1.0. 3# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 4 5cmake_minimum_required(VERSION 3.9) 6list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 7 8############################################################################## 9# Setup CMake options 10############################################################################## 11option(BOOST_HANA_ENABLE_CONCEPT_CHECKS "Enable concept checking in the interface methods." ON) 12option(BOOST_HANA_ENABLE_DEBUG_MODE "Enable Hana's debug mode." OFF) 13 14option(BOOST_HANA_ENABLE_STRING_UDL 15"Enable the GNU extension allowing the special string literal operator\ 16 template, which enables the _s suffix for creating compile-time strings." ON) 17 18option(BOOST_HANA_ENABLE_EXCEPTIONS 19"Build with exceptions enabled. Note that Hana does not make use of exceptions,\ 20 but this switch can be disabled when building the tests to assess that it is\ 21 really the case." ON) 22 23 24############################################################################## 25# Setup project 26# 27# We parse the canonical version number located in <boost/hana/version.hpp>. 28# This is done to allow the library to be used without requiring a proper 29# installation during which the version would be written to this header. 30############################################################################## 31foreach(level MAJOR MINOR PATCH) 32 file(STRINGS include/boost/hana/version.hpp 33 _define_${level} 34 REGEX "#define BOOST_HANA_${level}_VERSION") 35 string(REGEX MATCH "([0-9]+)" _version_${level} "${_define_${level}}") 36endforeach() 37 38set(Boost.Hana_VERSION_STRING "${_version_MAJOR}.${_version_MINOR}.${_version_PATCH}") 39project(Boost.Hana VERSION ${Boost.Hana_VERSION_STRING} LANGUAGES CXX) 40 41# Perform checks to make sure we support the current compiler 42include(CheckCxxCompilerSupport) 43 44 45############################################################################## 46# Setup the 'hana' header-only library target, along with its install target 47# and exports. 48############################################################################## 49include(CheckCXXCompilerFlag) 50add_library(hana INTERFACE) 51target_include_directories(hana INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>") 52target_compile_features(hana INTERFACE cxx_std_14) 53 54# Export the `hana` library into a HanaConfig.cmake file 55install(TARGETS hana 56 EXPORT HanaConfig 57 INCLUDES DESTINATION include) 58install(EXPORT HanaConfig 59 DESTINATION lib/cmake/hana) 60install(DIRECTORY include/boost 61 DESTINATION include 62 FILES_MATCHING PATTERN "*.hpp") 63 64# Also install an optional pkg-config file 65configure_file(cmake/hana.pc.in hana.pc @ONLY) 66install(FILES "${CMAKE_CURRENT_BINARY_DIR}/hana.pc" DESTINATION lib/pkgconfig) 67 68 69############################################################################## 70# Function to setup common compiler flags on tests and examples 71############################################################################## 72function(boost_hana_set_test_properties target) 73 target_link_libraries(${target} PRIVATE hana) 74 set_target_properties(${target} PROPERTIES CXX_EXTENSIONS NO) 75 76 macro(setflag testname flag) 77 check_cxx_compiler_flag(${flag} ${testname}) 78 if (${testname}) 79 target_compile_options(${target} PRIVATE ${flag}) 80 endif() 81 endmacro() 82 83 if (NOT MSVC) 84 setflag(BOOST_HANA_HAS_FDIAGNOSTICS_COLOR -fdiagnostics-color) 85 setflag(BOOST_HANA_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0) 86 setflag(BOOST_HANA_HAS_PEDANTIC -pedantic) 87 setflag(BOOST_HANA_HAS_WALL -Wall) 88 setflag(BOOST_HANA_HAS_WERROR -Werror) 89 setflag(BOOST_HANA_HAS_WEXTRA -Wextra) 90 setflag(BOOST_HANA_HAS_WNO_SELF_ASSIGN_OVERLOADED -Wno-self-assign-overloaded) 91 setflag(BOOST_HANA_HAS_WNO_UNUSED_LOCAL_TYPEDEFS -Wno-unused-local-typedefs) 92 setflag(BOOST_HANA_HAS_WWRITE_STRINGS -Wwrite-strings) 93 else() 94 setflag(BOOST_HANA_HAS_MSVC_EHSC -EHsc) 95 setflag(BOOST_HANA_HAS_MSVC_BIGOBJ -bigobj) 96 setflag(BOOST_HANA_HAS_MSVC_TERNARY -Zc:ternary) 97 endif() 98 99 if (NOT BOOST_HANA_ENABLE_EXCEPTIONS) 100 setflag(BOOST_HANA_HAS_FNO_EXCEPTIONS -fno-exceptions) 101 endif() 102 103 if (NOT BOOST_HANA_ENABLE_CONCEPT_CHECKS) 104 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS) 105 endif() 106 107 if (BOOST_HANA_ENABLE_DEBUG_MODE) 108 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_DEBUG_MODE) 109 endif() 110 111 if (BOOST_HANA_ENABLE_STRING_UDL) 112 if (NOT MSVC) 113 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_STRING_UDL) 114 # GCC pretends to have the flag, but produces a "unrecognized command line option" 115 # warning when we use it. 116 if (NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") 117 setflag(BOOST_HANA_HAS_WNO_GNU_STRING_UDL -Wno-gnu-string-literal-operator-template) 118 endif() 119 endif() 120 endif() 121endfunction() 122 123 124############################################################################## 125# Look for the rest of Boost, which is an optional dependency of some tests. 126############################################################################## 127find_package(Boost 1.64) 128if (NOT Boost_FOUND) 129 message(WARNING "The rest of Boost was not found; some tests and examples will be disabled.") 130endif() 131 132 133############################################################################## 134# Setup custom functions to ease the creation of targets 135############################################################################## 136# boost_hana_target_name_for(<output variable> <source file> [ext]) 137# 138# Return the target name associated to a source file. If the path of the 139# source file relative from the root of Hana is `path/to/source/file.ext`, 140# the target name associated to it will be `path.to.source.file`. 141# 142# The extension of the file should be specified as a last argument. If no 143# extension is specified, the `.cpp` extension is assumed. 144function(boost_hana_target_name_for out file) 145 if (NOT ARGV2) 146 set(_extension ".cpp") 147 else() 148 set(_extension "${ARGV2}") 149 endif() 150 151 file(RELATIVE_PATH _relative "${Boost.Hana_SOURCE_DIR}" "${file}") 152 string(REPLACE "${_extension}" "" _name "${_relative}") 153 string(REGEX REPLACE "/" "." _name "${_name}") 154 set(${out} "${_name}" PARENT_SCOPE) 155endfunction() 156 157 158############################################################################## 159# Setup the `check` target to build and then run all the tests and examples. 160############################################################################## 161add_custom_target(hana_check 162 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure 163 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" 164 COMMENT "Build and then run all the tests and examples." 165 USES_TERMINAL) 166if (NOT TARGET check) 167 add_custom_target(check DEPENDS hana_check) 168else() 169 add_dependencies(check hana_check) 170endif() 171 172 173############################################################################## 174# Setup subdirectories and testing 175############################################################################## 176enable_testing() 177find_program(MEMORYCHECK_COMMAND valgrind) 178if (MEMORYCHECK_COMMAND) 179 message(STATUS "Found Valgrind: ${MEMORYCHECK_COMMAND}") 180 set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1") 181else() 182 message("Valgrind not found") 183endif() 184include(CTest) 185 186add_subdirectory(benchmark) 187add_subdirectory(doc) 188add_subdirectory(example) 189add_subdirectory(test) 190