【问题标题】:Qt creator: c++: undefined reference to Class::FunctionQt 创建者:c++:对 Class::Function 的未定义引用
【发布时间】:2013-06-04 12:20:09
【问题描述】:

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

我在.pro file 中包含#INCLUDEPATH applicationProjectPathunit-test project 中。然后#include myClass 来自unit-test projectmain.cpp 中的应用程序项目。然后,从myClass 创建一个myObject 并在该对象中调用一个函数。

编译时出现这个错误:

undefined reference to `myObject::function' 

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

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

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

所以,我的问题是:为什么会发生这种情况

【问题讨论】:

  • 抱歉,当您从 *.pro 中删除 #INCLUDEPATH 时,您的程序会崩溃,或者您会像以前一样遇到编译错误? undefined reference to ...

标签: c++ qt unit-testing qt-creator include-path


【解决方案1】:

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

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

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

【讨论】:

  • >我认为更好的方法是将要测试的项目设置为静态库。这正是我正在寻找的答案。所以你的意思是:将我的应用程序项目作为库添加到单元测试项目中,而不是添加它的路径和源/头文件。但我现在的问题是如何将我的应用程序项目添加为库(抱歉,无法理解您的代码).. 但非常感谢您的解释。
  • 这不是代码,而是磁盘上文件夹的表示,有些 cmets 以 # 开头。我会尝试编辑我的帖子以便更容易理解
  • 如果您需要更多解释,请告诉我,我会添加更多内容
  • 谢谢..你提到:(链接器也需要链接到项目的代码,因为你的测试将使用这些类。)你的意思是包括(路径)和(类) ) 在 (Application-project) 的 (.pro 文件) 中的 (unit-test project)。但是由于我已经指定了(应用程序项目类),我需要在我的(单元测试项目)的(.pro 文件)中进行测试,并且单元测试正在工作,你真的认为添加(单元测试项目) ) 到(.pro 文件) 的(Application project) 有必要吗? (已经问过了,我还是要添加库)
  • 我不确定你的意思,但链接到库将解决这个问题,而无需添加任何其他内容。所有需要的对象都将包含在库中。如果您使用我在上面的回答中编写的代码(以“更好的方法”开头),您将拥有一个全局项目文件“Project.pro”,其中包含无源代码,仅告诉 qmake编译子目录。 UIProject 将是一个静态库,供 MainProject 和 UITestProject 使用。最后两个项目是完全分开的,唯一的共同点是它们都使用 UIProject。
【解决方案2】:

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

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

所以,当你不添加 cpp 文件到项目中时,你会得到 linker 错误。

包含只是单独处理

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

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

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

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

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

总结

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

进一步阅读

What is an undefined reference/unresolved external symbol error and how do I fix it?

【讨论】:

  • 感谢您的回答..感谢您提供的链接,因为它为我提供了我想更详细地了解编译过程的内容..
  • 我明白了。因此,将applicationProjectPath 添加到INCLUDEPATH 会使编译器知道标头。然后您还需要将所有与项目相关的.cpp 添加到SOURCES 变量中。 IE。您无需将 .h 添加到 HEADERS
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多