OmixVisualization / qtjambi

QtJambi is a wrapper for using Qt in Java.
http://www.qtjambi.io
Other
365 stars 43 forks source link

QtJambi 6.6.0 does not run with Qt 6.6.1 #182

Closed wolfseifert closed 11 months ago

wolfseifert commented 11 months ago

Describe the bug QtJambi 6.6.0 does not run with Qt 6.6.1 on Linux. The QtJambi README suggests that QtJambi 6.6.0 can be used with any Qt 6.x version. This seems to be wrong.

To Reproduce Running a QtJambi 6.6.0 program with Qt 6.6.1 gives (at exit): /usr/lib/jvm/java-21-openjdk/bin/java: symbol lookup error: /tmp/QtJambi6.6.0_wolfgang/lib/libQtJambi.so.6.6.0: undefined symbol: _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate, version Qt_6_PRIVATE_API

And in fact $ nm -D libQtJambi.so.6.6.0 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate U _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@Qt_6_PRIVATE_API while $ nm -D libQt6Core.so.6.6.1 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate 00000000002ce0a0 T _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6

The symbol names differ towards the end. Workaround Building QtJambi 6.6.0 from sources against Qt 6.6.1 resolves the issue. Now $ nm -D libQtJambi.so.6.6.0 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate U _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@Qt_6

System (please complete the following information):

omix commented 11 months ago

Hi. Is Qt 6.6.1 a Linux build or from Qt installer? I know of differences of symbol suffixes between builds on different Linux distributions. If your 6.6.1 is from Qt installer it might be that they changed the platform version where it has been compiled. Or maybe there is a change in a header between the versions, I don't know. The description in README is based upon the promise that different patch versions of Qt are binary compartible.

exaCORE42 commented 11 months ago

Is a version for 6.6.1 planned to be published on Maven?

wolfseifert commented 11 months ago

Linux build and Qt installer version have the same symbol name $ nm -D /usr/lib/libQt6Core.so.6.6.1 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate 00000000002ce0a0 T _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6 $ nm -D ~/qt/6.6.1/gcc_64/lib/libQt6Core.so.6.6.1 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate 00000000002f3130 T _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6 which differs from the one requested by QtJambi built against Qt 6.6.0.

It looks like QtJambi uses a "Qt Private" symbol, which may change even between minor Qt versions.

If this is true, QtJambi is only guaranteed to run with the Qt version it was built against. In the past the QtJambi version always matched exactly the Qt version it was built again. This needs to be documented.

omix commented 11 months ago

Ok, so this does not depend on distribution-specific build settings. I can confirm that QReadWriteLock::destroyRecursive seems to have different versions in Qt 6.6.0 and 6.6.1.

readelf -sW /opt/Qt/6.6.0/gcc_64/lib/libQt6Core.so | grep destroyRecursive
  2000: 00000000002f2370    94 FUNC    GLOBAL DEFAULT   13 _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6_PRIVATE_API
readelf -sW /opt/Qt/6.6.1/gcc_64/lib/libQt6Core.so | grep destroyRecursive
  1999: 00000000002f3130    94 FUNC    GLOBAL DEFAULT   13 _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6

And this incompatibility applies to all binaries linked against libQt6Core and using QReadWriteLock. This happens contrary to Qt's promise of binary compatibility. I am planning to publish new binaries shortly. They will be linked against 6.6.1. But this means they are not compatible to 6.6.0 in Linux. I will check if this also applies to other platforms.

omix commented 11 months ago

I believe it is an error in libQt6Core.so version 6.6.0 that has been corrected in 6.6.1. It does not make sense to export symbol QReadWriteLock::destroyRecursive as private API because it is not private API. It is part of public API and because of the inline descructor of QReadWriteLock it is linked in every binary using QReadWriteLock. I did not check Qt Bugs but I believe that's the reason for this incompatibility here.

wolfseifert commented 11 months ago

FYI $ nm -D ~/qt/6.7.0/gcc_64/lib/libQt6Core.so.6.7.0 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate 00000000002f6a10 T _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6_PRIVATE_API

omix commented 11 months ago

Ok, my my hypothesis is a fail.

omix commented 11 months ago

Also Windows binaries are incompatible.

wolfseifert commented 11 months ago

After doing some research on the Qt side I found this: to fix QTBUG-117514 they moved

QFutureInterfaceBase::setContinuation(std::function<void (QFutureInterfaceBase const&)>, QFutureInterfaceBasePrivate*)

    "_ZN20QFutureInterfaceBase15setContinuationE*P27QFutureInterfaceBasePrivate"
    # QReadWriteLock::destroyRecursive(QReadWriteLockPrivate*)
    "_ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate"

from Qt_6_PRIVATE_API to Qt_6 (see end of ~/qt/6.6.1/Src/qtbase/src/corelib/src/CMakeLists.txt).

So this change should make into Qt 6.7.0 and up.

omix commented 11 months ago

Fantastic! I think you got it. I see if I can make a workaround to let it work with both.

omix commented 11 months ago

QtJambi 6.6.1 is available now. It has been built with Qt 6.6.1.

wolfseifert commented 11 months ago

For Qt 6.7.0-beta1 I get:

$ nm -D ~/qt/6.7.0/gcc_64/lib/libQt6Core.so.6.7.0 | grep _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate
00000000002ff420 T _ZN14QReadWriteLock16destroyRecursiveEP21QReadWriteLockPrivate@@Qt_6

so this seems to be stable now (Qt 6.6.1, Qt 6.7.0-beta1).

wolfseifert commented 11 months ago

As supposed: QtJambi 6.6.1 does not run with Qt 6.6.0

This is not clear from the README:

"QtJambi 6.6.1 requires Qt 6.6.x whereas x can be any patch version greater or equals 0 (except qtjambi-activex). This release has been built with Qt 6.6.1. Qt 6.6.0 is not binary compatible to higher versions."