CMakeLists.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. cmake_minimum_required (VERSION 3.5.1)
  2. foreach(p
  3. CMP0048 # OK to clear PROJECT_VERSION on project()
  4. CMP0054 # CMake 3.1
  5. CMP0056 # export EXE_LINKER_FLAGS to try_run
  6. CMP0057 # Support no if() IN_LIST operator
  7. CMP0063 # Honor visibility properties for all targets
  8. CMP0077 # Allow option() overrides in importing projects
  9. )
  10. if(POLICY ${p})
  11. cmake_policy(SET ${p} NEW)
  12. endif()
  13. endforeach()
  14. project (benchmark VERSION 1.6.0 LANGUAGES CXX)
  15. option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
  16. option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
  17. option(BENCHMARK_ENABLE_LTO "Enable link time optimisation of the benchmark library." OFF)
  18. option(BENCHMARK_USE_LIBCXX "Build and test using libc++ as the standard library." OFF)
  19. if(NOT MSVC)
  20. option(BENCHMARK_BUILD_32_BITS "Build a 32 bit version of the library." OFF)
  21. else()
  22. set(BENCHMARK_BUILD_32_BITS OFF CACHE BOOL "Build a 32 bit version of the library - unsupported when using MSVC)" FORCE)
  23. endif()
  24. option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
  25. option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON)
  26. # Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
  27. # may require downloading the source code.
  28. option(BENCHMARK_DOWNLOAD_DEPENDENCIES "Allow the downloading and in-tree building of unmet dependencies" OFF)
  29. # This option can be used to disable building and running unit tests which depend on gtest
  30. # in cases where it is not possible to build or find a valid version of gtest.
  31. option(BENCHMARK_ENABLE_GTEST_TESTS "Enable building the unit tests which depend on gtest" ON)
  32. option(BENCHMARK_USE_BUNDLED_GTEST "Use bundled GoogleTest. If disabled, the find_package(GTest) will be used." ON)
  33. option(BENCHMARK_ENABLE_LIBPFM "Enable performance counters provided by libpfm" OFF)
  34. set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
  35. if(MSVC)
  36. # As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and
  37. # cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the
  38. # undocumented, but working variable.
  39. # See https://gitlab.kitware.com/cmake/cmake/-/issues/15170
  40. set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID})
  41. if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ARM")
  42. set(CMAKE_CROSSCOMPILING TRUE)
  43. endif()
  44. endif()
  45. set(ENABLE_ASSEMBLY_TESTS_DEFAULT OFF)
  46. function(should_enable_assembly_tests)
  47. if(CMAKE_BUILD_TYPE)
  48. string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
  49. if (${CMAKE_BUILD_TYPE_LOWER} MATCHES "coverage")
  50. # FIXME: The --coverage flag needs to be removed when building assembly
  51. # tests for this to work.
  52. return()
  53. endif()
  54. endif()
  55. if (MSVC)
  56. return()
  57. elseif(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
  58. return()
  59. elseif(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
  60. # FIXME: Make these work on 32 bit builds
  61. return()
  62. elseif(BENCHMARK_BUILD_32_BITS)
  63. # FIXME: Make these work on 32 bit builds
  64. return()
  65. endif()
  66. find_program(LLVM_FILECHECK_EXE FileCheck)
  67. if (LLVM_FILECHECK_EXE)
  68. set(LLVM_FILECHECK_EXE "${LLVM_FILECHECK_EXE}" CACHE PATH "llvm filecheck" FORCE)
  69. message(STATUS "LLVM FileCheck Found: ${LLVM_FILECHECK_EXE}")
  70. else()
  71. message(STATUS "Failed to find LLVM FileCheck")
  72. return()
  73. endif()
  74. set(ENABLE_ASSEMBLY_TESTS_DEFAULT ON PARENT_SCOPE)
  75. endfunction()
  76. should_enable_assembly_tests()
  77. # This option disables the building and running of the assembly verification tests
  78. option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly tests"
  79. ${ENABLE_ASSEMBLY_TESTS_DEFAULT})
  80. # Make sure we can import out CMake functions
  81. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
  82. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
  83. # Read the git tags to determine the project version
  84. include(GetGitVersion)
  85. get_git_version(GIT_VERSION)
  86. # If no git version can be determined, use the version
  87. # from the project() command
  88. if ("${GIT_VERSION}" STREQUAL "0.0.0")
  89. set(VERSION "${benchmark_VERSION}")
  90. else()
  91. set(VERSION "${GIT_VERSION}")
  92. endif()
  93. # Tell the user what versions we are using
  94. message(STATUS "Version: ${VERSION}")
  95. # The version of the libraries
  96. set(GENERIC_LIB_VERSION ${VERSION})
  97. string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION)
  98. # Import our CMake modules
  99. include(CheckCXXCompilerFlag)
  100. include(AddCXXCompilerFlag)
  101. include(CXXFeatureCheck)
  102. if (BENCHMARK_BUILD_32_BITS)
  103. add_required_cxx_compiler_flag(-m32)
  104. endif()
  105. if (MSVC)
  106. # Turn compiler warnings up to 11
  107. string(REGEX REPLACE "[-/]W[1-4]" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  108. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
  109. add_definitions(-D_CRT_SECURE_NO_WARNINGS)
  110. if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
  111. add_cxx_compiler_flag(-EHs-)
  112. add_cxx_compiler_flag(-EHa-)
  113. add_definitions(-D_HAS_EXCEPTIONS=0)
  114. endif()
  115. # Link time optimisation
  116. if (BENCHMARK_ENABLE_LTO)
  117. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
  118. set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
  119. set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
  120. set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
  121. set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL")
  122. string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}")
  123. set(CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
  124. string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}")
  125. set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
  126. string(REGEX REPLACE "[-/]INCREMENTAL" "/INCREMENTAL:NO" CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}")
  127. set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /LTCG")
  128. set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /GL")
  129. set(CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL "${CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL} /LTCG")
  130. set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "${CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL} /LTCG")
  131. set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "${CMAKE_EXE_LINKER_FLAGS_MINSIZEREL} /LTCG")
  132. endif()
  133. else()
  134. # Try and enable C++11. Don't use C++14 because it doesn't work in some
  135. # configurations.
  136. add_cxx_compiler_flag(-std=c++11)
  137. if (NOT HAVE_CXX_FLAG_STD_CXX11)
  138. add_cxx_compiler_flag(-std=c++0x)
  139. endif()
  140. # Turn compiler warnings up to 11
  141. add_cxx_compiler_flag(-Wall)
  142. add_cxx_compiler_flag(-Wextra)
  143. add_cxx_compiler_flag(-Wshadow)
  144. add_cxx_compiler_flag(-Werror RELEASE)
  145. add_cxx_compiler_flag(-Werror RELWITHDEBINFO)
  146. add_cxx_compiler_flag(-Werror MINSIZEREL)
  147. if (NOT BENCHMARK_ENABLE_TESTING)
  148. # Disable warning when compiling tests as gtest does not use 'override'.
  149. add_cxx_compiler_flag(-Wsuggest-override)
  150. endif()
  151. add_cxx_compiler_flag(-pedantic)
  152. add_cxx_compiler_flag(-pedantic-errors)
  153. add_cxx_compiler_flag(-Wshorten-64-to-32)
  154. add_cxx_compiler_flag(-fstrict-aliasing)
  155. # Disable warnings regarding deprecated parts of the library while building
  156. # and testing those parts of the library.
  157. add_cxx_compiler_flag(-Wno-deprecated-declarations)
  158. if (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  159. # Intel silently ignores '-Wno-deprecated-declarations',
  160. # warning no. 1786 must be explicitly disabled.
  161. # See #631 for rationale.
  162. add_cxx_compiler_flag(-wd1786)
  163. endif()
  164. # Disable deprecation warnings for release builds (when -Werror is enabled).
  165. add_cxx_compiler_flag(-Wno-deprecated RELEASE)
  166. add_cxx_compiler_flag(-Wno-deprecated RELWITHDEBINFO)
  167. add_cxx_compiler_flag(-Wno-deprecated MINSIZEREL)
  168. if (NOT BENCHMARK_ENABLE_EXCEPTIONS)
  169. add_cxx_compiler_flag(-fno-exceptions)
  170. endif()
  171. if (HAVE_CXX_FLAG_FSTRICT_ALIASING)
  172. if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Intel") #ICC17u2: Many false positives for Wstrict-aliasing
  173. add_cxx_compiler_flag(-Wstrict-aliasing)
  174. endif()
  175. endif()
  176. # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden
  177. # (because of deprecated overload)
  178. add_cxx_compiler_flag(-wd654)
  179. add_cxx_compiler_flag(-Wthread-safety)
  180. if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
  181. cxx_feature_check(THREAD_SAFETY_ATTRIBUTES)
  182. endif()
  183. # On most UNIX like platforms g++ and clang++ define _GNU_SOURCE as a
  184. # predefined macro, which turns on all of the wonderful libc extensions.
  185. # However g++ doesn't do this in Cygwin so we have to define it ourselfs
  186. # since we depend on GNU/POSIX/BSD extensions.
  187. if (CYGWIN)
  188. add_definitions(-D_GNU_SOURCE=1)
  189. endif()
  190. if (QNXNTO)
  191. add_definitions(-D_QNX_SOURCE)
  192. endif()
  193. # Link time optimisation
  194. if (BENCHMARK_ENABLE_LTO)
  195. add_cxx_compiler_flag(-flto)
  196. add_cxx_compiler_flag(-Wno-lto-type-mismatch)
  197. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  198. find_program(GCC_AR gcc-ar)
  199. if (GCC_AR)
  200. set(CMAKE_AR ${GCC_AR})
  201. endif()
  202. find_program(GCC_RANLIB gcc-ranlib)
  203. if (GCC_RANLIB)
  204. set(CMAKE_RANLIB ${GCC_RANLIB})
  205. endif()
  206. elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  207. include(llvm-toolchain)
  208. endif()
  209. endif()
  210. # Coverage build type
  211. set(BENCHMARK_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG}"
  212. CACHE STRING "Flags used by the C++ compiler during coverage builds."
  213. FORCE)
  214. set(BENCHMARK_EXE_LINKER_FLAGS_COVERAGE "${CMAKE_EXE_LINKER_FLAGS_DEBUG}"
  215. CACHE STRING "Flags used for linking binaries during coverage builds."
  216. FORCE)
  217. set(BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}"
  218. CACHE STRING "Flags used by the shared libraries linker during coverage builds."
  219. FORCE)
  220. mark_as_advanced(
  221. BENCHMARK_CXX_FLAGS_COVERAGE
  222. BENCHMARK_EXE_LINKER_FLAGS_COVERAGE
  223. BENCHMARK_SHARED_LINKER_FLAGS_COVERAGE)
  224. set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING
  225. "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel Coverage.")
  226. add_cxx_compiler_flag(--coverage COVERAGE)
  227. endif()
  228. if (BENCHMARK_USE_LIBCXX)
  229. if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  230. add_cxx_compiler_flag(-stdlib=libc++)
  231. elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR
  232. "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
  233. add_cxx_compiler_flag(-nostdinc++)
  234. message(WARNING "libc++ header path must be manually specified using CMAKE_CXX_FLAGS")
  235. # Adding -nodefaultlibs directly to CMAKE_<TYPE>_LINKER_FLAGS will break
  236. # configuration checks such as 'find_package(Threads)'
  237. list(APPEND BENCHMARK_CXX_LINKER_FLAGS -nodefaultlibs)
  238. # -lc++ cannot be added directly to CMAKE_<TYPE>_LINKER_FLAGS because
  239. # linker flags appear before all linker inputs and -lc++ must appear after.
  240. list(APPEND BENCHMARK_CXX_LIBRARIES c++)
  241. else()
  242. message(FATAL_ERROR "-DBENCHMARK_USE_LIBCXX:BOOL=ON is not supported for compiler")
  243. endif()
  244. endif(BENCHMARK_USE_LIBCXX)
  245. set(EXTRA_CXX_FLAGS "")
  246. if (WIN32 AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  247. # Clang on Windows fails to compile the regex feature check under C++11
  248. set(EXTRA_CXX_FLAGS "-DCMAKE_CXX_STANDARD=14")
  249. endif()
  250. # C++ feature checks
  251. # Determine the correct regular expression engine to use
  252. cxx_feature_check(STD_REGEX ${EXTRA_CXX_FLAGS})
  253. cxx_feature_check(GNU_POSIX_REGEX ${EXTRA_CXX_FLAGS})
  254. cxx_feature_check(POSIX_REGEX ${EXTRA_CXX_FLAGS})
  255. if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
  256. message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
  257. endif()
  258. if (NOT BENCHMARK_ENABLE_EXCEPTIONS AND HAVE_STD_REGEX
  259. AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
  260. message(WARNING "Using std::regex with exceptions disabled is not fully supported")
  261. endif()
  262. cxx_feature_check(STEADY_CLOCK)
  263. # Ensure we have pthreads
  264. set(THREADS_PREFER_PTHREAD_FLAG ON)
  265. find_package(Threads REQUIRED)
  266. if (BENCHMARK_ENABLE_LIBPFM)
  267. find_package(PFM)
  268. endif()
  269. # Set up directories
  270. include_directories(${PROJECT_SOURCE_DIR}/include)
  271. # Build the targets
  272. add_subdirectory(src)
  273. if (BENCHMARK_ENABLE_TESTING)
  274. enable_testing()
  275. if (BENCHMARK_ENABLE_GTEST_TESTS AND
  276. NOT (TARGET gtest AND TARGET gtest_main AND
  277. TARGET gmock AND TARGET gmock_main))
  278. if (BENCHMARK_USE_BUNDLED_GTEST)
  279. include(GoogleTest)
  280. else()
  281. find_package(GTest CONFIG REQUIRED)
  282. add_library(gtest ALIAS GTest::gtest)
  283. add_library(gtest_main ALIAS GTest::gtest_main)
  284. add_library(gmock ALIAS GTest::gmock)
  285. add_library(gmock_main ALIAS GTest::gmock_main)
  286. endif()
  287. endif()
  288. add_subdirectory(test)
  289. endif()