0

I'll start by saying that I'm using CMake for the first time, but I've already put hours of research into solving this problem and still didn't succeed. Maybe I'm missing some crucial part about CMake and I would be very happy if someone could point that out to me.

So here is my problem: I have a project with the following structure:

src
-- CMakeLists.txt 
-- main.cpp
-- example.h
-- example.cpp
-- ... (more .h and .cpp files)
-- testdir
   -- CMakeLists.txt
   -- testfile.cpp

I'm building a Qt project in src and want to test it with googletest, the files for testing are in testdir. These are the files:

src/CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(my_project VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Widgets Sql REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets Sql REQUIRED)

enable_testing()

add_subdirectory(testdir)

set(PROJECT_SOURCES
        main.cpp
        example.h
        example.cpp
        ...
)

add_executable(run ${PROJECT_SOURCES})

target_include_directories(run PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(run PUBLIC ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(run PUBLIC
        Qt${QT_VERSION_MAJOR}::Core
        Qt${QT_VERSION_MAJOR}::Widgets
        Qt${QT_VERSION_MAJOR}::Sql
)

src/testdir/CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets Sql REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets Sql REQUIRED)

include(FetchContent)

FetchContent_Declare(
        googletest
        URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

FetchContent_MakeAvailable(googletest)

find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Widgets Sql REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Widgets Sql REQUIRED)

set(TEST_SOURCES
        testfile.cpp
)

add_executable(unittest ${TEST_SOURCES})

target_include_directories(unittest PUBLIC googletest/include)
target_include_directories(unittest PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_include_directories(unittest PUBLIC ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(unittest PUBLIC
        gtest_main
        Qt${QT_VERSION_MAJOR}::Core
        Qt${QT_VERSION_MAJOR}::Widgets
        Qt${QT_VERSION_MAJOR}::Sql
)

include(GoogleTest)

add_test(
        NAME unittest
        COMMAND unittest
)

src/testdir/testfile.cpp

#include "gtest/gtest.h"
#include "../example.h"

TEST(testing, example) {
    int i = get_num();
    EXPECT_EQ(i, 42);
}

My actual code is much more complex, but for demonstrating this let's just assume that get_num() is a function defined in example.h and declared in example.cpp, which returns 42 and is similar to the very simple function I actually have in my code.

Now when I try to build this I get the error message: in function 'testing_example_Test::TestBody()': undefined reference to 'get_num()'

I'm pretty sure that this is a linking error, but I've tried everything I could think of and nothing works. I just don't have a clue how to access the files in src correctly.

I tried to put the files in src into a shared library for testdir to use, but for some reason when I tried to build the actual project with the library (not the tests), it didn't recognize the Qt Headers like or anymore even though I linked them like this:

target_link_libraries(my_library PUBLIC
    Qt${QT_VERSION_MAJOR}::Core
    Qt${QT_VERSION_MAJOR}::Widgets
    Qt${QT_VERSION_MAJOR}::Sql
)

Sorry if I'm just making a really dumb mistake here, but I would be beyond grateful if someone could tell me what I'm doing wrong.

Nia
  • 1
  • 1
  • You cannot test **executable** with googletest: https://stackoverflow.com/questions/23088252/how-to-test-an-exe-with-google-test. Approach with moving tested sources into the library should work, assuming you correctly link the executable with that library (`target_link_libraries(run PUBLIC my_library)`). If you think that you correctly links with that library, but still get errors, then edit the question post to contain all code for that case. – Tsyvarev Jun 05 '23 at 10:18

0 Answers0