New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes bundles the wrong Qt #2

Closed
probonopd opened this Issue Sep 5, 2016 · 11 comments

Comments

Projects
None yet
2 participants
@probonopd
Copy link
Owner

probonopd commented Sep 5, 2016

When I build an application in Qt Creator, then it has its rpath point to the Qt directory that came with Qt Creator, and that was used for compiling the application.

linuxdeployqt should use that location as the source location when bundling libraries, but it doesn't and bundles Qt from the host system instead, which is guaranteed to break due to version mismatches. Possibly related to #1.

When building an app using Qt Creator, it looks like this:

ldd /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3
    linux-vdso.so.1 =>  (0x00007fff61bef000)
    libQt5Widgets.so.5 => /tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/lib/libQt5Widgets.so.5 (0x00007f7f27dcf000)
    libQt5Core.so.5 => /tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/lib/libQt5Core.so.5 (0x00007f7f276b4000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f7f27319000)
...

linuxdeployqt currently wrongly tries to bundle the system Qt from the rpath (/usr/lib rather than the one in /tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64 from the example above):

Log: Deploying plugins from "/usr/lib/plugins"
ERROR: file copy failed from "/usr/lib/plugins/platforms/libqxcb.so"
ERROR:  to "/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/plugins/platforms/libqxcb.so"
ERROR: file copy failed from "/usr/lib/plugins/printsupport/libcupsprintersupport.so"
ERROR:  to "/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/plugins/printsupport/libcupsprintersupport.so"
Log: Created configuration file: "/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/qt.conf"

After running linuxdeployqt it looks like this

ldd /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3: /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libQt5Core.so.5: version `Qt_5.7' not found (required by /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3)
/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3: /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libQt5Core.so.5: version `Qt_5' not found (required by /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3)
/home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3: /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libQt5Widgets.so.5: version `Qt_5' not found (required by /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/untitled3)
    linux-vdso.so.1 =>  (0x00007ffd7effc000)
    libQt5Widgets.so.5 => /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libQt5Widgets.so.5 (0x00007f78b8681000)
    libQt5Core.so.5 => /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libQt5Core.so.5 (0x00007f78b8176000)
    libstdc++.so.6 => /home/me/build-untitled3-Desktop_Qt_5_7_0_GCC_64bit-Debug/lib/libstdc++.so.6 (0x00007f78b7db3000)

Which means that the wrong Qt libraries have been copied to the bundle location...

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Sep 5, 2016

If we find no better solution, we could do like https://github.com/aurelien-rainone/macdeployqtfix and ask the user to provide the "path of Qt libraries used to build the Qt application". However I think this is not elegant and the original macdeployqt doesn't need it.

EDIT: Seems like macdeployqt suffers from the same issue and they are also considering this. https://bugreports.qt.io/browse/QBS-954?focusedCommentId=315655&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-315655

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Sep 5, 2016

deploymentInfo.qtPath and deploymentInfo.qtPath sometimes contain the correct values... also copyFilePrintStatus sometimes gets the correct from argument passed in...
framework.sourceFilePath is the location from where the library gets copied.

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Sep 5, 2016

In 4c0da30 it seems to be working... for the moment... if the app can be run from Qt Creator prior to running linuxdeployqt. But sometimes this is not the case, prior to linuxdeployqt I get

This application failed to start because it could not find or load the Qt platform plugin "xcb"
in "".

Reinstalling the application may fix this problem.
The program has unexpectedly finished.

Then running linuxdeployqt seems to copy in the wrong Qt libraries from the system.

In which case I can

export QT_PLUGIN_PATH=/tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/plugins/ # not needed?
export LD_LIBRARY_PATH=/tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64/lib/
export QTDIR=/tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64 # not needed?

prior to running linuxdeployqt to make it launch.

When I do that and then run linuxdeployqt, then it seems to copy the correct libraries.

Afterwards when I

unset QT_PLUGIN_PATH
unset LD_LIBRARY_PATH
unset QTDIR

then we are up and running!

Tried this with https://github.com/LazyT/obpm

@Larpon

This comment has been minimized.

Copy link

Larpon commented Oct 7, 2016

To me it seems unreliable to let variables lay the foundation of any sane way of collecting correct path info. Variables can be, and often are, tangled with in very unpredictable maners. On top they are user-space which mean anyone or anything can change them whenever see fit. The most reliable and 'portable' way so far, as I see it, is still the output from ldd? You could have a dependency resolver (class or function) with a simple interface that underneath have implementations for using ldd or the ld.so.conf approach as you describe here - or whatever may come up in the future.

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Oct 7, 2016

As was suggested on the Qt mailing list, we need to replace the ldd calls with our own implementation. Pull requests welcome :-)

@Larpon

This comment has been minimized.

Copy link

Larpon commented Oct 7, 2016

I'm not currently on the list - can you point me to the thread?

@probonopd

This comment has been minimized.

@Larpon

This comment has been minimized.

Copy link

Larpon commented Oct 7, 2016

Ouch I can see now why ldd is not a winner :)

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Oct 7, 2016

We must not rely on information from from QLibraryInfo:: since it points to the Qt used by the linuxdeployqt executable, which, if it is inside an AppImage, comes with its own bundled Qt defined in its qt.conf. Rather we should use the Qt in /tmp/.mount_QtCreator-5.7.0-x86_64/5.7/gcc_64 from the example above.

Using QLibraryInfo:: currently results in

Log: Deploying QML imports 
Log: Application QML file search path(s) is ("/home/me/qakexamples/qakexamplesapp/qml")
Log: Looking for qmlimportscanner at "/tmp/.mount_2aFvEE/bin/qmlimportscanner"
Log: Fallback, looking for qmlimportscanner at "/tmp/.mount_2aFvEE/qmlimportscanner"
ERROR: Valid qmlImportsPath not found at "/tmp/.mount_2aFvEE/qml"
ERROR: Possibly your Qt library has the wrong information in qt_prfxpath, e.g., because it was moved since it was compiled

due to this.

I don't know how to get the path to the correct Qt reliably; it might be necessary for the user to pass it in as an argument.

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Oct 8, 2016

windeployqt says:

The simplest way to use windeployqt is to add the bin directory of your Qt
installation (e.g. <QT_DIR\bin>) to the PATH variable and then run:
  windeployqt <path-to-app-binary>

So we could also do that; check for qmake and assume that the Qt to be used is the one qtmake is set up to use:

dirname $(qmake --version | tail -n 1 | cut -d " " -f 6)

Does this logic hold?

@probonopd

This comment has been minimized.

Copy link
Owner Author

probonopd commented Oct 8, 2016

Implemented. Make sure you export the PATH to the Qt you want to bundle, so that qmake -v shows the correct Qt to be bundled.

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