Search code examples
c++cmakegoogletest

CMake and GTest linking tests


I want build and test a small project of mine with cmake and gtest. In the project I have a function readModel(...) where the definition and implementation is separated. The project builds fine but I get the following linker error for the test of readModel(...)

cd /home/kain88/Desktop/example/build/test && /usr/bin/cmake -E  cmake_link_script CMakeFiles/example_test.dir/link.txt --verbose=1
/usr/bin/c++   -Wall -std=c++14   CMakeFiles/example_test.dir/pdb_test.cpp.o  -o example_test -rdynamic ../ext/gtest-1.7.0/libgtest.a ../ext/gtest-1.7.0/libgtest_main.a ../ext/gtest-1.7.0/libgtest.a -lpthread 
CMakeFiles/example_test.dir/pdb_test.cpp.o: In function `PDB_TEST_readModel_Test::TestBody()':
pdb_test.cpp:(.text+0x13): undefined reference to `readModel(std::string const&)'
collect2: error: ld returned 1 exit status

It seems that cmake is not including the *.o file generated in the src folder for the test. How can I tell cmake that it should include the *.o files from the src folder also for the test?

This is the CMakeLists.txt I use in the test folder.

# enable GTest
enable_testing()
include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}
  ${PROJECT_SOURCE_DIR}/src)

# Unit Test
set(PROJECT_TEST_NAME ${PROJECT_NAME_STR}_test)
file(GLOB TEST_SOURCES "*.cpp")
add_executable(${PROJECT_TEST_NAME} ${TEST_SOURCES})
target_link_libraries(${PROJECT_TEST_NAME} gtest gtest_main)
add_test(test ${PROJECT_TEST_NAME})

A complete striped down example case can be found here


Solution

  • You may create an object library target that compiles the .o object files:

    ADD_LIBRARY(${PROJECT_NAME}_objects OBJECT ${SRC_FILES} ${INCL_FILES})
    

    Use the result of it on both your lib/exe and test:

    ADD_EXECUTABLE(${PROJECT_NAME} $<TARGET_OBJECTS:${PROJECT_NAME}_objects>)
    ADD_EXECUTABLE(${PROJECT_TEST_NAME} ${TEST_SOURCES} $<TARGET_OBJECTS:${PROJECT_NAME}_objects>)
    

    PS: You can use the same trick to compile the objects shared by multiple targets only once, for example, a shared and a static library target.