1include(ExternalProject) 2include(CheckCXXCompilerFlag) 3 4#============================================================================== 5# Build Google Benchmark for libc++ 6#============================================================================== 7 8set(BENCHMARK_LIBCXX_COMPILE_FLAGS 9 -Wno-unused-command-line-argument 10 -nostdinc++ 11 -isystem ${LIBCXX_SOURCE_DIR}/include 12 -L${LIBCXX_LIBRARY_DIR} 13 -Wl,-rpath,${LIBCXX_LIBRARY_DIR} 14 ${SANITIZER_FLAGS} 15 ) 16if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH) 17 list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS 18 -L${LIBCXX_CXX_ABI_LIBRARY_PATH} 19 -Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH}) 20endif() 21list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -include "${LIBCXX_BINARY_DIR}/__config_site") 22split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS) 23 24ExternalProject_Add(google-benchmark-libcxx 25 EXCLUDE_FROM_ALL ON 26 DEPENDS cxx cxx-headers 27 PREFIX benchmark-libcxx 28 SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark 29 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx 30 CMAKE_CACHE_ARGS 31 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} 32 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} 33 -DCMAKE_BUILD_TYPE:STRING=RELEASE 34 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 35 -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS} 36 -DBENCHMARK_USE_LIBCXX:BOOL=ON 37 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF) 38 39#============================================================================== 40# Build Google Benchmark for the native stdlib 41#============================================================================== 42set(BENCHMARK_NATIVE_TARGET_FLAGS) 43if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN) 44 set(BENCHMARK_NATIVE_TARGET_FLAGS 45 -gcc-toolchain ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) 46endif() 47split_list(BENCHMARK_NATIVE_TARGET_FLAGS) 48 49if (LIBCXX_BENCHMARK_NATIVE_STDLIB) 50 ExternalProject_Add(google-benchmark-native 51 EXCLUDE_FROM_ALL ON 52 PREFIX benchmark-native 53 SOURCE_DIR ${LIBCXX_SOURCE_DIR}/utils/google-benchmark 54 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native 55 CMAKE_CACHE_ARGS 56 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} 57 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} 58 -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_NATIVE_TARGET_FLAGS} 59 -DCMAKE_BUILD_TYPE:STRING=RELEASE 60 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 61 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF) 62endif() 63 64 65#============================================================================== 66# Benchmark tests configuration 67#============================================================================== 68add_custom_target(cxx-benchmarks) 69set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) 70set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx) 71set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native) 72 73check_flag_supported("-std=c++17") 74mangle_name("LIBCXX_SUPPORTS_STD_EQ_c++17_FLAG" BENCHMARK_SUPPORTS_STD_CXX17_FLAG) 75if (${BENCHMARK_SUPPORTS_STD_CXX17_FLAG}) 76 set(BENCHMARK_DIALECT_FLAG "-std=c++17") 77else() 78 # If the compiler doesn't support -std=c++17, attempt to fall back to -std=c++1z while still 79 # requiring C++17 language features. 80 set(BENCHMARK_DIALECT_FLAG "-std=c++1z") 81endif() 82 83set(BENCHMARK_TEST_COMPILE_FLAGS 84 ${BENCHMARK_DIALECT_FLAG} -O2 85 -fsized-deallocation 86 -I${BENCHMARK_LIBCXX_INSTALL}/include 87 -I${LIBCXX_SOURCE_DIR}/test/support 88) 89set(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS 90 ${BENCHMARK_TEST_COMPILE_FLAGS} 91 ${SANITIZER_FLAGS} 92 -Wno-user-defined-literals 93) 94 95set(BENCHMARK_TEST_LIBCXX_LINK_FLAGS 96 -nodefaultlibs 97 -L${BENCHMARK_LIBCXX_INSTALL}/lib/ 98 ${SANITIZER_FLAGS} 99) 100set(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS 101 ${BENCHMARK_NATIVE_TARGET_FLAGS} 102 ${BENCHMARK_TEST_COMPILE_FLAGS} 103) 104set(BENCHMARK_TEST_NATIVE_LINK_FLAGS 105 ${BENCHMARK_NATIVE_TARGET_FLAGS} 106 -L${BENCHMARK_NATIVE_INSTALL}/lib 107) 108split_list(BENCHMARK_TEST_COMPILE_FLAGS) 109split_list(BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS) 110split_list(BENCHMARK_TEST_LIBCXX_LINK_FLAGS) 111split_list(BENCHMARK_TEST_NATIVE_COMPILE_FLAGS) 112split_list(BENCHMARK_TEST_NATIVE_LINK_FLAGS) 113 114if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") 115 find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs 116 PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN} 117 PATH_SUFFIXES lib lib64 118 DOC "The libstdc++ filesystem library used by the benchmarks" 119 ) 120 if (NOT "${LIBSTDCXX_FILESYSTEM_TEST}" STREQUAL "LIBSTDCXX_FILESYSTEM_TEST-NOTFOUND") 121 set(LIBSTDCXX_FILESYSTEM_LIB "stdc++fs") 122 endif() 123endif() 124 125set(libcxx_benchmark_targets) 126 127function(add_benchmark_test name source_file) 128 set(libcxx_target ${name}_libcxx) 129 list(APPEND libcxx_benchmark_targets ${libcxx_target}) 130 add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file}) 131 add_dependencies(${libcxx_target} cxx google-benchmark-libcxx) 132 add_dependencies(cxx-benchmarks ${libcxx_target}) 133 if (LIBCXX_ENABLE_SHARED) 134 target_link_libraries(${libcxx_target} PRIVATE cxx_shared) 135 else() 136 target_link_libraries(${libcxx_target} PRIVATE cxx_static) 137 endif() 138 if (TARGET cxx_experimental) 139 target_link_libraries(${libcxx_target} PRIVATE cxx_experimental) 140 endif() 141 target_link_libraries(${libcxx_target} PRIVATE -lbenchmark) 142 if (LLVM_USE_SANITIZER) 143 target_link_libraries(${libcxx_target} PRIVATE -ldl) 144 endif() 145 set_target_properties(${libcxx_target} 146 PROPERTIES 147 OUTPUT_NAME "${name}.libcxx.out" 148 RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" 149 COMPILE_FLAGS "${BENCHMARK_TEST_LIBCXX_COMPILE_FLAGS}" 150 LINK_FLAGS "${BENCHMARK_TEST_LIBCXX_LINK_FLAGS}") 151 cxx_link_system_libraries(${libcxx_target}) 152 if (LIBCXX_BENCHMARK_NATIVE_STDLIB) 153 if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++" AND NOT DEFINED LIBSTDCXX_FILESYSTEM_LIB 154 AND "${name}" STREQUAL "filesystem") 155 return() 156 endif() 157 set(native_target ${name}_native) 158 add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file}) 159 add_dependencies(${native_target} google-benchmark-native 160 google-benchmark-libcxx) 161 target_link_libraries(${native_target} PRIVATE -lbenchmark) 162 if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") 163 target_link_libraries(${native_target} PRIVATE ${LIBSTDCXX_FILESYSTEM_LIB}) 164 elseif (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libc++") 165 target_link_libraries(${native_target} PRIVATE -lc++fs -lc++experimental) 166 endif() 167 if (LIBCXX_HAS_PTHREAD_LIB) 168 target_link_libraries(${native_target} PRIVATE -pthread) 169 endif() 170 add_dependencies(cxx-benchmarks ${native_target}) 171 set_target_properties(${native_target} 172 PROPERTIES 173 OUTPUT_NAME "${name}.native.out" 174 RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" 175 INCLUDE_DIRECTORIES "" 176 COMPILE_FLAGS "${BENCHMARK_TEST_NATIVE_COMPILE_FLAGS}" 177 LINK_FLAGS "${BENCHMARK_TEST_NATIVE_LINK_FLAGS}") 178 endif() 179endfunction() 180 181 182#============================================================================== 183# Register Benchmark tests 184#============================================================================== 185file(GLOB BENCHMARK_TESTS "*.bench.cpp") 186foreach(test_path ${BENCHMARK_TESTS}) 187 get_filename_component(test_file "${test_path}" NAME) 188 string(REPLACE ".bench.cpp" "" test_name "${test_file}") 189 if (NOT DEFINED ${test_name}_REPORTED) 190 message(STATUS "Adding Benchmark: ${test_file}") 191 # Only report the adding of the benchmark once. 192 set(${test_name}_REPORTED ON CACHE INTERNAL "") 193 endif() 194 add_benchmark_test(${test_name} ${test_file}) 195endforeach() 196 197if (LIBCXX_INCLUDE_TESTS) 198 include(AddLLVM) 199 200 if (NOT DEFINED LIBCXX_TEST_DEPS) 201 message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined") 202 endif() 203 204 configure_lit_site_cfg( 205 ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 206 ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py) 207 208 set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}") 209 210 add_lit_target(check-cxx-benchmarks 211 "Running libcxx benchmarks tests" 212 ${CMAKE_CURRENT_BINARY_DIR} 213 DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS} 214 ARGS ${BENCHMARK_LIT_ARGS}) 215endif() 216