QT Subdir - 未定义的参考

Posted

技术标签:

【中文标题】QT Subdir - 未定义的参考【英文标题】:QT Subdir - Undefined Reference 【发布时间】:2018-12-03 10:52:31 【问题描述】:

我正在开发一个带有子目录的 QT 项目,它在 linux (ubuntu) 上运行良好,但是当我尝试在 Windows 上运行时,我得到 对 `moduleInterface::...´ 的未定义引用其中 ... 指的是我的子目录上的所有方法。我使用的Qt版本(5.11.2)在linux和windows中都是一样的。子目录配置如下:

main.pro

TEMPLATE = subdirs

SUBDIRS += \
         tests \
         coreSerialTerm \
         serialTermView

serialTermView.depends = coreSerialTerm
tests.depends = coreSerialTerm

coreSerialTerm.pro

QT       -= gui
QT       += serialport
QT       += core
CONFIG   += c++14
TARGET = coreSerialTerm
TEMPLATE = lib

DEFINES += CORESERIALTERM_LIBRARY

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs. 
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version     of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs   deprecated before Qt 6.0.0

SOURCES += \
         coreserialterm.cpp \
         serialInterface/serialinterface.cpp \
         moduleInterface/moduleinterface.cpp \
         serialProtocol/serialProtocol.c \
         moduleInterface/progressbar.cpp \
         agroflashinterface.cpp \
         Storage/event_list.c \
         Storage/storage.c \
         flashfilehandler.cpp

HEADERS += \
    coreserialterm.h \
    coreserialterm_global.h \ 
   serialInterface/serialinterface.h \
moduleInterface/moduleinterface.h \
serialProtocol/serialProtocol.h \
devRetCode.h \
moduleInterface/progressbar.h \
Sensors/sensor.h \
Storage/storage.h \
Utils/configManager.h \
Utils/configStates.h \
Utils/delayPlus.h \
Utils/io.h \
Utils/rtcManager.h \
Utils/wdg.h \
version.h \
module.h \
flashfilehandler.h

serialTermView.pro

QT       += core gui
QT       += serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = serialTermView
TEMPLATE = app
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the 
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs. 
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

CONFIG += c++11

SOURCES += \
       main.cpp \
       mainwindow.cpp

HEADERS += \
       mainwindow.h

FORMS += \
       mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$$TARGET/bin
else: unix:!android: target.path = /opt/$$TARGET/bin
!isEmpty(target.path): INSTALLS += target

win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../coreSerialTerm/release/ -lcoreSerialTerm
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../coreSerialTerm/debug/ -lcoreSerialTerm
else:unix: LIBS += -L$$OUT_PWD/../coreSerialTerm/ -lcoreSerialTerm

INCLUDEPATH += $$PWD/../coreSerialTerm
DEPENDPATH += $$PWD/../coreSerialTerm

当我编译时,我得到以下错误:

debug/mainwindow.o: In function `ZN10MainWindowC2EP7QWidget':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:13: undefined reference to `flashFileHandler::flashFileHandler()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:18: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:18: undefined reference to `moduleInterface::availablePorts()'
debug/mainwindow.o: In function `operator()':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:58: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:58: undefined reference to `moduleInterface::connect(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:65: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:65: undefined reference to `moduleInterface::close()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:106: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:106: undefined reference to `moduleInterface::getTime(unsigned int*)'
debug/mainwindow.o: In function `ZN10MainWindow7getTimeEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:98: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:98: undefined reference to `moduleInterface::isConnected()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:138: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:138: undefined reference to `moduleInterface::close()'
debug/mainwindow.o: In function `operator()':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:163: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:163: undefined reference to `moduleInterface::setTime()'
debug/mainwindow.o: In function `ZN10MainWindow7setTimeEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:148: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:148: undefined reference to `moduleInterface::isConnected()'
debug/mainwindow.o: In function `operator()':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:229: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:229: undefined reference to `moduleInterface::memoryDump(unsigned char*, unsigned int)'
debug/mainwindow.o: In function `ZN10MainWindow7memDumpEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:210: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:210: undefined reference to `moduleInterface::isConnected()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:226: undefined reference to `moduleInterface::pageChanged(int)'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:223: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:261: undefined reference to `moduleInterface::Instance()'
debug/mainwindow.o: In function `ZN10MainWindow6saveAsEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:279: undefined reference to `flashFileHandler::open(QString)'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:281: undefined reference to `flashFileHandler::save(QString)'
debug/mainwindow.o: In function `ZN10MainWindow4saveEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:288: undefined reference to `flashFileHandler::isReady()'
debug/mainwindow.o: In function `ZN10MainWindow9closePortEv':
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:297: undefined reference to `moduleInterface::Instance()'
C:\Users\Augusto\Documents\Workspace\serialTerm\build-serialTerm-Desktop_Qt_5_11_2_MinGW_32bit-Debug\serialTermView/../../serialTerm/serialTermView/mainwindow.cpp:297: undefined reference to `moduleInterface::close()'
debug/mainwindow.o: In function `connect<void (moduleInterface::*)(int), MainWindow::memDump()::<lambda(int)> >':
C:/Qt/5.11.2/mingw53_32/include/QtCore/qobject.h:333: undefined reference to `moduleInterface::staticMetaObject'
collect2.exe: error: ld returned 1 exit status

【问题讨论】:

【参考方案1】:

这看起来像是一个编译顺序问题。可能链接器找不到某些符号,因为它们属于其他子项目之一,但尚未处理它们。

尝试如下更改您的 subdirs .pro 文件:

TEMPLATE = subdirs

CONFIG += ordered

SUBDIRS += \             
         coreSerialTerm \
         tests \
         serialTermView

.depends 属性在 Windows 上从来没有真正为我工作过。

【讨论】:

成功了!我以前应该看过这个,我试图在实际库之前编译测试套件。非常感谢! 绝对不推荐使用“ordered”。使用 make -j8 仍然会导致每个模块都按顺序构建。您必须使用“依赖”属性。例如:tests.depends = coreSerialTerm。删除有序标志。 正如@Frederik De Ruyck 指出的那样,您的子项目将按顺序编译,但如果您使用 -jX 选项,则可以并行处理其中的每个翻译单元。是否推荐,这取决于您的具体需求。这里的问题是 Windows 上的 qmake 实现存在部分缺陷:据我所知,ordered 选项有效,而depends 无效,因此该解决方案可能不是最佳的,但它具有真正的跨平台支持。

以上是关于QT Subdir - 未定义的参考的主要内容,如果未能解决你的问题,请参考以下文章

为啥在将 liblas 链接到 Qt 后出现未定义的参考错误?

包含源中的 Qt 未定义参考

Qt libao 未定义参考

qt.webChannelTransport 在 QWebEngineView 中未定义

Qt + cocoa:架构 x86_64 的未定义符号

使用 CMake 使用 Network 构建 Qt 项目会导致未定义的引用