How to start working with GTest and CMake

Chris picture Chris · Dec 14, 2011 · Viewed 121.5k times · Source

I have recently been sold on using CMake for compiling my C++ projects, and would now like to start writing some unit tests for my code. I have decided to use the Google Test utility to help with this, but require some help in getting started.

All day I have been reading various guides and examples include the Primer, an introduction at IBM and some questions on SO (here and here) as well as other sources I've lost track of. I realise there's plenty out there but somehow I am still having difficulties.

I'm currently trying to implement the most basic test, to confirm I've compiled/installed gtest right and it's not working. The only source file (testgtest.cpp) is taken almost exactly from this previous answer:

#include <iostream>

#include "gtest/gtest.h"

TEST(sample_test_case, sample_test)
{
    EXPECT_EQ(1, 1);
}

and my associated CMakeLists.txt is as follows:

cmake_minimum_required(VERSION 2.6)
project(basic_test)

# Setup testing
enable_testing()
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIR})

# Add test cpp file
add_executable(runUnitTests
    testgtest.cpp
)

# Link test executable against gtest & gtest_main
target_link_libraries(runUnitTests ${GTEST_LIBRARY_DEBUG} ${GTEST_MAIN_LIBRARY_DEBUG})

add_test(
    NAME runUnitTests
    COMMAND runUnitTests
)

Note that I have chosen to link against gtest_main instead of providing the main at the end of the cpp file as I believe this will allow me to scale testing up more easily to multiple files.

When building the generated .sln file (in Visual C++ 2010 Express) I unfortunately get a long list of errors of the form

2>msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: virtual __thiscall std::basic_iostream<char,struct std::char_traits<char> >::~basic_iostream<char,struct std::char_traits<char> >(void)" (??1?$basic_iostream@DU?$char_traits@D@std@@@std@@UAE@XZ) already defined in gtestd.lib(gtest-all.obj)

which I think means that I'm not successfully linking to the gtest libraries. I have made sure that when linking against the debug libraries, I have then tried to build in debug mode.

EDIT

Having done some more digging, I think my issue is something to do with the type of library I am building gtest into. When building gtest with CMake, if BUILD_SHARED_LIBS is un-checked, and I link my program against these .lib files I get the errors mentioned above. However, if BUILD_SHARED_LIBS is checked then I produce a set of .lib and .dll files. When now linking against these .lib files the program compiles, but when run complains that it can't find gtest.dll.

What are the differences between a SHARED and a not SHARED library, and if I choose not shared, why doesn't it work? Is there an option in the CMakeLists.txt for my project that I am missing?

Answer

Chris picture Chris · Jan 31, 2014

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 )