1# Copyright 2018, 2019 Peter Dimov 2# Distributed under the Boost Software License, Version 1.0. 3# See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt 4 5# Clear global variables on each `include(BoostTest)` 6 7set(BOOST_TEST_LINK_LIBRARIES "") 8set(BOOST_TEST_COMPILE_DEFINITIONS "") 9set(BOOST_TEST_COMPILE_OPTIONS "") 10set(BOOST_TEST_COMPILE_FEATURES "") 11 12# Include guard 13 14if(NOT CMAKE_VERSION VERSION_LESS 3.10) 15 include_guard() 16endif() 17 18include(BoostMessage) 19 20# Private helper functions 21 22function(__boost_test_list_replace list what with) 23 24 set(result "") 25 26 foreach(x IN LISTS ${list}) 27 28 if(x STREQUAL what) 29 set(x ${with}) 30 endif() 31 32 list(APPEND result ${x}) 33 34 endforeach() 35 36 set(${list} ${result} PARENT_SCOPE) 37 38endfunction() 39 40# boost_test( [TYPE type] [PREFIX prefix] [NAME name] [IGNORE_TEST_GLOBALS] 41# SOURCES sources... 42# ARGUMENTS args... 43# LINK_LIBRARIES libs... 44# COMPILE_DEFINITIONS defs... 45# COMPILE_OPTIONS opts... 46# COMPILE_FEATURES features... 47# ) 48 49function(boost_test) 50 51 cmake_parse_arguments(_ "IGNORE_TEST_GLOBALS" "TYPE;PREFIX;NAME" "SOURCES;ARGUMENTS;LIBRARIES;LINK_LIBRARIES;COMPILE_DEFINITIONS;COMPILE_OPTIONS;COMPILE_FEATURES" ${ARGN}) 52 53 if(NOT __TYPE) 54 set(__TYPE run) 55 endif() 56 57 if(NOT __PREFIX) 58 set(__PREFIX ${PROJECT_NAME}) 59 endif() 60 61 if(NOT __NAME) 62 list(GET __SOURCES 0 __NAME) 63 string(MAKE_C_IDENTIFIER ${__NAME} __NAME) 64 endif() 65 66 set(__NAME ${__PREFIX}-${__NAME}) 67 68 if(__UNPARSED_ARGUMENTS) 69 message(AUTHOR_WARNING "Extra arguments for test '${__NAME}' ignored: ${__UNPARSED_ARGUMENTS}") 70 endif() 71 72 if(__LIBRARIES) 73 boost_message(VERBOSE "Test '${__NAME}' uses deprecated parameter LIBRARIES; use LINK_LIBRARIES") 74 endif() 75 76 if(DEFINED BUILD_TESTING AND NOT BUILD_TESTING) 77 return() 78 endif() 79 80 if(__IGNORE_TEST_GLOBALS) 81 82 set(BOOST_TEST_LINK_LIBRARIES "") 83 set(BOOST_TEST_COMPILE_DEFINITIONS "") 84 set(BOOST_TEST_COMPILE_OPTIONS "") 85 set(BOOST_TEST_COMPILE_FEATURES "") 86 87 endif() 88 89 list(APPEND BOOST_TEST_LINK_LIBRARIES ${__LIBRARIES} ${__LINK_LIBRARIES}) 90 list(APPEND BOOST_TEST_COMPILE_DEFINITIONS ${__COMPILE_DEFINITIONS}) 91 list(APPEND BOOST_TEST_COMPILE_OPTIONS ${__COMPILE_OPTIONS}) 92 list(APPEND BOOST_TEST_COMPILE_FEATURES ${__COMPILE_FEATURES}) 93 94 if(MSVC) 95 96 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-fexceptions" "/GX") 97 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-fno-exceptions" "/GX-") 98 99 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-frtti" "/GR") 100 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-fno-rtti" "/GR-") 101 102 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-w" "/W0") 103 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-Wall" "/W4") 104 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-Wextra" "") 105 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-pedantic" "") 106 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-Wpedantic" "") 107 108 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-Werror" "/WX") 109 __boost_test_list_replace(BOOST_TEST_COMPILE_OPTIONS "-Wno-error" "/WX-") 110 111 endif() 112 113 foreach(feature IN LISTS BOOST_TEST_COMPILE_FEATURES) 114 if(NOT feature IN_LIST CMAKE_CXX_COMPILE_FEATURES) 115 116 boost_message(VERBOSE "Test '${__NAME}' skipped, '${feature}' is not supported") 117 return() 118 119 endif() 120 endforeach() 121 122 foreach(library IN LISTS BOOST_TEST_LINK_LIBRARIES) 123 124 if(TARGET ${library}) 125 get_target_property(features ${library} INTERFACE_COMPILE_FEATURES) 126 127 if(features) # need to check because features-NOTFOUND is a valid list 128 foreach(feature IN LISTS features) 129 if(NOT feature IN_LIST CMAKE_CXX_COMPILE_FEATURES) 130 131 boost_message(VERBOSE "Test '${__NAME}' skipped, '${feature}' required by '${library}' is not supported") 132 return() 133 134 endif() 135 endforeach() 136 endif() 137 endif() 138 endforeach() 139 140 if(__TYPE STREQUAL "compile" OR __TYPE STREQUAL "compile-fail") 141 142 add_library(${__NAME} STATIC EXCLUDE_FROM_ALL ${__SOURCES}) 143 target_link_libraries(${__NAME} ${BOOST_TEST_LINK_LIBRARIES}) 144 target_compile_definitions(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_DEFINITIONS}) 145 target_compile_options(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_OPTIONS}) 146 target_compile_features(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_FEATURES}) 147 148 add_test(NAME compile-${__NAME} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${__NAME} --config $<CONFIG>) 149 150 if(__TYPE STREQUAL "compile-fail") 151 set_tests_properties(compile-${__NAME} PROPERTIES WILL_FAIL TRUE) 152 endif() 153 154 elseif(__TYPE STREQUAL "link") 155 156 add_executable(${__NAME} EXCLUDE_FROM_ALL ${__SOURCES}) 157 target_link_libraries(${__NAME} ${BOOST_TEST_LINK_LIBRARIES}) 158 target_compile_definitions(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_DEFINITIONS}) 159 target_compile_options(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_OPTIONS}) 160 target_compile_features(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_FEATURES}) 161 162 add_test(NAME link-${__NAME} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${__NAME} --config $<CONFIG>) 163 164 elseif(__TYPE STREQUAL "link-fail") 165 166 add_library(compile-${__NAME} OBJECT EXCLUDE_FROM_ALL ${__SOURCES}) 167 target_link_libraries(compile-${__NAME} ${BOOST_TEST_LINK_LIBRARIES}) 168 target_compile_definitions(compile-${__NAME} PRIVATE ${BOOST_TEST_COMPILE_DEFINITIONS}) 169 target_compile_options(compile-${__NAME} PRIVATE ${BOOST_TEST_COMPILE_OPTIONS}) 170 target_compile_features(compile-${__NAME} PRIVATE ${BOOST_TEST_COMPILE_FEATURES}) 171 172 add_test(NAME compile-${__NAME} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target compile-${__NAME} --config $<CONFIG>) 173 174 add_executable(${__NAME} EXCLUDE_FROM_ALL $<TARGET_OBJECTS:compile-${__NAME}>) 175 target_link_libraries(${__NAME} ${BOOST_TEST_LINK_LIBRARIES}) 176 target_compile_definitions(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_DEFINITIONS}) 177 target_compile_options(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_OPTIONS}) 178 target_compile_features(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_FEATURES}) 179 180 add_test(NAME link-${__NAME} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${__NAME} --config $<CONFIG>) 181 set_tests_properties(link-${__NAME} PROPERTIES WILL_FAIL TRUE) 182 183 elseif(__TYPE STREQUAL "run" OR __TYPE STREQUAL "run-fail") 184 185 add_executable(${__NAME} EXCLUDE_FROM_ALL ${__SOURCES}) 186 target_link_libraries(${__NAME} ${BOOST_TEST_LINK_LIBRARIES}) 187 target_compile_definitions(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_DEFINITIONS}) 188 target_compile_options(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_OPTIONS}) 189 target_compile_features(${__NAME} PRIVATE ${BOOST_TEST_COMPILE_FEATURES}) 190 191 add_test(NAME compile-${__NAME} COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target ${__NAME} --config $<CONFIG>) 192 193 add_test(NAME run-${__NAME} COMMAND ${__NAME} ${__ARGUMENTS}) 194 set_tests_properties(run-${__NAME} PROPERTIES DEPENDS compile-${__NAME}) 195 196 if(__TYPE STREQUAL "run-fail") 197 set_tests_properties(run-${__NAME} PROPERTIES WILL_FAIL TRUE) 198 endif() 199 200 else() 201 202 message(AUTHOR_WARNING "Unknown test type '${__TYPE}' for test '${__NAME}'") 203 204 endif() 205 206endfunction(boost_test) 207