kevinhendricks / Access-Aide

A Sigil edit plugin to help ebook developers improve Accessibility of their epubs
GNU Lesser General Public License v2.1
20 stars 5 forks source link

pyside QT .so link issue #8

Closed derrickoswald closed 3 months ago

derrickoswald commented 3 months ago

Hi, I just updated my Sigil to version 2.2.1 using QT6.2.4 (I don't really know if that's legal or not, but it worked based on Sigil commit ad81ddc). It's probably not your plugin's fault, but I ran into an error running Access-Aide, that says:


Traceback (most recent call last):
  File "/opt/sigil/share/sigil/plugin_launchers/python/launcher.py", line 141, in launch
    target_script = __import__(script_module)
  File "/home/derrick/.local/share/sigil-ebook/sigil/plugins/Access-Aide/plugin.py", line 17, in <module>
    from accessgui import GUIUpdateFromList
  File "/home/derrick/.local/share/sigil-ebook/sigil/plugins/Access-Aide/accessgui.py", line 15, in <module>
    from plugin_utils import QtCore, QtGui, QtWidgets, QtSvg
  File "/home/derrick/.local/share/sigil-ebook/sigil/plugins/Access-Aide/plugin_utils.py", line 40, in <module>
    from PySide6 import QtCore, QtGui, QtNetwork, QtPrintSupport, QtSvg, QtWebChannel, QtWidgets  # noqa: F401
ImportError: /home/derrick/.local/lib/python3.10/site-packages/PySide6/libpyside6.abi3.so.6.4: undefined symbol: _Z5qHash14QByteArrayViewm, version Qt_6
Error: /home/derrick/.local/lib/python3.10/site-packages/PySide6/libpyside6.abi3.so.6.4: undefined symbol: _Z5qHash14QByteArrayViewm, version Qt_6

I've done all the Python voodoo I can think of:

Both your version 1.0.0 and 0.9.7 have the same issue.

Which version of PyQT6 do you use? None seem to correspond to the QT6.2.4 that Sigil is using?

pip3 install pyqt6==6.2.4
ERROR: Could not find a version that satisfies the requirement pyqt6==6.2.4 (from versions: 6.0.0, 6.0.1, 6.0.2, 6.0.3, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.2.3, 6.3.0, 6.3.1, 6.4.0, 6.4.1, 6.4.2, 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.6.0, 6.6.1, 6.7.0, 6.7.1)
ERROR: No matching distribution found for pyqt6==6.2.4

Should I recompile Sigil with another QT version, that is, so that it loads QT6.4.2 instead of QT6.2.4? Their instructions only say Qt6.2.2 or higher 6.4+ is more realistic (with QtWebEngine).

libqt6webenginecore6-bin is already the newest version (6.2.4+dfsg-6ubuntu1) available on Ubuntu.

kevinhendricks commented 3 months ago

The latest Sigil versions are built with Qt 6.7.2. From looking at the Qt web docs: QByteArrayView was added in Qt 6.0 but most of its accessor routines were not added until Qt 6.3 and later.

If I demangle that symbol for g++ (gcc) I get the following:

qHash(QByteArrayView, unsigned long)

and the closest signature I could find was the following: size_t qHash(const QByteArray &key, size_t seed = 0)

but that should exist in Qt 6.0. So Qt 6.2.4 should work but ...

I just can not see how it has a missing symbol unless size_t is not equal to unsigned long on your platform?

FYI, Our upcoming Sigil release will require Qt 6.4.2 as the minimum for building it with a matched PySide6 version. If you can get that version for both Qt6, and Python and add the Pyside6 version for Qt6.4.2, it should all just work.

A better idea might be to use the python3 module aqtinstall to create your own local version of Qt 6.7.2 and build PySide6 in your Python 3.10 against that Qt version.

kevinhendricks commented 3 months ago

See this post from our User forum and those following for and easy way to update Ubuntu Jammy to Qt 6.7.2 without disturbing the system version at all:

https://www.mobileread.com/forums/showthread.php?p=4437512#post4437512

You might also like to pull the very latest version of Sigil from our github master as we are probably about 2 or 3 weeks away from making a release and only waiting on translators to update some things. It should be a quite stable build of Sigil 2.3.0. I am using it on a daily basis with no issues.

kevinhendricks commented 3 months ago

FWIW, I misread that symbol QByteArray was there but not QByteArrayView.

Qt 6.2.4 has a function with the following symbol: size_t qHash(QByteArrayView&, size_t seed=0)

But by Qt 6.4.2 and later that was removed!

So you mixing of Qt 6.2.4 with Qt 6.4.2 is what is causing the issue. I would rebuild Sigil with at least Qt 6.4.2 and then find a matching Qt 6.4.2 version of PySide6.

Or as I said earlier, move both PySide6 and Sigil to your own Qt6.7.2 to future proof things.

kevinhendricks commented 3 months ago

Hear is a snippet of Qt's qhashfunctions.h that shows the change:

#if QT_CORE_REMOVED_SINCE(6, 4)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray &key, size_t seed = 0) noexcept;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArrayView &key, size_t seed = 0) noexcept;
#else
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(QByteArrayView key, size_t seed = 0) noexcept;
inline Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray &key, size_t seed = 0
        QT6_DECL_NEW_OVERLOAD_TAIL) noexcept
{ return qHash(qToByteArrayViewIgnoringNull(key), seed); }
#endif

So Qt 6.2.4 had: size_t qHash(const QByteArrayView &key, size_t seed = 0);

but Qt 6.4 and after have (which is not documented on official Qt docs at all): size_t qHash(QByteArrayView key, size_t seed = 0)

The only difference is that a reference to the QByteArrayView is passed in Qt 6.2.4 which is very inefficient compared to a version used to Qt 6.4.0 and later which does not need the reference at all and the QByteArrayView gets resolved by templates to a byte pointer and length which can be passed in registers when compiled as optimized (and is read-only).

This is why the PySide6 from Qt 6.2.4 is broken when used with Qt 6.4.0 and later.

Hope something here helps.

Closing this. But you can post here or in our Sigil User Forums on Mobileread to get build help if you run into issues.

Once you get aqtinstall to get you Qt 6.7.2, you can checkout the right PySide6 version from PySide's github or use the official source archive from Qt and create your own PySide6 that will work with your own Qt version.