• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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