Solved Undefined reference, altough references in library exists
-
Hello,
i have some strange reoccouring linker error which i can't track down. The last time i had this error it somehow disappeared after deleting the *.pro.user file, but this time, it just keeps reappearing.
My subdirs pro file:
TEMPLATE = subdirs common.subdir = src/common common.target = sub-src-common atctrl.subdir = src/atctrl atctrl.target = sub-src-atctrl atctrl.depends = common app.subdir = src/app app.target = sub-src-app app.depends = common atctrl SUBDIRS = common atctrl app
The pro file for the app project:
QT += quick CONFIG += c++17 static DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 DEFINES += QT_MESSAGELOGCONTEXT QT += serialport INCLUDEPATH += $$PWD/src SOURCES += \ src/main.cpp #HEADERS += TARGET = app # common win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../common/release/ -lcommon else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../common/debug/ -lcommon else:unix:!macx: LIBS += -L$$OUT_PWD/../common/ -lcommon INCLUDEPATH += $$PWD/../common DEPENDPATH += $$PWD/../common win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/release/libcommon.a else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/debug/libcommon.a else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/release/common.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/debug/common.lib else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../common/libcommon.a # atctrl win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../atctrl/release/ -latctrl else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../atctrl/debug/ -latctrl else:unix:!macx: LIBS += -L$$OUT_PWD/../atctrl/ -latctrl INCLUDEPATH += $$PWD/../atctrl DEPENDPATH += $$PWD/../atctrl win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../atctrl/release/libatctrl.a else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../atctrl/debug/libatctrl.a else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../atctrl/release/atctrl.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../atctrl/debug/atctrl.lib else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../atctrl/libatctrl.a
The pro file for the atctrl library:
QT -= gui TEMPLATE = lib CONFIG += c++17 staticlib DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 DEFINES += QT_MESSAGELOGCONTEXT SOURCES += \ atctrl/atctrl.cpp HEADERS += \ atctrl/atctrl.h QT += serialport # common win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../common/release/ -lcommon else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../common/debug/ -lcommon else:unix:!macx: LIBS += -L$$OUT_PWD/../common/ -lcommon INCLUDEPATH += $$PWD/../common DEPENDPATH += $$PWD/../common win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/release/libcommon.a else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/debug/libcommon.a else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/release/common.lib else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../common/debug/common.lib else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../common/libcommon.a
The pro file for the common library:
QT -= gui TEMPLATE = lib CONFIG += c++17 staticlib DEFINES += QT_DEPRECATED_WARNINGS DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 DEFINES += QT_MESSAGELOGCONTEXT SOURCES += \ common/serial_base/serial_base.cpp HEADERS += \ common/serial_base/serial_base.h QT += serialport !isEmpty(target.path): INSTALLS += target
In the atctrl library there is the class ATCtrl::cATCtrl which derives from SerialBase::cSerialBase from the common library.
In the app project i'm using the ATCtrl::cATCtrl class. So the dependency goes like app (project) -> atrctrl (staticlib) -> common (staticlib).
When i'm building the app project, i get this linker error:
The complete error log:
<build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::~cATCtrl()': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.h:42: undefined reference to `SerialBase::cSerialBase::~cSerialBase()' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::cATCtrl(QObject*)': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:48: undefined reference to `SerialBase::cSerialBase::cSerialBase(QObject*)' <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:48: undefined reference to `SerialBase::cSerialBase::~cSerialBase()' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::init(QString)': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:64: undefined reference to `SerialBase::cSerialBase::open(QString)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::disableLocalEcho()': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:132: undefined reference to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::AT()': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:148: undefined reference to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::enableGPS(bool)': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:164: undefined reference to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::resetGPS(int)': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:182: undefined reference to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o): In function `ATCtrl::cATCtrl::getGPSStatus(int)': <build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:199: undefined reference to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' <build_debug>/src/atctrl/debug/libatctrl.a(atctrl.o):<build_debug>\src\atctrl/../../../keyboard/src/atctrl/atctrl/atctrl.cpp:217: more undefined references to `SerialBase::cSerialBase::handleRequest(QString const&, QString const&, QStringList&)' follow <build_debug>/src/atctrl/debug/libatctrl.a(moc_atctrl.o): In function `ATCtrl::cATCtrl::qt_metacast(char const*)': <build_debug>\src\atctrl/debug/moc_atctrl.cpp:221: undefined reference to `SerialBase::cSerialBase::qt_metacast(char const*)' <build_debug>/src/atctrl/debug/libatctrl.a(moc_atctrl.o): In function `ATCtrl::cATCtrl::qt_metacall(QMetaObject::Call, int, void**)': <build_debug>\src\atctrl/debug/moc_atctrl.cpp:226: undefined reference to `SerialBase::cSerialBase::qt_metacall(QMetaObject::Call, int, void**)' <build_debug>/src/atctrl/debug/libatctrl.a(moc_atctrl.o):moc_atctrl.cpp:(.rdata+0x620): undefined reference to `SerialBase::cSerialBase::staticMetaObject'
The linker command which fails is the following (i replaced the build dir with <build_debug>):
g++ -Wl,-subsystem,windows -mthreads -o debug/app.exe debug/main.o debug/backend.o debug/moc_backend.o -L"<build_debug>/src/common/debug" -lcommon -L"<build_debug>/src/atctrl/debug" -latctrl D:/Qt/5.14.2/mingw73_64/lib/libQt5Quick.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Gui.a D:/Qt/5.14.2/mingw73_64/lib/libQt5QmlModels.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Qml.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Network.a D:/Qt/5.14.2/mingw73_64/lib/libQt5SerialPort.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Core.a -lmingw32 D:/Qt/5.14.2/mingw73_64/lib/libqtmain.a -LC:/openssl/lib -LC:/Utils/my_sql/mysql-5.7.25-winx64/lib -LC:/Utils/postgresql/pgsql/lib -lshell32
The two static libraries are included (-lcommon -latctrl) in the linker command.
Now when i'm looking into libcommon.a with nm (nm -A -C libcommon.a), i can find all the references which the linker says it is not finding it:
<...> libcommon.a:serial_base.o:000000000000014c T SerialBase::cSerialBase::open(QString) libcommon.a:serial_base.o:0000000000000f16 T SerialBase::cSerialBase::close() <...> libcommon.a:serial_base.o:0000000000000088 T SerialBase::cSerialBase::cSerialBase(QObject*) libcommon.a:serial_base.o:0000000000000088 T SerialBase::cSerialBase::cSerialBase(QObject*) libcommon.a:serial_base.o:000000000000005e T SerialBase::cSerialBase::~cSerialBase() libcommon.a:serial_base.o:0000000000000000 T SerialBase::cSerialBase::~cSerialBase() libcommon.a:serial_base.o:0000000000000000 T SerialBase::cSerialBase::~cSerialBase()
What am i missing?
Qt Creator Version 4.12.0
Qt 5.14.2 (mingw730_64)I appreciate any help here, thanks.
Best regards,
Kevin -
The link order is wrong,
-lactrl
must come first,s ee also e.g. here -
@kkettinger said in Undefined reference, altough references in library exists:
g++ -Wl,-subsystem,windows -mthreads -o debug/app.exe debug/main.o debug/backend.o debug/moc_backend.o -L"<build_debug>/src/common/debug" -lcommon -L"<build_debug>/src/atctrl/debug" -latctrl D:/Qt/5.14.2/mingw73_64/lib/libQt5Quick.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Gui.a D:/Qt/5.14.2/mingw73_64/lib/libQt5QmlModels.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Qml.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Network.a D:/Qt/5.14.2/mingw73_64/lib/libQt5SerialPort.a D:/Qt/5.14.2/mingw73_64/lib/libQt5Core.a -lmingw32 D:/Qt/5.14.2/mingw73_64/lib/libqtmain.a -LC:/openssl/lib -LC:/Utils/my_sql/mysql-5.7.25-winx64/lib -LC:/Utils/postgresql/pgsql/lib -lshell32
The paths look strange: -L"<build_debug>/src/common/debug" -lcommon -L"<build_debug>/src/atctrl/debug"
What is <build_debug>?
Also, if common is a static lib when your pro file is wrong as you are linking dynamically. -
I have replaced the build-dir with <build_debug>, the original path is:
D:/Dev/project01/src/build-subdirs-Desktop_Qt_5_14_2_MinGW_64_bit-Debug/
@jsulm said in Undefined reference, altough references in library exists:
Also, if common is a static lib when your pro file is wrong as you are linking dynamically.
Why? I added "CONFIG += static" in the project pro-file, isn't that correct?
-
This is getting strange.. when i'm using SerialBase::cSerialBase (from common lib) directly in the app project (instantiating in main.cpp), suddenly the linker finds everything.
It seems like the linker doesn't find the dependency to SerialBase::cSerialBase (common lib) when only using ATCtrl::cATCtrl (atctrl lib).
Just for clarification, here the headers for the libraries:
class cSerialBase: public QObject { Q_OBJECT }
class cATCtrl: public SerialBase::cSerialBase { Q_OBJECT }
Usage in app.pro (main.cpp) which doesn't work (linker doesn't find SerialBase::cSerialBase):
#include <atctrl/atctrl.h> int main(int argc, char *argv[]) { ATCtrl::cATCtrl atctrl; return 0; }
Usage in app.pro (main.cpp) which strangly does work:
#include <atctrl/atctrl.h> int main(int argc, char *argv[]) { ATCtrl::cATCtrl atctrl; SerialBase::cSerialBase serialBase; return 0; }
-
The link order is wrong,
-lactrl
must come first,s ee also e.g. here -
I switched the order in the app.pro file for the common and atctrl lib and now it works. Thank you very much.