4
votes

I want to use gtest within a CMake project. Previously, I had built gtest and copied the headers and libraries into a location where they could be found in order to overcome the lack of an Ubuntu package to provide the same.

The approach recommended by the gtest developers is to build gtest inside the project that is using it.

However, I would also like to use the functions gtest_add_tests and gtest_discover_tests, which are defined in CMake's GoogleTest module.

But find_package(GTest REQUIRED) fails because the library hasn't been built yet:

Could NOT find GTest (missing: GTEST_LIBRARY GTEST_MAIN_LIBRARY)

So it seems like it has to be a two stage process, and there is no way to guarantee compliance with the 'One-Definition Rule'. Do I need to write a custom FindGTest.cmake that defines the functions but doesn't look for the libraries, so that they will only become available after cmake completes and make builds them?

3

3 Answers

3
votes

You might consider using External Projects.

http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html

You could use it roughly like the following (from my code that does the same thing, versions may vary, etc):

set(GTest_version 1.6.0)
set(GTest_url "http://googletest.googlecode.com/files/gtest-${GTest_version}.zip")
set(GTest_md5 "4577b49f2973c90bf9ba69aa8166b786")
set(GTest_BUILD_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/build")
set(GTest_BUILD_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/install")
set(GTest_DOWNLOAD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Downloads")

ExternalProject_Add(GTest
  URL ${GTest_url}
  URL_MD5 ${GTest_md5}
  PREFIX  ${GTest_BUILD_PREFIX}
  DOWNLOAD_DIR ${GTest_DOWNLOAD_DIR}
  CMAKE_GENERATOR ${gen}
  CMAKE_ARGS
    -DBUILD_SHARED_LIBS:BOOL=ON
    -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
    -DCMAKE_INSTALL_PREFIX:PATH=${GTest_BUILD_INSTALL_PREFIX}
    -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
)

set(GTEST_ROOT ${GTest_BUILD_INSTALL_PREFIX} CACHE STRING "")
0
votes

Another option is to make the GoogleTest sources available to your build at CMake time and simply pull them in with add_subdirectory. This will ensure GoogleTest is built with the same compiler settings as your main project. You don't get to use the FindGTest module, but you get gtest and gtest_main CMake targets which you can use instead and these are very convenient. For example, they carry dependency information and the platform-specific name of the library, so all you have to do is simply link against the gtest or gtest_main target as needed and CMake will do the rest for you.

If you want to have CMake download the GoogleTest source code for you as part of the CMake configure step, then this article explains how it can be done. It includes a complete example which should show you how to get it working. The approach uses ExternalProject to perform just the download stage by invoking it as a CMake script at configure time instead of delaying the download to build time. This is what allows you to then call add_subdirectory because the source is downloaded immediately and available to later parts of your CMakeLists.txt file. Update: This approach is now also part of the googletest documentation.

Note also that GoogleTest has now been merged with GoogleMock and the canonical repo has moved to github.

-1
votes

If you don't need find_package have you tried using

include(FindGTest)

before using the gtest_add_tests

While here, let me also point to http://smspillaz.wordpress.com/2012/07/05/unit-test-autodiscovery-with-cmake-and-google-test/ which looks like a better solution to GTEST_ADD_TESTS

Disclaimer: i have not tried neither myself.