I'm having repeatedly a linker error in Qt-Project containing a local Installation of Qt 5.14.2 and OpenCV 4.3 and a gcc 11 (fedora 35, x64) and in the last step bringing everything together there might be something off or not fit together:
This is the last call out of the make system together with the error:
g -Wl,-rpath,/home/qt/Qt/5.14.2/gcc_64/lib -o QtOpenCVCompatibleTest main.o mainwindow.o moc_mainwindow.o -L/home/qt/Qt/5.14.2/gcc_64/lib -lopencv_core -lopencv_videoio -lopencv_highgui /home/qt/Qt/5.14.2/gcc_64/lib/libQt5Widgets.so /home/qt/Qt/5.14.2/gcc_64/lib/libQt5Gui.so /home/qt/Qt/5.14.2/gcc_64/lib/libQt5Core.so -lGL -lpthread
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/11/../../../../lib64/libopencv_highgui.so: undefined reference to `QPushButton::hitButton(QPoint const&) const@Qt_5'
So in short: CV needs a symbol that Qt can't deliver.
The relevant parts of the .pro file:
QT = core gui
greaterThan(QT_MAJOR_VERSION, 4): QT = widgets
INCLUDEPATH = /usr/include/opencv4/
LIBS = -L/home/qt/Qt/5.14.2/gcc_64/lib -lopencv_core -lopencv_videoio -lopencv_highgui
A closer look towards the libs:
nm -gDC /usr/lib64/libopencv_highgui.so | grep QPushButton
U QPushButton::paintEvent(QPaintEvent*)@Qt_5
U QPushButton::qt_metacall(QMetaObject::Call, int, void**)@Qt_5
U QPushButton::qt_metacast(char const*)@Qt_5
U QPushButton::focusInEvent(QFocusEvent*)@Qt_5
U QPushButton::focusOutEvent(QFocusEvent*)@Qt_5
U QPushButton::keyPressEvent(QKeyEvent*)@Qt_5
U QPushButton::staticMetaObject@Qt_5
U QPushButton::event(QEvent*)@Qt_5
U QPushButton::setFlat(bool)@Qt_5
U QPushButton::QPushButton(QWidget*)@Qt_5
U QPushButton::QPushButton(QWidget*)@Qt_5
U QPushButton::~QPushButton()@Qt_5
U QPushButton::minimumSizeHint() const@Qt_5
U QPushButton::sizeHint() const@Qt_5
U QPushButton::hitButton(QPoint const&) const@Qt_5
U typeinfo for QPushButton@Qt_5
So yes, we need QPushButton::hitButton(QPoint const&) of Qt in opencv's highgui
but the Qt Version only has:
nm -gDC /home/qt/Qt/5.14.2/gcc_64/lib/libQt5Widgets.so | grep hitButton
0000000000331a00 T QToolButton::hitButton(QPoint const&) const@@Qt_5
00000000002e4990 T QRadioButton::hitButton(QPoint const&) const@@Qt_5
000000000024e060 T QAbstractButton::hitButton(QPoint const&) const@@Qt_5
000000000025d840 T QCheckBox::hitButton(QPoint const&) const@@Qt_5
... the method of its superclass, which in fact should be enough to have something to bind to.
So there are 3 Questions left:
- How does the early binding in c works along the linker - I would guess every inherited class have at least a symbol pointing towards a proper method. I've might build OpenCV with a different version of Qt (but all Qt5 Versions have QPushButton::hitButton)
- What is the correct calling order in gcc's linker command - I assume all Qt libs will be always called last as long as every other component depends on them?
- Basically: How do I get rid of that error.
The local Qt Installation (on a Fedora 35 x64) is located as its own user but with all files at least accessible. A pure Qt Project just builds fine on the system.
CodePudding user response:
The QPushButton::hitButton
override exists in the latest Qt 5 (which is 5.15 at the time of writing), but did not yet exist in Qt 5.14.
It looks like your OpenCV build was compiled with a newer set of Qt headers than the version you're linking with. Presumably these came from your system, since Fedora 35 ships with Qt 5.15.2.
The only right solution is to use the correct headers for the libraries that you are linking with; anything else will just lead to more headaches.
When building OpenCV, make sure you're using your local Qt distribution and not your system's version. I think (but did not test this) that you can do this by setting Qt5_DIR
to /home/qt/Qt/5.14.2
in CMake.