我在Qt creator中创建了两个c++项目。一个是Application project
,另一个是unit-test project
。这两个项目单独运行良好。然而,当将两者联系在一起时,我遇到了一个小问题。
我在unit-test project
中包括.pro file
中的#INCLUDEPATH applicationProjectPath
。然后是unit-test project
的main.cpp
中的应用项目#include myClass
。然后,从myClass
创建myObject
,并在该对象中调用一个函数。
编译时,出现以下错误:
undefined reference to `myObject::function'
然而,当将#SOURCES applicationProjectPath/myClass.cpp
添加到单元测试项目的.pro文件时(同时保留#INCLUDEPATH applicationProjectPath
),一切都在工作(即:测试单元被执行)
#INCLUDEPATH
时,它再次崩溃。
我想如果我包括#SOURCES
,那么我不需要包括#INCLUDEPATH
。如果我包括#INCLUDEPATH
,我不应该包括#SOURCES
(至少不是完整路径,只是.cpp文件,然后编译器应该寻找两个目录,默认的一个和添加的一个)。
那么,我的问题是:为什么会发生这种情况
您的单元测试将需要编译您想要进行单元测试的项目中的类。因此,您需要在两个项目中都添加include(否则测试项目将不知道您要测试的类)。并且链接器还需要链接到项目的代码,因为您的测试将使用这些类。
一种方法是在你的测试项目中添加你想要测试的类,并在你编译单元测试项目时再次编译它们,但这很繁琐,而且不太方便,因为每次你想要添加一个类时,你都需要将它添加到两个。pro文件中(提示,你可以在。pro文件中使用通配符,如*.cpp将文件夹中的所有源文件添加到项目中)。
在我看来,一个更好的方法是将你想要测试的项目设置为一个静态库,将它与应用程序分开:你有另一个项目,它是一个应用程序,只包含链接到该静态库的main.cpp
。
下面是包含项目的文件夹的表示:
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}
你必须编辑它来匹配你的项目,但主要的东西在这里。它应该工作,因为我从我的一个项目复制它,提供我没有添加任何错误。
您应该将您的CPP文件包含到项目中,以告诉构建系统(qmake)编译给定的文件。
当您将
myClass.cpp
添加到测试项目时,它会被编译,否则不会。
所以,当你不添加cpp文件到项目中,你会得到链接器错误。
include只是单独处理
当你添加INCLUDEPATH
的新路径时,编译器会将该路径添加到头文件搜索列表
当你将
applicationProjectPath
添加到include路径时,编译器将在那里搜索头文件。这很重要,因为它允许编译器找到myClass.h
如果你不添加路径到头搜索列表,编译器将无法编译你的main.cpp
,你会得到编译错误。
但是,您可以在测试项目的主目录中指定myClass.h
的(相对)路径:
#include "../applicationProjectPath/myClass.h"
总结你需要添加你的源文件到测试项目和添加你的头路径到测试项目的包含搜索列表
进一步阅读
什么是未定义的引用/未解析的外部符号错误,我如何修复它?
当您以错误的方式使用inline
时,有时Qt会显示此错误,因此请检查您的inline
'd功能。