diff --git a/CMakeLists.txt b/CMakeLists.txt index e51cb385..5797f87f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -268,7 +268,7 @@ add_subdirectory(src) if (BENCHMARK_ENABLE_TESTING) enable_testing() if (BENCHMARK_ENABLE_GTEST_TESTS) - include(HandleGTest) + include(GoogleTest) endif() add_subdirectory(test) endif() diff --git a/cmake/GoogleTest.cmake b/cmake/GoogleTest.cmake new file mode 100644 index 00000000..6b98c913 --- /dev/null +++ b/cmake/GoogleTest.cmake @@ -0,0 +1,40 @@ +# Download and unpack googletest at configure time +set(GOOGLETEST_PREFIX "${benchmark_BINARY_DIR}/third_party/googletest") +configure_file(${benchmark_SOURCE_DIR}/cmake/GoogleTest.cmake.in ${GOOGLETEST_PREFIX}/CMakeLists.txt @ONLY) + +execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" + -DALLOW_DOWNLOADING_GOOGLETEST=${BENCHMARK_DOWNLOAD_DEPENDENCIES} -DGOOGLETEST_PATH:PATH="${CMAKE_CURRENT_SOURCE_DIR}/googletest" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${GOOGLETEST_PREFIX} +) + +if(result) + message(FATAL_ERROR "CMake step for googletest failed: ${result}") +endif() + +execute_process( + COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${GOOGLETEST_PREFIX} +) + +if(result) + message(FATAL_ERROR "Build step for googletest failed: ${result}") +endif() + +# Prevent overriding the parent project's compiler/linker +# settings on Windows +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +include(${GOOGLETEST_PREFIX}/googletest-paths.cmake) + +# Add googletest directly to our build. This defines +# the gtest and gtest_main targets. +add_subdirectory(${GOOGLETEST_SOURCE_DIR} + ${GOOGLETEST_BINARY_DIR} + EXCLUDE_FROM_ALL) + +set_target_properties(gtest PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) +set_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $) diff --git a/cmake/GoogleTest.cmake.in b/cmake/GoogleTest.cmake.in new file mode 100644 index 00000000..28818ee2 --- /dev/null +++ b/cmake/GoogleTest.cmake.in @@ -0,0 +1,58 @@ +cmake_minimum_required(VERSION 2.8.12) + +project(googletest-download NONE) + +# Enable ExternalProject CMake module +include(ExternalProject) + +option(ALLOW_DOWNLOADING_GOOGLETEST "If googletest src tree is not found in location specified by GOOGLETEST_PATH, do fetch the archive from internet" OFF) +set(GOOGLETEST_PATH "/usr/src/googletest" CACHE PATH + "Path to the googletest root tree. Should contain googletest and googlemock subdirs. And CMakeLists.txt in root, and in both of these subdirs") + +# Download and install GoogleTest + +message(STATUS "Looking for Google Test sources") +message(STATUS "Looking for Google Test sources in ${GOOGLETEST_PATH}") +if(EXISTS "${GOOGLETEST_PATH}" AND IS_DIRECTORY "${GOOGLETEST_PATH}" AND EXISTS "${GOOGLETEST_PATH}/CMakeLists.txt" AND + EXISTS "${GOOGLETEST_PATH}/googletest" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googletest" AND EXISTS "${GOOGLETEST_PATH}/googletest/CMakeLists.txt" AND + EXISTS "${GOOGLETEST_PATH}/googlemock" AND IS_DIRECTORY "${GOOGLETEST_PATH}/googlemock" AND EXISTS "${GOOGLETEST_PATH}/googlemock/CMakeLists.txt") + message(STATUS "Found Google Test in ${GOOGLETEST_PATH}") + + ExternalProject_Add( + googletest + PREFIX "${CMAKE_BINARY_DIR}" + DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download" + SOURCE_DIR "${GOOGLETEST_PATH}" # use existing src dir. + BINARY_DIR "${CMAKE_BINARY_DIR}/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) +else() + if(NOT ALLOW_DOWNLOADING_GOOGLETEST) + message(SEND_ERROR "Did not find Google Test sources! Either pass correct path in GOOGLETEST_PATH, or enable ALLOW_DOWNLOADING_GOOGLETEST, or disable BENCHMARK_ENABLE_GTEST_TESTS / BENCHMARK_ENABLE_TESTING.") + else() + message(WARNING "Did not find Google Test sources! Fetching from web...") + ExternalProject_Add( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG master + PREFIX "${CMAKE_BINARY_DIR}" + STAMP_DIR "${CMAKE_BINARY_DIR}/stamp" + DOWNLOAD_DIR "${CMAKE_BINARY_DIR}/download" + SOURCE_DIR "${CMAKE_BINARY_DIR}/src" + BINARY_DIR "${CMAKE_BINARY_DIR}/build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" + ) + endif() +endif() + +ExternalProject_Get_Property(googletest SOURCE_DIR BINARY_DIR) +file(WRITE googletest-paths.cmake +"set(GOOGLETEST_SOURCE_DIR \"${SOURCE_DIR}\") +set(GOOGLETEST_BINARY_DIR \"${BINARY_DIR}\") +") diff --git a/cmake/HandleGTest.cmake b/cmake/HandleGTest.cmake deleted file mode 100644 index b9c14436..00000000 --- a/cmake/HandleGTest.cmake +++ /dev/null @@ -1,113 +0,0 @@ - -include(split_list) - -macro(build_external_gtest) - include(ExternalProject) - set(GTEST_FLAGS "") - if (BENCHMARK_USE_LIBCXX) - if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - list(APPEND GTEST_FLAGS -stdlib=libc++) - else() - message(WARNING "Unsupported compiler (${CMAKE_CXX_COMPILER}) when using libc++") - endif() - endif() - if (BENCHMARK_BUILD_32_BITS) - list(APPEND GTEST_FLAGS -m32) - endif() - if (NOT "${CMAKE_CXX_FLAGS}" STREQUAL "") - list(APPEND GTEST_FLAGS ${CMAKE_CXX_FLAGS}) - endif() - string(TOUPPER "${CMAKE_BUILD_TYPE}" GTEST_BUILD_TYPE) - if ("${GTEST_BUILD_TYPE}" STREQUAL "COVERAGE") - set(GTEST_BUILD_TYPE "DEBUG") - endif() - # FIXME: Since 10/Feb/2017 the googletest trunk has had a bug where - # -Werror=unused-function fires during the build on OS X. This is a temporary - # workaround to keep our travis bots from failing. It should be removed - # once gtest is fixed. - if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - list(APPEND GTEST_FLAGS "-Wno-unused-function") - endif() - split_list(GTEST_FLAGS) - set(EXCLUDE_FROM_ALL_OPT "") - set(EXCLUDE_FROM_ALL_VALUE "") - if (${CMAKE_VERSION} VERSION_GREATER "3.0.99") - set(EXCLUDE_FROM_ALL_OPT "EXCLUDE_FROM_ALL") - set(EXCLUDE_FROM_ALL_VALUE "ON") - endif() - ExternalProject_Add(googletest - ${EXCLUDE_FROM_ALL_OPT} ${EXCLUDE_FROM_ALL_VALUE} - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master - PREFIX "${CMAKE_BINARY_DIR}/googletest" - INSTALL_DIR "${CMAKE_BINARY_DIR}/googletest" - CMAKE_CACHE_ARGS - -DCMAKE_BUILD_TYPE:STRING=${GTEST_BUILD_TYPE} - -DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER} - -DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER} - -DCMAKE_INSTALL_PREFIX:PATH= - -DCMAKE_INSTALL_LIBDIR:PATH=/lib - -DCMAKE_CXX_FLAGS:STRING=${GTEST_FLAGS} - -Dgtest_force_shared_crt:BOOL=ON - ) - - ExternalProject_Get_Property(googletest install_dir) - set(GTEST_INCLUDE_DIRS ${install_dir}/include) - file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIRS}) - - set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}") - if("${GTEST_BUILD_TYPE}" STREQUAL "DEBUG") - set(LIB_SUFFIX "d${CMAKE_STATIC_LIBRARY_SUFFIX}") - endif() - - # Use gmock_main instead of gtest_main because it initializes gtest as well. - # Note: The libraries are listed in reverse order of their dependancies. - foreach(LIB gtest gmock gmock_main) - add_library(${LIB} UNKNOWN IMPORTED) - set_target_properties(${LIB} PROPERTIES - IMPORTED_LOCATION ${install_dir}/lib/${LIB_PREFIX}${LIB}${LIB_SUFFIX} - INTERFACE_INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIRS} - INTERFACE_LINK_LIBRARIES "${GTEST_BOTH_LIBRARIES}" - ) - add_dependencies(${LIB} googletest) - list(APPEND GTEST_BOTH_LIBRARIES ${LIB}) - endforeach() -endmacro(build_external_gtest) - -if (BENCHMARK_ENABLE_GTEST_TESTS) - if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/googletest) - set(GTEST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/googletest") - set(INSTALL_GTEST OFF CACHE INTERNAL "") - set(INSTALL_GMOCK OFF CACHE INTERNAL "") - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/googletest) - set(GTEST_BOTH_LIBRARIES gtest gmock gmock_main) - foreach(HEADER test mock) - # CMake 2.8 and older don't respect INTERFACE_INCLUDE_DIRECTORIES, so we - # have to add the paths ourselves. - set(HFILE g${HEADER}/g${HEADER}.h) - set(HPATH ${GTEST_ROOT}/google${HEADER}/include) - find_path(HEADER_PATH_${HEADER} ${HFILE} - NO_DEFAULT_PATHS - HINTS ${HPATH} - ) - if (NOT HEADER_PATH_${HEADER}) - message(FATAL_ERROR "Failed to find header ${HFILE} in ${HPATH}") - endif() - list(APPEND GTEST_INCLUDE_DIRS ${HEADER_PATH_${HEADER}}) - endforeach() - elseif(BENCHMARK_DOWNLOAD_DEPENDENCIES) - build_external_gtest() - else() - find_package(GTest REQUIRED) - find_path(GMOCK_INCLUDE_DIRS gmock/gmock.h - HINTS ${GTEST_INCLUDE_DIRS}) - if (NOT GMOCK_INCLUDE_DIRS) - message(FATAL_ERROR "Failed to find header gmock/gmock.h with hint ${GTEST_INCLUDE_DIRS}") - endif() - set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}) - # FIXME: We don't currently require the gmock library to build the tests, - # and it's likely we won't find it, so we don't try. As long as we've - # found the gmock/gmock.h header and gtest_main that should be good enough. - endif() -endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d3a07639..030f35aa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -178,14 +178,8 @@ add_test(complexity_benchmark complexity_test --benchmark_min_time=${COMPLEXITY_ if (BENCHMARK_ENABLE_GTEST_TESTS) macro(compile_gtest name) add_executable(${name} "${name}.cc") - if (TARGET googletest) - add_dependencies(${name} googletest) - endif() - if (GTEST_INCLUDE_DIRS) - target_include_directories(${name} PRIVATE ${GTEST_INCLUDE_DIRS}) - endif() target_link_libraries(${name} benchmark - ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + gmock_main ${CMAKE_THREAD_LIBS_INIT}) endmacro(compile_gtest) macro(add_gtest name)