mirror of https://github.com/google/benchmark.git
CMake: codedrop of googletest cmake magic from me (#809)
https://github.com/google/benchmark/pull/801 is stuck with some cryptic cmake failure due to some linking issue between googletest and threading libraries. I suspect that is mostly happening because of the, uhm, intentionally extremely twisted-in-the-brains approach that is being used to actually build the library as part of the buiild, except without actually building it as part of the build. If we do actually build it as part of the build, then all the transitive dependencies should magically be in order, and maybe everything will just work. This new version of cmake magic was written by me in0e22f085c5/cmake/Modules/GoogleTest.cmake.in
0e22f085c5/cmake/Modules/GoogleTest.cmake
, based on the official googletest docs and LOTS of experimentation.
This commit is contained in:
parent
05d8c1c5d0
commit
4b77194032
|
@ -268,7 +268,7 @@ add_subdirectory(src)
|
||||||
if (BENCHMARK_ENABLE_TESTING)
|
if (BENCHMARK_ENABLE_TESTING)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
if (BENCHMARK_ENABLE_GTEST_TESTS)
|
if (BENCHMARK_ENABLE_GTEST_TESTS)
|
||||||
include(HandleGTest)
|
include(GoogleTest)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -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 $<TARGET_PROPERTY:gtest,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
set_target_properties(gtest_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gtest_main,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
set_target_properties(gmock PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||||
|
set_target_properties(gmock_main PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES $<TARGET_PROPERTY:gmock_main,INTERFACE_INCLUDE_DIRECTORIES>)
|
|
@ -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}\")
|
||||||
|
")
|
|
@ -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=<INSTALL_DIR>
|
|
||||||
-DCMAKE_INSTALL_LIBDIR:PATH=<INSTALL_DIR>/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()
|
|
|
@ -178,14 +178,8 @@ add_test(complexity_benchmark complexity_test --benchmark_min_time=${COMPLEXITY_
|
||||||
if (BENCHMARK_ENABLE_GTEST_TESTS)
|
if (BENCHMARK_ENABLE_GTEST_TESTS)
|
||||||
macro(compile_gtest name)
|
macro(compile_gtest name)
|
||||||
add_executable(${name} "${name}.cc")
|
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
|
target_link_libraries(${name} benchmark
|
||||||
${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
|
gmock_main ${CMAKE_THREAD_LIBS_INIT})
|
||||||
endmacro(compile_gtest)
|
endmacro(compile_gtest)
|
||||||
|
|
||||||
macro(add_gtest name)
|
macro(add_gtest name)
|
||||||
|
|
Loading…
Reference in New Issue