Skip to content

Instantly share code, notes, and snippets.

@johnb003
Forked from ClintLiddick/External_GTest.cmake
Last active April 13, 2024 09:03
Show Gist options
  • Save johnb003/65982fdc7a1274fdb023b0c68664ebe4 to your computer and use it in GitHub Desktop.
Save johnb003/65982fdc7a1274fdb023b0c68664ebe4 to your computer and use it in GitHub Desktop.
CMake ExternalProject_Add for Google Mock (gmock) and Google Test (gtest) Libraries With Includes and Example Usage
# Assuming this your tests/CMakeLists.txt (and your libs are setup in a root config)
# Just make sure to include(CTest) in your *root* cmake config.
# 3.9 adds support for "GoogleTest" which enumerates the tests inside
# of the code and adds them to ctest.
cmake_minimum_required(VERSION 3.9)
# Configure google-test as a downloadable library.
include(External_GTest.cmake)
add_executable(myTests
src/main.cpp)
# This will automatically handle all of the lib linkage and include dirs
target_link_libraries(myTests
libraryTargetOfCodeBeingTested
${GTEST_LIBRARY}
)
# Tell ctest about my tests
include(GoogleTest)
gtest_add_tests(
TARGET myTests
TEST_LIST myTests_targets
)
# set each target to timeout if not finished within 10 sec
set_tests_properties(${myTests_targets} PROPERTIES TIMEOUT 10)
find_package(Threads REQUIRED)
include(ExternalProject)
ExternalProject_Add(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
UPDATE_COMMAND ""
INSTALL_COMMAND ""
LOG_DOWNLOAD ON
LOG_CONFIGURE ON
LOG_BUILD ON)
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include)
set(GMOCK_INCLUDE_DIRS ${source_dir}/googlemock/include)
# The cloning of the above repo doesn't happen until make, however if the dir doesn't
# exist, INTERFACE_INCLUDE_DIRECTORIES will throw an error.
# To make it work, we just create the directory now during config.
file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIRS})
file(MAKE_DIRECTORY ${GMOCK_INCLUDE_DIRS})
ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest.a)
set(GTEST_LIBRARY gtest)
add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED)
set_target_properties(${GTEST_LIBRARY} PROPERTIES
"IMPORTED_LOCATION" "${GTEST_LIBRARY_PATH}"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
"INTERFACE_INCLUDE_DIRECTORIES" "${GTEST_INCLUDE_DIRS}")
add_dependencies(${GTEST_LIBRARY} googletest)
set(GTEST_MAIN_LIBRARY_PATH ${binary_dir}/googlemock/gtest/${CMAKE_FIND_LIBRARY_PREFIXES}gtest_main.a)
set(GTEST_MAIN_LIBRARY gtest_main)
add_library(${GTEST_MAIN_LIBRARY} UNKNOWN IMPORTED)
set_target_properties(${GTEST_MAIN_LIBRARY} PROPERTIES
"IMPORTED_LOCATION" "${GTEST_MAIN_LIBRARY_PATH}"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
"INTERFACE_INCLUDE_DIRECTORIES" "${GTEST_INCLUDE_DIRS}")
add_dependencies(${GTEST_MAIN_LIBRARY} googletest)
set(GMOCK_LIBRARY_PATH ${binary_dir}/googlemock/${CMAKE_FIND_LIBRARY_PREFIXES}gmock.a)
set(GMOCK_LIBRARY gmock)
add_library(${GMOCK_LIBRARY} UNKNOWN IMPORTED)
set_target_properties(${GMOCK_LIBRARY} PROPERTIES
"IMPORTED_LOCATION" "${GMOCK_LIBRARY_PATH}"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
"INTERFACE_INCLUDE_DIRECTORIES" "${GMOCK_INCLUDE_DIRS}")
add_dependencies(${GMOCK_LIBRARY} googletest)
set(GMOCK_MAIN_LIBRARY_PATH ${binary_dir}/googlemock/${CMAKE_FIND_LIBRARY_PREFIXES}gmock_main.a)
set(GMOCK_MAIN_LIBRARY gmock_main)
add_library(${GMOCK_MAIN_LIBRARY} UNKNOWN IMPORTED)
set_target_properties(${GMOCK_MAIN_LIBRARY} PROPERTIES
"IMPORTED_LOCATION" "${GMOCK_MAIN_LIBRARY_PATH}"
"IMPORTED_LINK_INTERFACE_LIBRARIES" "${CMAKE_THREAD_LIBS_INIT}"
"INTERFACE_INCLUDE_DIRECTORIES" "${GMOCK_INCLUDE_DIRS}")
add_dependencies(${GMOCK_MAIN_LIBRARY} ${GTEST_LIBRARY})
@johnb003
Copy link
Author

johnb003 commented Jan 9, 2018

As an alternative to:
gtest_add_tests(TARGET myTests TEST_LIST myTests_targets)
you can use:
gtest_discover_tests(myTests TEST_LIST myTests_targets)

But you'll need CMake 3.10.
This method is able to overcome some limitations of the "gtest_add_tests". See: https://blog.kitware.com/dynamic-google-test-discovery-in-cmake-3-10/ for a detailed explanation.

@nboutin
Copy link

nboutin commented Dec 5, 2018

Using as it is, I have the following error:
make[2]: *** No rule to make target 'googletest-prefix/src/googletest-build/googlemock/gtest/libgtest.a', needed by 'myTests'. Stop.

Any idea ?

@shawncao
Copy link

shawncao commented Dec 7, 2018

Using as it is, I have the following error:
make[2]: *** No rule to make target 'googletest-prefix/src/googletest-build/googlemock/gtest/libgtest.a', needed by 'myTests'. Stop.

Any idea ?

just change "googlemock/gtest" with "lib" in External_GTest.cmake for you

@Mars-2dot
Copy link

Is it possible to rewrite External_GTest.cmake to build a project for windows?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment