0

I want to use Google C++ Testing and I am completely beginner to cmake and gtest.

I have a class called Filter which uses a 3d party library called jane.

For this case I have a cmakeFile which builds my project nicely as follows:

cmake_minimum_required(VERSION 3.1.2)
project(Filter)
include(../../../cmake/CMakeMacros.txt)
set_variables()
#add 3rdparty libraries
add_jane()
#add framework libraries
add_framework_libs(
ip/Image
)
include_directories(
../include
${FW_INCLUDE_DIRS}
)

#set project's source and include files
set(INCS
../include/${PROJECT_NAME}.h
../include/${PROJECT_NAME}.tpp
../include/FilterMask.h
)

set(SRCS
../src/${PROJECT_NAME}.cpp
../src/FilterMask.cpp
)

#set link directories
link_directories(
${FW_LIBRARY_DIRS}
)

#build project as static library (*.lib)
add_library(${PROJECT_NAME} STATIC
${INCS}
${SRCS}
)
#link libraries against project
target_link_libraries( ${PROJECT_NAME}
${FW_LIBRARIES}
)

#if a test executable should be build
if(Test_BUILD_EXAMPLES)
#build test executable
add_executable(${PROJECT_NAME}Test
    ../src/main.cpp
)
#link library against executable
target_link_libraries(${PROJECT_NAME}Test
    ${PROJECT_NAME}
)
endif(Test_BUILD_EXAMPLES)

and also I have read this simple tutorial on https://github.com/snikulov/google-test-examples with this cmake file https://github.com/snikulov/google-test-examples/blob/master/CMakeLists.txt and tried to build my project again to combine these cmake files together (may be in very silly way) but I can not achieve it since days.

The problem is that when I want to test a simple project with just a header file I can use this cmake file but as soon as I try to test my project containing a 3rd party library I run into different errors.

Can someone please tell me how I can edit a correct cmake file to test my project with googleTest using a cmake file !?

  • You may want to check out [this answer](http://stackoverflow.com/a/31622855/1938798) for an alternative way of bringing in gtest to your build rather than the method in that tutorial. The article that answer links through to also has an associated project on github with a fully working example. As to your linking problem, if you showed the actual errors you get, that would allow a more specific diagnosis of your underlying problem. It's also pretty weird that your project seems to be pulling in all its sources, etc. from directories outside of the project. – Craig Scott Jul 02 '16 at 22:49

1 Answers1

1

If you want to link against a 3rd party library you typically first:

  1. find_package() or use the pkg config support to check the library is available on the build host and pick up a reference to it.
  2. Include the reference from step #1 in target_link_libraries()

So that's what you need to do for your 3rd party lib. For your own code which you want to bring under test you probably want to put it all inside your own libraries and then link your tests against those.

If you have multiple test executables to separate & isolate each test suite into its own binaries you probably want an alternative technique to avoid over linking and limit the code inside the test suite to the actual unit under test. (This is also quite useful when your code base is in flux and builds only partially but you still wish to check that what builds continues to pass relevant tests.)

In that case you may want to define your units under test as OBJECT type libraries and then instead of doing target_link_libraries() against those object libs you include the objects as part of the sources for the executable using this syntax: $<TARGET_OBJECTS:NameOfObjLibHere> (cmake generator expressions).

So in the case of units which depend on a 3rd party lib, say, Qt5 Core, you'd have snippets like this:

# define the dependency on 3rd party project Qt5, (sub)component: Core, Test)
set(MY_QT_VERSION "5.4.0")
find_package(Qt5 ${MY_QT_VERSION} REQUIRED COMPONENTS Core CONFIG)

# define the object lib for a unit to be tested (Item1)
set(item1_srcs item1.cpp util1.cpp)
add_library(Item1 TYPE OBJECT ${item1_srcs})

# ensure that necessary compiler flags are passed 
# when building "Item1" separately
# note that PRIVATE may also be INTERFACE or PUBLIC
# read the cmake docs on target_include_*** to determine which applies.
# you probably want to hide this behind a convenience macro.
target_include_directories(Item1 PRIVATE $<TARGET_PROPERTY:Qt5::Core,INTERFACE_INCLUDE_DIRECTORIES>)
target_compile_options(Item1 PRIVATE $<TARGET_PROPERTY:Qt5::Core,INTERFACE_COMPILE_OPTIONS>)

# find the unit testing framework (dependency)
# this sample uses Qt5 Test (Qt5::Test) but you could use GTest, too
find_package(Qt5 ${MY_QT_VERSION} REQUIRED COMPONENTS Test CONFIG)

# define an executable which contains test sources + unit under test
# link against the testing framework (obviously) as per normal
# note the Qt5::Core dependency here: remember Item1 depends on Qt5::Core (!)
set(test_item1_srcs, test_item1.cpp $<TARGET_OBJECTS:Item1>)
add_executable(test_item1 ${test_item1_srcs)
target_link_libraries(test_item1 Qt5::Core Qt5::Test)

# inform cmake/ctest integration about our test
# so it knows to execute it during `make test` phase.
# and other cmake/ctest integration falls into place as well, possibly
add_test(test_item1 test_item1)
user268396
  • 11,576
  • 2
  • 31
  • 26