Windeployqt from vcpkg does not deploy all required libraries
Describe the bug
Windeployqt from vcpkg (located at tools\qt5\bin) does not deploy the following required libraries:
- pcre2-16.dll
- zstd.dll
- harfbuzz.dll
- freetype.dll
- bz2.dll
- brotlidec.dll
- brotlicommon.dll
Environment
- OS: Windows 10
- Compiler: MSVC 19.28.29915 for x64
To Reproduce Steps to reproduce the behavior:
- ./vcpkg install qt5-tools
- Build any Qt application with vcpkg
- Run windeployqt with the path to your application
Expected behavior Usually all libraries are copied to the application folder when using windeploqt from the standard installation.
cc @Neumann-A
Ping @Neumann-A, could you please take a look this issue? Thanks in advance.
Here is a minimal example to reproduce: TestQt.zip
- Compile it as usual (
vcpkg.jsonis included, dependencies will be installed automatically). - Run the executable from the build folder (all dlls are copied automatically using vcpkg), it should show empty window.
- Copy the executable to any other place and run
<you build folder>\vcpkg_installed\x64-windows\tools\qt5\bin\windeployqt.exe --no-opengl-sw --no-angle <path to TestQt.exe> - Try to run the executable, it will say that the mentioned dlls from the issue description are missing.
It's important to have windeployqt.exe working because it usually used to deploy binaries that depends on Qt. Even @Neumann-A suggested to use CMake + windeployqt for Qt deployment.
Ping @Neumann-A
Looks like an upstream issue for me? The real question is why are those missing?
I'm having the same problem. Interestingly as @Shatur writes vcpkg manages to copy all required dlls during the build (Not sure how this works, qtdeploy.ps1?). For normal development this is great, but for deployment this is not quite enough.
The main issue with this is that there is no (good?) way to make cmake install work for a Qt app with vcpkg on Windows. You can copy the other runtime dependencies with $<TARGET_RUNTIME_DLLS:target>, but for Qt you need to run windeployqt.exe which does not work with vcpkg.
So for deployment you either
- have a hard dependency on vcpkg using the build directory output (this will only work with vcpkg since "normal" CMake builds will not copy all runtime dependencies during build)
- do not use vcpkg at all, in which case the usual Windows Qt CMake approach works (CMake install with some custom
windeployqt.exemagic and$<TARGET_RUNTIME_DLLS:target>).
Is there a connection to #14608? E.g. the official Qt5 library has the abovementioned dlls statically linked in, while the vcpkg one does not, so not directly a windeployqt problem? In that case I would expect CMakes $<TARGET_RUNTIME_DLLS:target> to pick them up though right? Perhaps the IMPORTED_LOCATION is missing for these?
It seems like an upstream bug and we can't reproduce this, so I'm going to close this issue. If more information comes up, or this issue appears again, please reopen.
Thanks.
we can't reproduce this,
But I provided minimal reproducible example in https://github.com/microsoft/vcpkg/issues/21044#issuecomment-1024424989. Does the problem not reproduce on your machine?
I'm sorry for your doubts, I didn't make it clear: Closed this issue prefers that we've been waiting for an upstream fix for a long time.
Closed this issue prefers that we've been waiting for an upstream fix for a long time.
@JackBoosY I afraid that the issue not in the upstream.
windeployqt installed as usual doesn't have this issue. It behaves like this only with vcpkg installation.
I will have an investigation later.
@Shatur Sorry for late, I built your sample project successful but I'm not familar with qt coding. Which parameter should I pass into windeployqt,exe?
@JackBoosY copy the compiled application to a clean folder, run windeployqt --no-compiler-runtime --no-angle <path to the application> - the mentioned DLLs from the first message should be missing.
@Shatur Such like:
C:\Users\usr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Debug\vcpkg_installed\x86-windows\tools\qt5\bin>windeployqt.exe C:\Users\usr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Debug\tst --no-compiler-runtime --no-angle
Unable to find dependent libraries of C:\Users\usr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Debug\vcpkg_installed\x86-windows\bin\Qt5Widgetsd.dll :Cannot open 'C:/Users/usr/CMakeBuilds/bd6fc262-4128-8c3e-9d7a-de6165a29aa7/build/x86-Debug/vcpkg_installed/x86-windows/bin/Qt5Widgetsd.dll': The system cannot find the file specified.
Right?
I can run this command successfully on x86-release:
C:\Users\vusr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Release\test\TestQt.exe 32 bit, release executable
Adding Qt5Svg for qsvgicon.dll
Direct dependencies: Qt5Core Qt5Widgets
All dependencies : Qt5Core Qt5Gui Qt5Widgets
To be deployed : Qt5Core Qt5Gui Qt5Svg Qt5Widgets
Updating icuin71.dll.
Updating icuuc71.dll.
Updating icudt71.dll.
Updating Qt5Core.dll.
Updating Qt5Gui.dll.
Updating Qt5Svg.dll.
Updating Qt5Widgets.dll.
Creating directory C:/Users/vusr/CMakeBuilds/bd6fc262-4128-8c3e-9d7a-de6165a29aa7/build/x86-Release/test/iconengines.
Updating qsvgicon.dll.
Creating directory C:/Users/vusr/CMakeBuilds/bd6fc262-4128-8c3e-9d7a-de6165a29aa7/build/x86-Release/test/imageformats.
Updating qgif.dll.
Updating qicns.dll.
Updating qico.dll.
Updating qjp2.dll.
Updating qjpeg.dll.
Updating qsvg.dll.
Updating qtga.dll.
Updating qtiff.dll.
Updating qwbmp.dll.
Updating qwebp.dll.
Creating directory C:/Users/vusr/CMakeBuilds/bd6fc262-4128-8c3e-9d7a-de6165a29aa7/build/x86-Release/test/platforms.
Updating qwindows.dll.
Creating directory C:/Users/vusr/CMakeBuilds/bd6fc262-4128-8c3e-9d7a-de6165a29aa7/build/x86-Release/test/styles.
Updating qwindowsvistastyle.dll.
Creating C:\Users\vusr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Release\test\translations...
Warning: Could not find any translations in C:\Users\vusr\CMakeBuilds\bd6fc262-4128-8c3e-9d7a-de6165a29aa7\build\x86-Release\vcpkg_installed\x86-windows\share\qt5\translations (developer build?)
Since we only install the release tool, I think it's reasonable.
Right?
This is correct.
I can run this command successfully on x86-release:
Yes, but the result is wrong. As I mentioned in the first message the following libraries won't be copied:
pcre2-16.dll
zstd.dll
harfbuzz.dll
freetype.dll
bz2.dll
brotlidec.dll
brotlicommon.dll
If you try to run the application it will crash. This does not happen if you are using windeployqt from the official installation.
@Shatur Are you sure that the official windeployqt can copy those libraries?
@JackBoosY yes, I checked it before opening this issue.
I think it maybe related to the installed tool path but I copied all the libraries from bin to tools/qt5/bin couldn't fix this issue. I don't check the logic code in the tool source.
Hm, Qt could be installed in any folder. Maybe the issue in how windeploqt it built?
windeployqt pulls the paths from qmake and qmake should pull the paths from qt.conf in the same folder as qmake.
@JackBoosY so qt.conf could be adjusted to fix the issue?
According to https://doc.qt.io/qt-6/qt-conf.html, I added Binraries=bin and Libraries=lib or changed LibraryExecutables to bin didn't fix this issue.
As a workaround to this issue I found out that using this snippet allows you to copy over the missing DLLs which windeployqt is NOT copying over:
if (X_VCPKG_APPLOCAL_DEPS_INSTALL)
install(TARGETS ${MY_APP_TARGET} RUNTIME DESTINATION .)
else()
install(TARGETS ${MY_APP_TARGET}
RUNTIME_DEPENDENCIES
PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
DIRECTORIES ${QT_BIN_DIR}
RUNTIME DESTINATION .)
endif()
Question is: can't we link this list of DLLs statically into Qt while building it? Also why those are not required when building with the official Qt online installer framework?
Also why those are not required when building with the official Qt online installer framework?
Probably because Qt vendors those dependencies statically on its own. (or disables the features requiring them.)
Probably because Qt vendors those dependencies statically on its own. (or disables the features requiring them.)
Can we involve someone from Qt to help us on fixing this on our own side in vcpkg? Would be best if we could get an aligned behavior.
Traditionally, Qt bundles a bunch of 3rdparty dependencies (libpng, zlib, libjpeg, ...) to aid esp. Windows users where we don't have "system libraries". With package managers like vcpkg and conan available the situation has changed a bit, and we're looking into getting rid of the bundled libraries in the future. See https://bugreports.qt.io/browse/QTBUG-73760
When using the Qt from vcpkg, the bundled libraries are not used but the ones that are provided by vcpkg. Qt handles those as "system libraries" and windeployqt does not deploy them.
What can you do to cope with this?
-
Recent enough vcpkg versions come with a facility that can install vcpkg dependencies. Set X_VCPKG_APPLOCAL_DEPS_INSTALL=ON for your CMake project to enable it.
-
Alternatively, you could create an overlay triplet that builds all libraries but Qt statically.
The example under "Per-port customization" at https://learn.microsoft.com/en-us/vcpkg/users/triplets does exactly this for Qt5.
Recent enough vcpkg versions come with a facility that can install vcpkg dependencies. Set X_VCPKG_APPLOCAL_DEPS_INSTALL=ON for your CMake project to enable it.
Not enough, X_VCPKG_APPLOCAL_DEPS_INSTALL won't install libraries that windeployqt install.
Do you use https://www.qt.io/blog/cmake-deployment-api ?
Interesting, no, I didn't know about it!
I executed windeployqt manually:
https://github.com/crow-translate/crow-translate/blob/652a04ff5c5440f59db03ece04e07bb6fce25807/CMakeLists.txt#L256-L258
And then copy missing libs manually:
https://github.com/crow-translate/crow-translate/blob/652a04ff5c5440f59db03ece04e07bb6fce25807/CMakeLists.txt#L260-L263
I also provided a minimal example to reproduce the issue in https://github.com/microsoft/vcpkg/issues/21044#issuecomment-1024424989.