CPack missed dlls copied by windeployqt

In my Qt-based project, I deploy qt dlls by following steps:

  1. Run my custom cmake script by install(SCRIPT
  2. My cmake script runs windeployqt during installation, and the working directory is set to CMAKE_INSTALL_PREFIX so it can run correctly

This works fine when I install my project, but when I try to package my project as an archive by cpack -G ZIP, Qt deployed dlls are missing from the archive. It seems that only files installed with install() function can be packed. And another discovery is that, cpack runs my custom script again during packaging, but it takes no works, because the command is executed in CMAKE_INSTALL_PREFIX, but not where applications are staged.

How can I make qt deployed files exist in my package?

@craig.scott ?

Can’t offer much advice here without a minimal, complete project that demonstrates the problem.

I have written a minimalist example, consisting of 3 files in one directory:

Source code

Files:

  • CMakeLists.txt
  • main.cpp
  • deploy.cmake.in

And here’s all the code:

# CMakeLists.txt:
cmake_minimum_required(VERSION 3.0.0)
project(example VERSION 0.1.0)

find_package(Qt6 6.2.4 COMPONENTS Widgets REQUIRED)

add_executable(example main.cpp)
target_link_libraries(example PRIVATE Qt6::Widgets)
set_target_properties(example PROPERTIES WIN32_EXECUTABLE true)

find_program(windeployqt_exe windeployqt REQUIRED)
configure_file(deploy.cmake.in ${CMAKE_BINARY_DIR}/deploy.cmake)

install(TARGETS example
    RUNTIME DESTINATION .)
install(SCRIPT ${CMAKE_BINARY_DIR}/deploy.cmake)

set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
# deploy.cmake.in
message(WARNING Running windeployqt...)
execute_process(COMMAND "@windeployqt_exe@" example.exe
    WORKING_DIRECTORY "@CMAKE_INSTALL_PREFIX@")
// main.cpp
#include <QApplication>
#include <QWidget>
#include <iostream>

int main(int argc, char **argv) {
  QApplication qapp(argc, argv);
  QWidget wind;
  wind.show();
  return qapp.exec();
}

Commands from config to pack

I configure and build it with:

cmake -S D:/Git/example -B D:/Git/build-example-win -G Ninja -DCMAKE_PREFIX_PATH=D:/ProgramFiles/Qt/libQt/Qt6.4.0-gcc12-shared -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=D:/ProgramFilesU/gcc-compilers/mingw-gcc12/bin/gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=D:/ProgramFilesU/gcc-compilers/mingw-gcc12/bin/g++.exe -DCMAKE_INSTALL_PREFIX:PATH=D:/Git/build-example-win/install

cmake --build D:/Git/build-example-win

And install in the build directory with:

cmake --install .

And run cpack in the build directory with:

cpack -G ZIP

Outputs

The output during configuration is:

-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: D:/ProgramFilesU/gcc-compilers/mingw-gcc12/bin/gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: D:/ProgramFilesU/gcc-compilers/mingw-gcc12/bin/g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE
-- Performing Test HAVE_STDATOMIC
-- Performing Test HAVE_STDATOMIC - Success
-- Found WrapAtomic: TRUE
-- Configuring done (1.5s)
-- Generating done (0.0s)
-- Build files have been written to: D:/Git/build-example-win

The output during build is:

[2/2] Linking CXX executable example.exe

The output during installation is:

-- Install configuration: "Debug"
-- Installing: D:/Git/build-example-win/install/./example.exe
CMake Warning at deploy.cmake:1 (message):
  Runningwindeployqt...
Call Stack (most recent call first):
  cmake_install.cmake:51 (include)


D:\Git\build-example-win\install\example.exe 64 bit, release executable
Direct dependencies: Qt6Core Qt6Widgets
All dependencies   : Qt6Core Qt6Gui Qt6Widgets
To be deployed     : Qt6Core Qt6Gui Qt6Widgets
Warning: Cannot find GCC installation directory. g++.exe must be in the path.
Updating Qt6Core.dll.
Updating Qt6Gui.dll.
Updating Qt6Widgets.dll.
Updating D3Dcompiler_47.dll.
Creating directory D:/Git/build-example-win/install/imageformats.
Updating qgif.dll.
Updating qico.dll.
Updating qjpeg.dll.
Creating directory D:/Git/build-example-win/install/platforms.
Updating qwindows.dll.
Creating directory D:/Git/build-example-win/install/styles.
Updating qwindowsvistastyle.dll.
Creating D:\Git\build-example-win\install\translations...
Warning: Could not find any translations in D:\ProgramFiles\Qt\libQt\Qt6.4.0-gcc12-shared\translations (developer build?)
.

The output during packaging is:

CPack: Create package using ZIP
CPack: Install projects
CPack: - Install project: example []
CMake Warning at D:/Git/build-example-win/deploy.cmake:1 (message):
  Runningwindeployqt...
Call Stack (most recent call first):
  D:/Git/build-example-win/cmake_install.cmake:51 (include)


D:\Git\build-example-win\install\example.exe 64 bit, release executable
Direct dependencies: Qt6Core Qt6Widgets
All dependencies   : Qt6Core Qt6Gui Qt6Widgets
To be deployed     : Qt6Core Qt6Gui Qt6Widgets
Warning: Cannot find GCC installation directory. g++.exe must be in the path.
Qt6Core.dll is up to date.
Qt6Gui.dll is up to date.
Qt6Widgets.dll is up to date.
D3Dcompiler_47.dll is up to date.
qgif.dll is up to date.
qico.dll is up to date.
qjpeg.dll is up to date.
qwindows.dll is up to date.
qwindowsvistastyle.dll is up to date.
Warning: Could not find any translations in D:\ProgramFiles\Qt\libQt\Qt6.4.0-gcc12-shared\translations (developer build?)
.CPack: Create package
CPack: - package: D:/Git/build-example-win/example-0.1.0-win64.zip generated.

What really happen:

The zip pack is generated, but it contains only one executable: example.exe. All dlls deployed by windeployqt are missing from zip package.

What I hope to happen:

I hope that all deployed files can be added in the zip archive.

Your replies were flagged as spam and needed manual review. I’ve marked them all as not spam. Please delete the messages we don’t need and just keep the most relevant one.

Thank you. I have deleted unrevelant messages now.

You cannot set your WORKING_DIRECTORY in the deploy.cmake script to "@CMAKE_INSTALL_PREFIX@". That will force it to try to use the configure-time install prefix as the working directory because that value is substituted from the variable’s value when CMake runs the configure step. I’m guessing you meant for that value to be the install prefix as used at install time. To do that, change this to "${CMAKE_INSTALL_PREFIX}" and add @ONLY to the end of your configure_file() call to prevent it from be substituted.

Thanks very much, it works!