1if (CMAKE_VERSION VERSION_LESS 3.17) 2 message(WARNING "The libc++ benchmarks won't be available because the version of CMake is too old to support them.") 3 return() 4endif() 5 6include(ExternalProject) 7include(CheckCXXCompilerFlag) 8 9#============================================================================== 10# Build Google Benchmark for libc++ 11#============================================================================== 12 13set(CMAKE_FOLDER "${CMAKE_FOLDER}/Benchmarks") 14 15set(BENCHMARK_LIBCXX_COMPILE_FLAGS 16 -Wno-unused-command-line-argument 17 -nostdinc++ 18 -isystem "${LIBCXX_GENERATED_INCLUDE_DIR}" 19 -L${LIBCXX_LIBRARY_DIR} 20 -Wl,-rpath,${LIBCXX_LIBRARY_DIR} 21 ${SANITIZER_FLAGS} 22 ) 23if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) 24 list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS 25 -isystem "${LIBCXX_GENERATED_INCLUDE_TARGET_DIR}") 26endif() 27if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH) 28 list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS 29 -L${LIBCXX_CXX_ABI_LIBRARY_PATH} 30 -Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH}) 31endif() 32split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS) 33 34ExternalProject_Add(google-benchmark-libcxx 35 EXCLUDE_FROM_ALL ON 36 DEPENDS cxx cxx-headers 37 PREFIX benchmark-libcxx 38 SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark 39 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx 40 CMAKE_CACHE_ARGS 41 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} 42 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} 43 -DCMAKE_BUILD_TYPE:STRING=RELEASE 44 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 45 -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_LIBCXX_COMPILE_FLAGS} 46 -DBENCHMARK_USE_LIBCXX:BOOL=ON 47 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF) 48 49#============================================================================== 50# Build Google Benchmark for the native stdlib 51#============================================================================== 52set(BENCHMARK_NATIVE_TARGET_FLAGS) 53if (LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN) 54 set(BENCHMARK_NATIVE_TARGET_FLAGS 55 --gcc-toolchain=${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN}) 56endif() 57split_list(BENCHMARK_NATIVE_TARGET_FLAGS) 58 59if (LIBCXX_BENCHMARK_NATIVE_STDLIB) 60 ExternalProject_Add(google-benchmark-native 61 EXCLUDE_FROM_ALL ON 62 PREFIX benchmark-native 63 SOURCE_DIR ${LLVM_THIRD_PARTY_DIR}/benchmark 64 INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native 65 CMAKE_CACHE_ARGS 66 -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} 67 -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} 68 -DCMAKE_CXX_FLAGS:STRING=${BENCHMARK_NATIVE_TARGET_FLAGS} 69 -DCMAKE_BUILD_TYPE:STRING=RELEASE 70 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 71 -DBENCHMARK_ENABLE_TESTING:BOOL=OFF) 72endif() 73 74 75#============================================================================== 76# Benchmark tests configuration 77#============================================================================== 78add_custom_target(cxx-benchmarks) 79set(BENCHMARK_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) 80set(BENCHMARK_LIBCXX_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-libcxx) 81set(BENCHMARK_NATIVE_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/benchmark-native) 82 83add_library( cxx-benchmarks-flags INTERFACE) 84target_compile_features( cxx-benchmarks-flags INTERFACE cxx_std_20) 85target_compile_options( cxx-benchmarks-flags INTERFACE -fsized-deallocation -nostdinc++) 86target_include_directories(cxx-benchmarks-flags INTERFACE "${LIBCXX_GENERATED_INCLUDE_DIR}" 87 INTERFACE "${BENCHMARK_LIBCXX_INSTALL}/include" 88 INTERFACE "${LIBCXX_SOURCE_DIR}/test/support") 89 90add_library( cxx-benchmarks-flags-native INTERFACE) 91target_link_libraries( cxx-benchmarks-flags-native INTERFACE cxx-benchmarks-flags) 92target_compile_options(cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS}) 93target_link_options( cxx-benchmarks-flags-native INTERFACE ${BENCHMARK_NATIVE_TARGET_FLAGS} "-L${BENCHMARK_NATIVE_INSTALL}/lib") 94if (LIBCXX_BENCHMARK_NATIVE_STDLIB STREQUAL "libstdc++") 95 find_library(LIBSTDCXX_FILESYSTEM_TEST stdc++fs 96 PATHS ${LIBCXX_BENCHMARK_NATIVE_GCC_TOOLCHAIN} 97 PATH_SUFFIXES lib lib64 98 DOC "The libstdc++ filesystem library used by the benchmarks" 99 ) 100 if (LIBSTDCXX_FILESYSTEM_TEST) 101 target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lstdc++fs) 102 endif() 103else() 104 target_link_libraries(cxx-benchmarks-flags-native INTERFACE -lc++fs -lc++experimental) 105endif() 106 107add_library( cxx-benchmarks-flags-libcxx INTERFACE) 108target_link_libraries( cxx-benchmarks-flags-libcxx INTERFACE cxx-benchmarks-flags) 109target_compile_options(cxx-benchmarks-flags-libcxx INTERFACE ${SANITIZER_FLAGS} -Wno-user-defined-literals -Wno-suggest-override) 110target_link_options( cxx-benchmarks-flags-libcxx INTERFACE -nodefaultlibs "-L${BENCHMARK_LIBCXX_INSTALL}/lib" ${SANITIZER_FLAGS}) 111 112set(libcxx_benchmark_targets) 113 114function(add_benchmark_test name source_file) 115 set(libcxx_target ${name}_libcxx) 116 list(APPEND libcxx_benchmark_targets ${libcxx_target}) 117 add_executable(${libcxx_target} EXCLUDE_FROM_ALL ${source_file}) 118 target_link_libraries(${libcxx_target} PRIVATE cxx-benchmarks-flags-libcxx) 119 add_dependencies(${libcxx_target} cxx google-benchmark-libcxx) 120 add_dependencies(cxx-benchmarks ${libcxx_target}) 121 if (LIBCXX_ENABLE_SHARED) 122 target_link_libraries(${libcxx_target} PRIVATE cxx_shared) 123 else() 124 target_link_libraries(${libcxx_target} PRIVATE cxx_static) 125 endif() 126 target_link_libraries(${libcxx_target} PRIVATE cxx_experimental benchmark) 127 if (LLVM_USE_SANITIZER) 128 target_link_libraries(${libcxx_target} PRIVATE -ldl) 129 endif() 130 set_target_properties(${libcxx_target} 131 PROPERTIES 132 OUTPUT_NAME "${name}.libcxx.out" 133 RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" 134 CXX_EXTENSIONS NO) 135 cxx_link_system_libraries(${libcxx_target}) 136 if (LIBCXX_BENCHMARK_NATIVE_STDLIB) 137 set(native_target ${name}_native) 138 add_executable(${native_target} EXCLUDE_FROM_ALL ${source_file}) 139 target_link_libraries(${native_target} PRIVATE cxx-benchmarks-flags-native) 140 add_dependencies(${native_target} google-benchmark-native 141 google-benchmark-libcxx) 142 target_link_libraries(${native_target} PRIVATE -lbenchmark) 143 if (LIBCXX_HAS_PTHREAD_LIB) 144 target_link_libraries(${native_target} PRIVATE -pthread) 145 endif() 146 add_dependencies(cxx-benchmarks ${native_target}) 147 set_target_properties(${native_target} 148 PROPERTIES 149 OUTPUT_NAME "${name}.native.out" 150 RUNTIME_OUTPUT_DIRECTORY "${BENCHMARK_OUTPUT_DIR}" 151 CXX_EXTENSIONS NO) 152 endif() 153endfunction() 154 155 156#============================================================================== 157# Register Benchmark tests 158#============================================================================== 159set(BENCHMARK_TESTS 160 algorithms.partition_point.bench.cpp 161 algorithms/lower_bound.bench.cpp 162 algorithms/make_heap.bench.cpp 163 algorithms/make_heap_then_sort_heap.bench.cpp 164 algorithms/min_max_element.bench.cpp 165 algorithms/pop_heap.bench.cpp 166 algorithms/push_heap.bench.cpp 167 algorithms/ranges_make_heap.bench.cpp 168 algorithms/ranges_make_heap_then_sort_heap.bench.cpp 169 algorithms/ranges_pop_heap.bench.cpp 170 algorithms/ranges_push_heap.bench.cpp 171 algorithms/ranges_sort.bench.cpp 172 algorithms/ranges_sort_heap.bench.cpp 173 algorithms/ranges_stable_sort.bench.cpp 174 algorithms/sort.bench.cpp 175 algorithms/sort_heap.bench.cpp 176 algorithms/stable_sort.bench.cpp 177 allocation.bench.cpp 178 deque.bench.cpp 179 deque_iterator.bench.cpp 180 filesystem.bench.cpp 181 format_to_n.bench.cpp 182 format_to.bench.cpp 183 format.bench.cpp 184 formatted_size.bench.cpp 185 formatter_float.bench.cpp 186 formatter_int.bench.cpp 187 function.bench.cpp 188 join_view.bench.cpp 189 map.bench.cpp 190 monotonic_buffer.bench.cpp 191 ordered_set.bench.cpp 192 std_format_spec_string_unicode.bench.cpp 193 string.bench.cpp 194 stringstream.bench.cpp 195 to_chars.bench.cpp 196 unordered_set_operations.bench.cpp 197 util_smartptr.bench.cpp 198 variant_visit_1.bench.cpp 199 variant_visit_2.bench.cpp 200 variant_visit_3.bench.cpp 201 vector_operations.bench.cpp 202 ) 203 204foreach(test_path ${BENCHMARK_TESTS}) 205 get_filename_component(test_file "${test_path}" NAME) 206 string(REPLACE ".bench.cpp" "" test_name "${test_file}") 207 if (NOT DEFINED ${test_name}_REPORTED) 208 message(STATUS "Adding Benchmark: ${test_file}") 209 # Only report the adding of the benchmark once. 210 set(${test_name}_REPORTED ON CACHE INTERNAL "") 211 endif() 212 add_benchmark_test(${test_name} ${test_path}) 213endforeach() 214 215if (LIBCXX_INCLUDE_TESTS) 216 include(AddLLVM) 217 218 if (NOT DEFINED LIBCXX_TEST_DEPS) 219 message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined") 220 endif() 221 222 configure_lit_site_cfg( 223 ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in 224 ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py) 225 226 set(BENCHMARK_LIT_ARGS "--show-all --show-xfail --show-unsupported ${LIT_ARGS_DEFAULT}") 227 228 add_lit_target(check-cxx-benchmarks 229 "Running libcxx benchmarks tests" 230 ${CMAKE_CURRENT_BINARY_DIR} 231 DEPENDS cxx-benchmarks ${LIBCXX_TEST_DEPS} 232 ARGS ${BENCHMARK_LIT_ARGS}) 233endif() 234