Skip to content

macdeployqt (Qt6/migrate/qt6): QtSvg/QtPdf/QtVirtualKeyboard unresolved, breaking nested plugin bundles #17

Description

@JimHanan

Building macOS browser.app on the migrate/qt6 branch (Qt 6.11.1 via Homebrew, arm64, macOS 26) and packaging with Distribution/vlab-macdeployqt.sh produces a broken app. macdeployqt errors partway through:

ERROR: Cannot resolve rpath "@rpath/QtPdf.framework/Versions/A/QtPdf"
ERROR: Cannot resolve rpath "@rpath/QtSvg.framework/Versions/A/QtSvg"
ERROR: Cannot resolve rpath "@rpath/QtVirtualKeyboardQml.framework/Versions/A/QtVirtualKeyboardQml"
ERROR: Cannot resolve rpath "@rpath/QtVirtualKeyboard.framework/Versions/A/QtVirtualKeyboard"

These come from three plugins that pull in extra Qt modules macdeployqt doesn't bundle or fix up: PlugIns/iconengines/libqsvgicon.dylib (QtSvg), PlugIns/imageformats/libqpdf.dylib (QtPdf), PlugIns/platforminputcontexts/libqtvirtualkeyboardplugin.dylib (QtVirtualKeyboard/QtVirtualKeyboardQml). Their Qt dependency references are left as bare @rpath/QtX.framework/... instead of being rewritten to @loader_path/../Frameworks/... like every other bundled dylib.

Consequence: if the build machine also has an rpath fallback to a system/Homebrew Qt install (e.g. a leftover /opt/homebrew/lib LC_RPATH from local qmake/build config), dyld resolves those bare @rpath references against the external Qt install instead of failing outright — loading a second, separate copy of QtCore/QtGui alongside the bundled one. This produces real runtime hazards:

objc[...]: Class QT_ROOT_LEVEL_POOL__... is implemented in both
  .../browser.app/Contents/Frameworks/QtCore.framework/Versions/A/QtCore and
  /opt/homebrew/Cellar/qtbase/6.11.1/lib/QtCore.framework/Versions/A/QtCore.
  This may cause spurious casting failures and mysterious crashes.

Secondary effect of the same partial failure: because macdeployqt aborts on these errors partway through processing the -executable= list, it also never creates the Frameworks/PlugIns symlinks inside each nested tool bundle (Plug-ins/*.app/Contents/Frameworks -> ../../../Frameworks, Plug-ins/*.app/Contents/PlugIns -> ../../../PlugIns) that a completed run does create — without them every nested tool (lpfg, cpfg, etc.) fails with qt.qpa.plugin: Could not find the Qt platform plugin "cocoa".

Workaround used locally: since none of SVG icons, PDF image loading, or on-screen keyboard input are needed by vlab's tools, we removed the three offending plugins (rm -rf Contents/PlugIns/iconengines Contents/PlugIns/platforminputcontexts; rm -f Contents/PlugIns/imageformats/libqpdf.dylib) and manually created the missing per-bundle symlinks, which let macdeployqt-equivalent packaging complete cleanly with no duplicate framework loads.

Suggested proper fix: either have vlab-macdeployqt.sh explicitly exclude/strip libqsvgicon.dylib, libqpdf.dylib, and libqtvirtualkeyboardplugin.dylib (or their triggering Qt modules) before running macdeployqt, or ensure the frameworks they need are resolvable/bundled so macdeployqt completes without erroring and finishes creating all per-executable symlinks.

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