I'm currently trying to cross-compile my Qt apps on a Fedora 21 machine to Windows (32 bit, for now). Compilation works without problems, but deployment doesn't. Of cours, I could copy all the necessary files out of the directories, but I think that's a waste of time, so I want to use Qt's 'windeployqt' tool. But whenever I invoke it, e.g. in Qt Creator as a build step, it just puts out this message(my test application is called day_404 :D) :
Unable to find dependent libraries of /home/marius/Entwicklung/build-day_404-Windows_32bit-Release/release/day_404.exe :Not implemented.
Does any of you know how to fix this, and use windeployqt without using Windows?
Thanks in advance, Marius
The windeployqt
tool doesn't seem to be usable on Fedora 23. It relies on accessing qmake
, thus, it doesn't work in the mingw cross-compile environment, where you build with mingw32-qmake-qt5
(or mingw64-qmake-qt5
). Even if this issue is patched - it wouldn't work with Qt5 projects using mingw64-cmake
.
A relatively simple way to get a list of all DLLs that need to be copied for deployment is to run the application under wine and trace all dll loads.
For example like this:
$ WINEDEBUG=+loaddll wine ./myapp 2> dll.log
The dll paths can be extracted like that:
$ grep Loaded dll.log | grep -v 'system32\|:load_builtin_dll' \
| awk -F'"' '{print $2}' \
| sed -e 's@\\\\@/@g' -e 's/^[A-Z]://' \
| sort > dll.lst
The file dll.lst
looks like this for a typical Qt5 project cross-compiled with mingw64:
/path/to/cwd/myapp.exe
/path/to/cwd/project.dll
[..]
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libpng16-16.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libwinpthread-1.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libxml2-2.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/Qt5Core.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/Qt5Gui.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/Qt5Widgets.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/zlib1.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qgif.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qico.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qjpeg.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll
You can then deploy those files like this:
$ mkdir -p "$deploy_dir"/{imageformats,platforms}
$ for i in imageformats platforms ; do
grep "/plugins/$i" dll.lst | xargs -r cp -t "$deploy_dir"/$i
done
$ grep -v '/plugins/' dll.lst | xargs -r cp -t "$deploy_dir"
For running a cross-compiled binary under wine, the mingw dll directory has to be added to the wine path, e.g. via:
sed 's/^\("PATH".*\)"$/\1;Z:\\\\usr\\\\x86_64-w64-mingw32\\\\sys-root\\\\mingw\\\\bin"/' \
-i $HOME/.wine/system.reg
The file ~/.wine/system.reg
is automatically created by wine
if it is doesn't exist, yet.
You can also use the tool peldd to get a list of all DLLs that a windows binary depends on. The tool runs on Linux, e.g.:
$ peldd myapp.exe -a -p . \
| sed -e 's@^\./@'"$PWD"'/@' -e 's@^\([^/]\)@'"$PWD"'/\1@' \
| sort > dll2.lst
The tool transitively walks all dependencies as compiled into the binaries - but - DLLs that are conditionally loaded at runtime (think dlopen()
, think Qt plugin) don't leave traces in the binary headers. In contrast to that: when running under wine, those DLLs are recorded, as well. For our example, this could be:
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libjpeg-62.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qgif.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qico.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/imageformats/qjpeg.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With