Reputation: 1491
I am creating two c++ projects in my Qt creator. The first is an Application project
and the other is unit-test project
. the two projects, separately, work fine. However, when linking the two together I face a little problem.
I am including #INCLUDEPATH applicationProjectPath
in .pro file
in the unit-test project
. then #include myClass
from the application project in the main.cpp
of the unit-test project
. then, creating a myObject
from myClass
and calling a function within that object.
when compiling, this error appears:
undefined reference to `myObject::function'
however, when adding #SOURCES applicationProjectPath/myClass.cpp
to the .pro file of the unit-test project (while keeping the #INCLUDEPATH applicationProjectPath
), everything is working (i.e.: the test units are executed)
again when removing the #INCLUDEPATH
from the .pro, it again crashes .
I thought if I included #SOURCES
, then I don't need to include the #INCLUDEPATH
. and if I included the #INCLUDEPATH
, I should not include #SOURCES
(at least not with the full path, just the .cpp file and then the compiler should look for both directories, the default one and the added one).
so, my question is: why is this happening
Upvotes: 6
Views: 47283
Reputation: 1
Sometimes Qt displays this error when you are using inline
in a wrong way, so check your inline
'd functions.
Upvotes: 0
Reputation: 1426
Your unit tests will need to compile the classes in your project that you want to unit-test. So you need to add the include in both project (otherwise the test project will not know the classes you are trying to test). And the linker needs to link to the project's code as well, as your tests will use the classes.
One way is to add the classes you want to test in your test project as well and compile them again when you compile your unit test project but this is tedious and not really handy as every time you want to add a class, you need to add it to both .pro files (hint, you can use wildcards in the .pro files, like *.cpp to add all source files in a folder to a project).
A better approach in my opinion is to setup the project you want to test as a static library, separating it from the application: you have another project which is an application, containing only the main.cpp
linking to that static library.
Here is a representation of the folder containing the project:
Project.pro #subdir project
UIProject/ #static lib
UIProject.pro
#all your classes here
MainProject/ #application
MainProject.pro
main.cpp
UITestProject/ #unit tests of UIProject (linking to it)
UITestProject.pro
#all your UI test classes here
Project.pro:
TEMPLATE = subdirs
SUBDIRS += UIProject
SUBDIRS += MainProject
SUBDIRS += UITestProject
UIProject.pro:
# project type
TEMPLATE = lib
# library type
CONFIG += staticlib
HEADERS += *.h
SOURCES += *.cpp
MainProject.pro:
#[...]
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += ../UIProject/
DEPENDPATH += $${INCLUDEPATH} # force rebuild if the headers change
# link against UILib
_UI_LIB = ../UIProject/
CONFIG(debug, debug|release) {
win32: _UI_LIB = $$join(_UI_LIB,,,debug/UIProject.lib)
} else {
win32: _UI_LIB = $$join(_UI_LIB,,,release/UIProject.lib)
}
LIBS += $${_UI_LIB}
PRE_TARGETDEPS += $${_UI_LIB}
UITestProject.pro:
#[...]
TEMPLATE = app
HEADERS += *.h
SOURCES += *.cpp
INCLUDEPATH += ../UIProject/
DEPENDPATH += $${INCLUDEPATH} # force rebuild if the headers change
# link against UILib
_UI_LIB = ../UIProject/
CONFIG(debug, debug|release) {
win32: _UI_LIB = $$join(_UI_LIB,,,debug/UIProject.lib)
} else {
win32: _UI_LIB = $$join(_UI_LIB,,,release/UIProject.lib)
}
LIBS += $${_UI_LIB}
PRE_TARGETDEPS += $${_UI_LIB}
You would have to edit that to match your project but the main things are here. It should work as I copied it from one of my project, providing I didn't add any errors.
Upvotes: 4
Reputation: 12547
you should include your cpp file to the project to tell build system (qmake) to compile the given file.
When you add
myClass.cpp
to test project, it gets compiled, otherwise does not.
So, when you will not add cpp file to the project, you'll get linker error.
When you add new path to INCLUDEPATH
, compiler will add that pass to headers search list
When you add
applicationProjectPath
to the include path, compiler will search headers there. It is important, as allows compiler to findmyClass.h
If you will not add path to headers search list, compiler will not be able to compile your main.cpp
and you'll get compilation error.
You, however, can just specify (relative) path to your myClass.h
in your test-project's main:
#include "../applicationProjectPath/myClass.h"
You need add your source files to test project and add your headers path to test project's include search list.
What is an undefined reference/unresolved external symbol error and how do I fix it?
Upvotes: 2