4

我在我的 Qt 创建器中创建了两个 c++ 项目。第一个是一个Application project,另一个是unit-test project。这两个项目分别工作正常。但是,当将两者联系在一起时,我遇到了一个小问题。

我包括#INCLUDEPATH applicationProjectPath.pro file. unit-test project然后#include myClass从应用项目中main.cppunit-test project. 然后,在该对象中创建一个myObjectfrom并调用一个函数。myClass

编译时出现这个错误:

undefined reference to `myObject::function' 

但是,当添加#SOURCES applicationProjectPath/myClass.cpp到单元测试项目的 .pro 文件时(同时保留#INCLUDEPATH applicationProjectPath),一切正常(即:执行测试单元)

再次#INCLUDEPATH从.pro中删除时,它再次崩溃。

我想如果我包括#SOURCES,那么我不需要包括#INCLUDEPATH. 如果我包含#INCLUDEPATH,我不应该包含#SOURCES(至少不包含完整路径,只是 .cpp 文件,然后编译器应该查找两个目录,默认目录和添加的目录)。

所以,我的问题是:为什么会这样

4

2 回答 2

4

您的单元测试将需要编译您想要单元测试的项目中的类。因此,您需要在两个项目中添加包含(否则测试项目将不知道您要测试的类)。并且链接器也需要链接到项目的代码,因为您的测试将使用这些类。

一种方法是在测试项目中添加要测试的类,并在编译单元测试项目时再次编译它们,但这很乏味而且不是很方便,因为每次要添加类时,都需要添加将它添加到两个 .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

项目.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}

您必须对其进行编辑以匹配您的项目,但主要内容在这里。它应该可以工作,因为我从我的一个项目中复制了它,前提是我没有添加任何错误。

于 2013-06-04T12:55:39.307 回答
2

您应该将您的 cpp 文件包含到项目中,以告诉构建系统(qmake)编译给定的文件。

当您添加myClass.cpp到测试项目时,它会被编译,否则不会。

因此,当您不将 cpp 文件添加到项目中时,您将收到链接器错误。

包含只是单独处理

当您添加新路径时INCLUDEPATH,编译器会将该传递添加到标题搜索列表

当您添加applicationProjectPath到包含路径时,编译器将在那里搜索标头。这很重要,因为它允许编译器找到myClass.h

如果您不将路径添加到标题搜索列表,编译器将无法编译您main.cpp,您将收到编译错误。

但是,您可以myClass.h在测试项目的主目录中指定(相对)路径:

#include "../applicationProjectPath/myClass.h"

加起来

您需要将源文件添加到测试项目并将标题路径添加到测试项目的包含搜索列表。

进一步阅读

什么是未定义的引用/未解决的外部符号错误,我该如何解决?

于 2013-06-04T12:43:33.170 回答