Skip to content

Qt bootstrap assumes every native Qt library has a corresponding PySide wrapper #3395

Open

Description

@marcoAffuso

Title: Qt bootstrap assumes every native Qt library has a corresponding PySide wrapper

Description:

I found an issue in the python-for-android Qt bootstrap when it is used by PySide6.

Environment:

  • PySide6: 6.12
  • Python: 3.14
  • Android ABI: arm64-v8a
  • Android emulator: Android 16
  • Android NDK: r28c
  • Qt Quick / Qt Quick Controls

The PySide Android deployment correctly needs to pass native Qt dependencies such as:

Core
Gui
Network
Qml
OpenGL
QmlModels
QmlWorkerScript
QmlMeta
Quick
QuickTemplates2
QuickControls2

The problem is in:

pythonforandroid/bootstraps/qt/build/templates/libs.tmpl.xml

The current template iterates over qt_libs and generates both:

Qt6<Module>_<arch>

for native Qt libraries, and:

Qt<Module>.abi3.so

for PySide wrapper libraries.

These two sets are not equivalent.

Some native Qt dependencies do not have a corresponding PySide wrapper library.

For example:

QmlModels
QmlWorkerScript
QmlMeta
QuickTemplates2

are valid native Qt dependencies, but the corresponding wrapper libraries do not exist in the PySide wheel:

QtQmlModels.abi3.so
QtQmlWorkerScript.abi3.so
QtQmlMeta.abi3.so
QtQuickTemplates2.abi3.so

As a result, the generated load_local_libs array can contain non-existent libraries.

The runtime then fails with an error like:

dlopen failed: library ".../QtQmlModels.abi3.so" not found
java.lang.UnsatisfiedLinkError
Loading Qt native libraries failed

Root cause:

qt_libs is currently used for two different purposes:

  1. native Qt libraries;
  2. PySide wrapper libraries.

This assumption is not always valid.

Suggested solution:

Introduce a separate list/argument for PySide wrapper modules, for example:

--pyside-libs

Then:

qt_libs

should be used only for native Qt libraries, while:

pyside_libs

should be used only to generate:

Qt<Module>.abi3.so

entries in load_local_libs.

For backward compatibility, if --pyside-libs is not provided, it could fall back to qt_libs.

Conceptually:

pyside_libs = (
    args.pyside_libs.split(",")
    if args.pyside_libs
    else qt_libs
)

and in libs.tmpl.xml:

{%- for pyside_lib in pyside_libs %}
<item>{{ arch }};Qt{{ pyside_lib }}.abi3.so</item>
{% if pyside_lib == "Qml" -%}
<item>{{ arch }};libpyside6qml.abi3.so</item>
{% endif %}
{%- endfor -%}

I implemented this locally and tested it successfully.

After separating native Qt libraries from PySide wrapper libraries:

  • the application starts correctly;
  • Qt Quick Controls work;
  • no non-existent Qt*.abi3.so libraries are loaded;
  • no UnsatisfiedLinkError occurs;
  • QML to Python interaction works correctly.

The relevant files are:

pythonforandroid/bootstraps/common/build/build.py
pythonforandroid/bootstraps/qt/build/templates/libs.tmpl.xml

This issue is related to PySide Android deployment, because PySide may need to pass native Qt-only dependencies which do not have Python wrapper libraries.

I have a working local implementation and can provide the diff if useful.

python-for-android-fix.patch

python-for-android-fix.patch

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions