8

I have a rather large application I need to build/maintain so I decided to use googletest and for convenience wanted to structure the test and the application code as subprojects. I created a superproject with the following structure:

SuperProject
- SuperProject.pro
- defaults.pri
- Application
  -- Application.pro
  -- Sources
  -- main.cpp
  -- Headers
- Tests
  -- Tests.pro
  -- main.cpp
  -- Sources
  -- Headers

With superproject.pro

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
    Application \
    Tests \
OTHER_FILES += \
    defaults.pri

With defaults.pri

INCLUDEPATH += $$PWD/Application

And Tests.pro

include(gtest_dependency.pri)
include(../defaults.pri)

TEMPLATE = app
QT += core
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG += thread

HEADERS +=     tst_redoundo.h
SOURCES +=     main.cpp

And Application.pro

include(ExcelLib/qtxlsx.pri)
include(../defaults.pri)

TEMPLATE = app
QT += qml quick

CONFIG += c++14

static { # everything below takes effect with CONFIG ''= static
 CONFIG+= static
 CONFIG += staticlib # this is needed if you create a static library, not a static executable
 DEFINES+= STATIC
 message("~~~ static build ~~~") # this is for information, that the static build is done
 win32: TARGET = $$join(TARGET,,,s) #this adds an s in the end, so you can seperate static build from

}

RC_ICONS += msiconbmp.ico


SOURCES += ..omitted

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES += *.pri

HEADERS += ..omitted

:w

Application compiles and runs fine by its own, so does the test code. But as soon as I try to include anything from Application like so

#include "util.h"
#include "tst_redoundo.h"
#include <gtest/gtest.h>

int main(int argc, char *argv[])
{

    Util u;
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

The code compiles but won't link with undefined reference to Util constructor. Most of the guides with the same setup as mine assumes that the template of what the test code links against is TEMPLATE = lib but I cannot change the template from app to lib for Application. How do I get the linker to link against Application?

arynaq
  • 6,710
  • 9
  • 44
  • 74
  • I don't know how to do it with qmake. But the solution is to divide your application into a library and a executable with the regular main. Then you can link the normal executable and the test executable against the library. In this [post](https://stackoverflow.com/questions/41883841/confusion-about-unit-tests-googletest-and-projects-folder-files/41939662#41939662) I wrote down a possible solution with cmake. – Soeren Jun 01 '17 at 11:58
  • @Soeren Hoping to dear life I can avoid that :D that will be my last resort, a lot of extra work. – arynaq Jun 01 '17 at 12:00
  • @arynaq if you include "util.h" you can add the "util.cpp" to the Test project source files to make the linker happy. Are their any reasons preventing it? – Mikhail Churbanov Jun 05 '17 at 12:53
  • Yeah qmake fails to find util.cpp when it runs the Test folder .pro file, – arynaq Jun 07 '17 at 20:22

2 Answers2

5

First thing, I can't see anywhere that you linked the gtest library in your test subproject. The command to add is LIBS += -lgtest

More generally, you have only two options. Either you compile your main project as a lib that you then link to your testing subproject, or you have to include in the testing all of your .cpp files. In any case, since it's a separate project, your testing project has no knowledge of your other (sub)projects.

I hope this will point you towards the right answer

David LUC
  • 335
  • 1
  • 5
  • The gtest library is compiled and linked with the test project with the include(gtest_dependency.pri) – arynaq Jun 09 '17 at 11:25
  • @arynaq If you do not want/can compile your app as a library, you really don't have a choice: your sources are to be (re-)included in the testing subproject. Which is no problem, if you include the same files as in your main application, and not copies of those files. So include `util.cpp` and everything else you're testing – David LUC Jun 09 '17 at 11:50
0

I arrived at a solution doing what David LUC suggested below, his answer is incomplete but he will still have the bounty from me.

What I ended up doing was including every .cpp file in the sources of Tests.pro, eg "../Application/util.cpp". This means that I essentially build the application twice, once as the application, and again when when the Test project is compiled, object files of the same .cpp are in two different projects. Not beautiful, and time consuming, but it works.

Would still like to avoid having duplicate object files.

arynaq
  • 6,710
  • 9
  • 44
  • 74