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)
5 cmake_minimum_required(VERSION 3.8)
6 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
8 ##############################################################################
10 ##############################################################################
11 option(BOOST_HANA_ENABLE_CONCEPT_CHECKS "Enable concept checking in the interface methods." ON)
12 option(BOOST_HANA_ENABLE_DEBUG_MODE "Enable Hana's debug mode." OFF)
13 option(BOOST_HANA_ENABLE_CPP17 "Build with C++17 instead of usual required C++ standard. Useful for testing." OFF)
15 option(BOOST_HANA_ENABLE_STRING_UDL
16 "Enable the GNU extension allowing the special string literal operator\
17 template, which enables the _s suffix for creating compile-time strings." ON)
19 option(BOOST_HANA_ENABLE_EXCEPTIONS
20 "Build with exceptions enabled. Note that Hana does not make use of exceptions,\
21 but this switch can be disabled when building the tests to assess that it is\
25 ##############################################################################
28 # We parse the canonical version number located in <boost/hana/version.hpp>.
29 # This is done to allow the library to be used without requiring a proper
30 # installation during which the version would be written to this header.
31 ##############################################################################
32 foreach(level MAJOR MINOR PATCH)
33 file(STRINGS include/boost/hana/version.hpp
35 REGEX "#define BOOST_HANA_${level}_VERSION")
36 string(REGEX MATCH "([0-9]+)" _version_${level} "${_define_${level}}")
39 set(Boost.Hana_VERSION_STRING "${_version_MAJOR}.${_version_MINOR}.${_version_PATCH}")
40 project(Boost.Hana VERSION ${Boost.Hana_VERSION_STRING} LANGUAGES CXX)
42 # Perform checks to make sure we support the current compiler
43 include(CheckCxxCompilerSupport)
46 ##############################################################################
47 # Setup the 'hana' header-only library target, along with its install target
49 ##############################################################################
50 include(CheckCXXCompilerFlag)
51 add_library(hana INTERFACE)
52 target_include_directories(hana INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
53 $<INSTALL_INTERFACE:include>)
54 # With Clang on Windows, the -std=c++14 flag is incorrectly set and the compiler
55 # complains about the unknown option. TODO: Remove this workaround once the
56 # underlying bug is fixed in CMake: https://gitlab.kitware.com/cmake/cmake/issues/17015
57 if (NOT (MSVC AND ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
58 if (BOOST_HANA_ENABLE_CPP17)
59 target_compile_features(hana INTERFACE cxx_std_17)
61 target_compile_features(hana INTERFACE cxx_std_14)
65 # Export the `hana` library into a HanaConfig.cmake file
66 install(TARGETS hana EXPORT HanaConfig)
67 install(EXPORT HanaConfig DESTINATION lib/cmake/hana)
68 install(DIRECTORY include/boost DESTINATION include FILES_MATCHING PATTERN "*.hpp")
70 # Also install an optional pkg-config file
71 configure_file(cmake/hana.pc.in hana.pc @ONLY)
72 install(FILES "${CMAKE_CURRENT_BINARY_DIR}/hana.pc" DESTINATION lib/pkgconfig)
75 ##############################################################################
76 # Function to setup common compiler flags on tests and examples
77 ##############################################################################
78 function(boost_hana_set_test_properties target)
79 target_link_libraries(${target} PRIVATE hana)
80 set_target_properties(${target} PROPERTIES CXX_EXTENSIONS NO)
82 macro(setflag testname flag)
83 check_cxx_compiler_flag(${flag} ${testname})
85 target_compile_options(${target} PRIVATE ${flag})
89 setflag(BOOST_HANA_HAS_FDIAGNOSTICS_COLOR -fdiagnostics-color)
90 setflag(BOOST_HANA_HAS_FTEMPLATE_BACKTRACE_LIMIT -ftemplate-backtrace-limit=0)
91 setflag(BOOST_HANA_HAS_PEDANTIC -pedantic)
92 setflag(BOOST_HANA_HAS_WALL -Wall)
93 setflag(BOOST_HANA_HAS_WERROR -Werror)
94 setflag(BOOST_HANA_HAS_WEXTRA -Wextra)
95 setflag(BOOST_HANA_HAS_WNO_UNUSED_LOCAL_TYPEDEFS -Wno-unused-local-typedefs)
96 setflag(BOOST_HANA_HAS_WWRITE_STRINGS -Wwrite-strings)
98 if (NOT BOOST_HANA_ENABLE_EXCEPTIONS)
99 setflag(BOOST_HANA_HAS_FNO_EXCEPTIONS -fno-exceptions)
102 if (NOT BOOST_HANA_ENABLE_CONCEPT_CHECKS)
103 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS)
106 if (BOOST_HANA_ENABLE_DEBUG_MODE)
107 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_DEBUG_MODE)
110 if (BOOST_HANA_ENABLE_STRING_UDL)
111 target_compile_definitions(${target} PRIVATE -DBOOST_HANA_CONFIG_ENABLE_STRING_UDL)
112 # GCC pretends to have the flag, but produces a "unrecognized command line option"
113 # warning when we use it.
114 if (NOT ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU")
115 setflag(BOOST_HANA_HAS_WNO_GNU_STRING_UDL -Wno-gnu-string-literal-operator-template)
121 ##############################################################################
122 # Look for the rest of Boost, which is an optional dependency of some tests.
123 ##############################################################################
124 find_package(Boost 1.59)
126 message(WARNING "The rest of Boost was not found; some tests and examples will be disabled.")
130 ##############################################################################
131 # Setup custom functions to ease the creation of targets
132 ##############################################################################
133 # boost_hana_target_name_for(<output variable> <source file> [ext])
135 # Return the target name associated to a source file. If the path of the
136 # source file relative from the root of Hana is `path/to/source/file.ext`,
137 # the target name associated to it will be `path.to.source.file`.
139 # The extension of the file should be specified as a last argument. If no
140 # extension is specified, the `.cpp` extension is assumed.
141 function(boost_hana_target_name_for out file)
143 set(_extension ".cpp")
145 set(_extension "${ARGV2}")
148 file(RELATIVE_PATH _relative "${Boost.Hana_SOURCE_DIR}" "${file}")
149 string(REPLACE "${_extension}" "" _name "${_relative}")
150 string(REGEX REPLACE "/" "." _name "${_name}")
151 set(${out} "${_name}" PARENT_SCOPE)
155 ##############################################################################
156 # Setup the `check` target to build and then run all the tests and examples.
157 ##############################################################################
158 add_custom_target(check
159 COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
160 WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
161 COMMENT "Build and then run all the tests and examples.")
164 ##############################################################################
165 # Setup subdirectories and testing
166 ##############################################################################
168 find_program(MEMORYCHECK_COMMAND valgrind)
169 if (MEMORYCHECK_COMMAND)
170 message(STATUS "Found Valgrind: ${MEMORYCHECK_COMMAND}")
171 set(MEMORYCHECK_COMMAND_OPTIONS "--leak-check=full --error-exitcode=1")
173 message("Valgrind not found")
177 add_subdirectory(benchmark)
178 add_subdirectory(doc)
179 add_subdirectory(example)
180 add_subdirectory(test)