Search code examples
c++cmakegoogletest

CMake Error: Unable to find package GTest


I am developing a C/C++ app using CMake. I want to use GTest in my project for unit testing. For this I have decided to use GTest as a git submodule in my repository.

My directory hierarchy is as follows:

/
--include
--lib
  --GoogleTest
--src
--Tests

The GoogleTest subdirectory in lib contains the source code of GTest from their official repository.

But I am unable to use it to test my source. The CMakeLists.txt file at the root of my repository is as follows:

OPTION (BUILD_UNIT_TESTS "Build unit tests" ON)

if (BUILD_UNIT_TESTS)
    enable_testing ()
    find_package (GTest REQUIRED)
    add_subdirectory (Tests)
endif ()

But I receive the error:

Error:Could NOT find GTest (missing: GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY)

When I searched for this, there were many questions similar to mine, but none of them addressed my problem. And their manual is very limited and does not tell much about its usage properly.

CMake is successfully able to build the target GTest but fails to recognise it when I try to use it as an external package.


Solution

  • You don't have to manually download the Gtest git. Just add the following lines to your CMakeLists.txt

    # -------- GOOGLE TEST ----------
    # Download and unpack googletest at configure time
    configure_file(CMakeLists.txt.in googletest-download/CMakeLists.txt)
    execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
            RESULT_VARIABLE result
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
    if(result)
        message(FATAL_ERROR "CMake step for googletest failed: ${result}")
    endif()
    execute_process(COMMAND ${CMAKE_COMMAND} --build .
            RESULT_VARIABLE result
            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/googletest-download )
    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)
    
    # Add googletest directly to our build. This defines
    # the gtest and gtest_main targets.
    add_subdirectory(${CMAKE_CURRENT_BINARY_DIR}/googletest-src
            ${CMAKE_CURRENT_BINARY_DIR}/googletest-build
            EXCLUDE_FROM_ALL)
    
    # The gtest/gtest_main targets carry header search path
    # dependencies automatically when using CMake 2.8.11 or
    # later. Otherwise we have to add them here ourselves.
    if (CMAKE_VERSION VERSION_LESS 2.8.11)
        include_directories("${gtest_SOURCE_DIR}/include")
    endif()
    # -------------------------------------------------------------------------
    enable_testing()
    include_directories("${gtest_SOURCE_DIR}/include")
    

    And add the following lines to another file, named CMakeLists.txt.in, in the same directory your CMakeLists.txt file is

    cmake_minimum_required(VERSION 2.8.2)
    
    project(googletest-download NONE)
    
    include(ExternalProject)
    ExternalProject_Add(googletest
            GIT_REPOSITORY    https://github.com/google/googletest.git
            GIT_TAG           release-1.10.0
            SOURCE_DIR        "${CMAKE_CURRENT_BINARY_DIR}/googletest-src"
            BINARY_DIR        "${CMAKE_CURRENT_BINARY_DIR}/googletest-build"
            CONFIGURE_COMMAND ""
            BUILD_COMMAND     ""
            INSTALL_COMMAND   ""
            TEST_COMMAND      ""
            )
    

    What does it do ?

    The things you added to your main CMakeLists will download GTest and GMock git projects at the version specified in the CMakeLists.txt.in file. Then it will build these, and include the build path in your main project.

    Source : GoogleTest Git