Qt 创建者:c:对 Class::Function 的未定义引用

新手上路,请多包涵

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

我包括 #INCLUDEPATH applicationProjectPath.pro fileunit-test project 。然后 #include myClass 来自 main.cppunit-test project 的应用程序项目。然后,从 myClass 创建一个 myObject --- 并在该对象中调用一个函数。

编译时出现这个错误:

 undefined reference to `myObject::function'

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

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

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

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

原文由 hashDefine 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 653
2 个回答

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

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

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

原文由 Uflex 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

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

包含只是单独处理

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

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

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

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

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

加起来

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

进一步阅读

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

原文由 Lol4t0 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题