1add_subdirectory(gtest) 2 3include(CheckSymbolExists) 4 5set(TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc) 6add_library(test-main STATIC ${TEST_MAIN_SRC}) 7target_include_directories(test-main PUBLIC 8 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>) 9target_link_libraries(test-main gtest fmt) 10 11# Adds a test. 12# Usage: add_fmt_test(name srcs...) 13function(add_fmt_test name) 14 cmake_parse_arguments(ADD_FMT_TEST "HEADER_ONLY;MODULE" "" "" ${ARGN}) 15 16 set(sources ${name}.cc ${ADD_FMT_TEST_UNPARSED_ARGUMENTS}) 17 if (ADD_FMT_TEST_HEADER_ONLY) 18 set(sources ${sources} ${TEST_MAIN_SRC} ../src/os.cc) 19 set(libs gtest fmt-header-only) 20 if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 21 set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wno-weak-vtables) 22 endif () 23 elseif (ADD_FMT_TEST_MODULE) 24 set(libs test-main test-module) 25 set_source_files_properties(${name}.cc PROPERTIES OBJECT_DEPENDS test-module) 26 else () 27 set(libs test-main fmt) 28 endif () 29 add_executable(${name} ${sources}) 30 target_link_libraries(${name} ${libs}) 31 32 if (ADD_FMT_TEST_HEADER_ONLY AND NOT FMT_UNICODE) 33 target_compile_definitions(${name} PUBLIC FMT_UNICODE=0) 34 endif () 35 36 # Define if certain C++ features can be used. 37 if (FMT_PEDANTIC) 38 target_compile_options(${name} PRIVATE ${PEDANTIC_COMPILE_FLAGS}) 39 endif () 40 if (FMT_WERROR) 41 target_compile_options(${name} PRIVATE ${WERROR_FLAG}) 42 endif () 43 add_test(NAME ${name} COMMAND ${name}) 44endfunction() 45 46if (FMT_MODULE) 47 return () 48endif () 49 50add_fmt_test(args-test) 51add_fmt_test(base-test) 52add_fmt_test(assert-test) 53add_fmt_test(chrono-test) 54add_fmt_test(color-test) 55add_fmt_test(gtest-extra-test) 56add_fmt_test(format-test mock-allocator.h) 57if (MSVC) 58 target_compile_options(format-test PRIVATE /bigobj) 59endif () 60if (NOT (MSVC AND BUILD_SHARED_LIBS)) 61 add_fmt_test(format-impl-test HEADER_ONLY header-only-test.cc) 62endif () 63add_fmt_test(ostream-test) 64add_fmt_test(compile-test) 65add_fmt_test(compile-fp-test) 66if (MSVC) 67 # Without this option, MSVC returns 199711L for the __cplusplus macro. 68 target_compile_options(compile-fp-test PRIVATE /Zc:__cplusplus) 69endif() 70add_fmt_test(printf-test) 71add_fmt_test(ranges-test ranges-odr-test.cc) 72add_fmt_test(no-builtin-types-test HEADER_ONLY) 73 74add_fmt_test(scan-test HEADER_ONLY) 75check_symbol_exists(strptime "time.h" HAVE_STRPTIME) 76if (HAVE_STRPTIME) 77 target_compile_definitions(scan-test PRIVATE FMT_HAVE_STRPTIME) 78endif () 79 80add_fmt_test(std-test) 81try_compile(compile_result_unused 82 ${CMAKE_CURRENT_BINARY_DIR} 83 SOURCES ${CMAKE_CURRENT_LIST_DIR}/detect-stdfs.cc 84 OUTPUT_VARIABLE RAWOUTPUT) 85string(REGEX REPLACE ".*libfound \"([^\"]*)\".*" "\\1" STDLIBFS "${RAWOUTPUT}") 86if (STDLIBFS) 87 target_link_libraries(std-test ${STDLIBFS}) 88endif () 89add_fmt_test(unicode-test HEADER_ONLY) 90if (MSVC) 91 target_compile_options(unicode-test PRIVATE /utf-8) 92endif () 93add_fmt_test(xchar-test) 94add_fmt_test(enforce-checks-test) 95target_compile_definitions(enforce-checks-test PRIVATE 96 -DFMT_ENFORCE_COMPILE_STRING) 97 98add_executable(perf-sanity perf-sanity.cc) 99target_link_libraries(perf-sanity fmt::fmt) 100 101if (FMT_MODULE) 102 # The tests need {fmt} to be compiled as traditional library 103 # because of visibility of implementation details. 104 # If module support is present the module tests require a 105 # test-only module to be built from {fmt} 106 add_library(test-module OBJECT ${CMAKE_SOURCE_DIR}/src/fmt.cc) 107 target_compile_features(test-module PUBLIC cxx_std_11) 108 target_include_directories(test-module PUBLIC 109 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>) 110 enable_module(test-module) 111 112 add_fmt_test(module-test MODULE test-main.cc) 113 if (MSVC) 114 target_compile_options(test-module PRIVATE /utf-8 /Zc:__cplusplus 115 /Zc:externConstexpr /Zc:inline) 116 target_compile_options(module-test PRIVATE /utf-8 /Zc:__cplusplus 117 /Zc:externConstexpr /Zc:inline) 118 endif () 119endif () 120 121if (NOT DEFINED MSVC_STATIC_RUNTIME AND MSVC) 122 foreach (flag_var 123 CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE 124 CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) 125 if (${flag_var} MATCHES "^(/|-)(MT|MTd)") 126 set(MSVC_STATIC_RUNTIME ON) 127 break() 128 endif() 129 endforeach() 130endif() 131 132if (NOT MSVC_STATIC_RUNTIME) 133 add_executable(posix-mock-test 134 posix-mock-test.cc ../src/format.cc ${TEST_MAIN_SRC}) 135 target_include_directories( 136 posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR}/include) 137 target_link_libraries(posix-mock-test gtest) 138 if (FMT_PEDANTIC) 139 target_compile_options(posix-mock-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) 140 endif () 141 if (MSVC) 142 target_compile_options(posix-mock-test PRIVATE /utf-8) 143 endif () 144 add_test(NAME posix-mock-test COMMAND posix-mock-test) 145 add_fmt_test(os-test) 146endif () 147 148message(STATUS "FMT_PEDANTIC: ${FMT_PEDANTIC}") 149 150if (FMT_PEDANTIC) 151 # Test that the library can be compiled with exceptions disabled. 152 # -fno-exception is broken in icc: https://github.com/fmtlib/fmt/issues/822. 153 if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel") 154 check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG) 155 endif () 156 if (HAVE_FNO_EXCEPTIONS_FLAG) 157 add_library(noexception-test ../src/format.cc noexception-test.cc) 158 target_include_directories( 159 noexception-test PRIVATE ${PROJECT_SOURCE_DIR}/include) 160 target_compile_options(noexception-test PRIVATE -fno-exceptions) 161 target_compile_options(noexception-test PRIVATE ${PEDANTIC_COMPILE_FLAGS}) 162 endif () 163 164 # Test that the library compiles without locale. 165 add_library(nolocale-test ../src/format.cc) 166 target_include_directories( 167 nolocale-test PRIVATE ${PROJECT_SOURCE_DIR}/include) 168 target_compile_definitions( 169 nolocale-test PRIVATE FMT_STATIC_THOUSANDS_SEPARATOR=1) 170endif () 171 172# These tests are disabled on Windows because they take too long. 173# They are disabled on GCC < 4.9 because it can not parse UDLs without 174# a space after `operator""` but that is an incorrect syntax for any more 175# modern compiler. 176if (FMT_PEDANTIC AND NOT WIN32 AND NOT ( 177 CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND 178 CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)) 179 # Test if incorrect API usages produce compilation error. 180 add_test(compile-error-test ${CMAKE_CTEST_COMMAND} 181 --build-and-test 182 "${CMAKE_CURRENT_SOURCE_DIR}/compile-error-test" 183 "${CMAKE_CURRENT_BINARY_DIR}/compile-error-test" 184 --build-generator ${CMAKE_GENERATOR} 185 --build-makeprogram ${CMAKE_MAKE_PROGRAM} 186 --build-options 187 "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 188 "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}" 189 "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" 190 "-DCXX_STANDARD_FLAG=${CXX_STANDARD_FLAG}" 191 "-DFMT_DIR=${CMAKE_SOURCE_DIR}") 192 193 # Test if the targets are found from the build directory. 194 add_test(find-package-test ${CMAKE_CTEST_COMMAND} 195 -C ${CMAKE_BUILD_TYPE} 196 --build-and-test 197 "${CMAKE_CURRENT_SOURCE_DIR}/find-package-test" 198 "${CMAKE_CURRENT_BINARY_DIR}/find-package-test" 199 --build-generator ${CMAKE_GENERATOR} 200 --build-makeprogram ${CMAKE_MAKE_PROGRAM} 201 --build-options 202 "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 203 "-DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}" 204 "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" 205 "-DFMT_DIR=${PROJECT_BINARY_DIR}" 206 "-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}" 207 "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 208 209 # Test if the targets are found when add_subdirectory is used. 210 add_test(add-subdirectory-test ${CMAKE_CTEST_COMMAND} 211 -C ${CMAKE_BUILD_TYPE} 212 --build-and-test 213 "${CMAKE_CURRENT_SOURCE_DIR}/add-subdirectory-test" 214 "${CMAKE_CURRENT_BINARY_DIR}/add-subdirectory-test" 215 --build-generator ${CMAKE_GENERATOR} 216 --build-makeprogram ${CMAKE_MAKE_PROGRAM} 217 --build-options 218 "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 219 "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" 220 "-DPEDANTIC_COMPILE_FLAGS=${PEDANTIC_COMPILE_FLAGS}" 221 "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 222endif () 223 224# This test is disabled on Windows because it is POSIX-specific. 225if (FMT_PEDANTIC AND NOT WIN32) 226 add_test(static-export-test ${CMAKE_CTEST_COMMAND} 227 -C ${CMAKE_BUILD_TYPE} 228 --build-and-test 229 "${CMAKE_CURRENT_SOURCE_DIR}/static-export-test" 230 "${CMAKE_CURRENT_BINARY_DIR}/static-export-test" 231 --build-generator ${CMAKE_GENERATOR} 232 --build-makeprogram ${CMAKE_MAKE_PROGRAM} 233 --build-options 234 "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" 235 "-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}" 236 "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}") 237endif () 238 239# Activate optional CUDA tests if CUDA is found. For version selection see 240# https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#cpp14-language-features 241if (FMT_CUDA_TEST) 242 if (${CMAKE_VERSION} VERSION_LESS 3.15) 243 find_package(CUDA 9.0) 244 else () 245 include(CheckLanguage) 246 check_language(CUDA) 247 if (CMAKE_CUDA_COMPILER) 248 enable_language(CUDA OPTIONAL) 249 set(CUDA_FOUND TRUE) 250 endif () 251 endif () 252 253 if (CUDA_FOUND) 254 add_subdirectory(cuda-test) 255 add_test(NAME cuda-test COMMAND fmt-in-cuda-test) 256 endif () 257endif () 258