How to start working with GTest and CMake

You can get the best of both worlds. It is possible to use ExternalProject to download the gtest source and then use add_subdirectory() to add it to your build. This has the following advantages:

  • gtest is built as part of your main build, so it uses the same compiler flags, etc. and hence avoids problems like the ones described in the question.
  • There's no need to add the gtest sources to your own source tree.

Used in the normal way, ExternalProject won't do the download and unpacking at configure time (i.e. when CMake is run), but you can get it to do so with just a little bit of work. I've written a blog post on how to do this which also includes a generalised implementation which works for any external project which uses CMake as its build system, not just gtest. You can find them here:

  • https://crascit.com/2015/07/25/cmake-gtest/
  • https://github.com/Crascit/DownloadProject

Update: This approach is now also part of the googletest documentation.


Here is a complete working example that I just tested. It downloads directly from the web, either a fixed tarball, or the latest subversion directory.

cmake_minimum_required (VERSION 3.1)

project (registerer)

##################################
# Download and install GoogleTest

include(ExternalProject)
ExternalProject_Add(gtest
  URL https://github.com/google/googletest/archive/release-1.8.0.zip
  # Comment above line, and uncomment line below to use subversion.
  # SVN_REPOSITORY http://googletest.googlecode.com/svn/trunk/ 
  # Uncomment line below to freeze a revision (here the one for 1.7.0)
  # SVN_REVISION -r700
  
  PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest
  INSTALL_COMMAND ""
)
ExternalProject_Get_Property(gtest source_dir binary_dir)

################
# Define a test
add_executable(registerer_test registerer_test.cc)

######################################
# Configure the test to use GoogleTest
#
# If used often, could be made a macro.

add_dependencies(registerer_test gtest)
include_directories(${source_dir}/include)
target_link_libraries(registerer_test ${binary_dir}/libgtest.a)
target_link_libraries(registerer_test ${binary_dir}/libgtest_main.a)

##################################
# Just make the test runnable with
#   $ make test
    
enable_testing()
add_test(NAME    registerer_test 
         COMMAND registerer_test)

The solution involved putting the gtest source directory as a subdirectory of your project. I've included the working CMakeLists.txt below if it is helpful to anyone.

cmake_minimum_required(VERSION 2.6)
project(basic_test)

################################
# GTest
################################
ADD_SUBDIRECTORY (gtest-1.6.0)
enable_testing()
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})

################################
# Unit Tests
################################
# Add test cpp file
add_executable( runUnitTests testgtest.cpp )
# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests gtest gtest_main)
add_test( runUnitTests runUnitTests )