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