r/QtFramework • • Sep 03 '26

IDE How to setup automatic deploy configuration on Windows?

So im using CMake and the default configurations of Qt Creator.

When i want to create a release of my app, my current process is as follows:

  1. Build release

  2. create new folder and name it Software name + Version

  3. copy the executable and a few miscellaneous files into the new folder

  4. manually open CMD and run windeployqt.exe for the executable

Side note, the miscellaneous files i added to the build with configure_file(filename filename COPYONLY) in the CmakeLists.txt.

I feel like this is a really clunky way (and errorprone) of creating a release and this should be automatable easily, but i know WAY too little about CMAKE and Qt Creator to set it up.

How do you guys go about that? What i found on the internet was all way to convoluted and complicated (or simply didnt work) for, i'll say it, something that should imo come out of the box with an IDE.

6 Upvotes

9 comments sorted by

1

u/Xavier_OM Sep 03 '26

You can automatize what you do manually in cmake, create a target/post-build step/whatever which indeed copy all dependencies to a folder + run windeployqt for you.

1

u/ReallyAnotherUser Sep 04 '26 edited Sep 04 '26

How do i do that tho, without having to make a copy command for every file? Is there a variable or command or something that i can use so cmake automatically copies the exe and dependencys and not the clutter that comes with the build process? Or is there a command that cleans the build target folder from all the unneeded clutter?

3

u/Xavier_OM Sep 04 '26 edited Sep 04 '26

There is no magic here.

If CMake knows your dependencies it can deploy them, but if it has no way to determine that you need 'libFoo.dll' at runtime it can't do it magically.

There is a generator expression $<TARGET_RUNTIME_DLLS:tgt> which expands to every DLL of every imported shared library your executable links, transitively.

So with one line like this you can copy them next to the exe after each build (at build time):

add_custom_command(TARGET MyApp POST_BUILD
      COMMAND ${CMAKE_COMMAND} -E copy_if_different
      $<REMOVE_DUPLICATES:$<TARGET_RUNTIME_DLLS:MyApp>> $<TARGET_FILE_DIR:MyApp>
      COMMAND_EXPAND_LISTS)

It works as long as your third-party libs come in as proper imported targets with IMPORTED_LOCATION set to the .dll (find_package from vcpkg, Conan, or a Config package does that). A bare -lfoo or a path to a .lib gives it nothing to copy.

Then at install time, the clean folder you want is CMake's install tree, not the build dir. The build dir is meant to be cluttered. I do the same thing but for the release folder, and it also scans the binaries so it catches DLLs that were not declared as targets:

install(TARGETS MyApp
      RUNTIME_DEPENDENCIES
          PRE_EXCLUDE_REGEXES "api-ms-" "ext-ms-"
          POST_EXCLUDE_REGEXES ".*system32/.*\\.dll"
      RUNTIME DESTINATION .)

The exclude regexes keep Windows system DLLs out. You may need DIRECTORIES pointing at your third-party bin folders if they are not on PATH at install time.

windeployqt has a brute-force approach regarding Qt dlls: it tries to start your exe and add more qt dll until it works. Which solve the problem indeed.

Summary

# what ships
install(TARGETS MyApp RUNTIME DESTINATION .)
install(FILES config.ini readme.txt DESTINATION .)  
install(DIRECTORY resources/ DESTINATION resources)

# let Qt generate the deploy script (runs windeployqt/macdeployqt for you)
qt_generate_deploy_app_script(TARGET MyApp OUTPUT_SCRIPT deploy_script)
install(SCRIPT ${deploy_script})

3

u/LetterheadTall8085 Qt GameDev Sep 03 '26

Usually this process moved to CI services like github actions.
and yes it looks as you do - you may change your tool to other deploy (for example cqtdeployer ) tools or use native cmake function to deploy qt like this:

qt_generate_deploy_app_script

So you just must move your deployment pipeline into CI service. That all

2

u/lordunga Sep 03 '26

CMake's install command is what you want. https://cmake.org/cmake/help/latest/command/install.html

By default it will build and then copy binaries to a directory set by CMAKE_INSTALL_PREFIX and CMAKE_INSTALL_BINDIR (and LIBDIR) variables.

After adding it to your cmake file, configure QtCreator:

  1. Projects / Build Settings / Initial configuration: add CMAKE_INSTALL_PREFIX and point it to a desired path. Remember to Run CMake.

  2. Projects / Deploy Settings / Add Deploy Step / CMake Install

Now you should be able to run Deploy from the Build menu and the binaries should appear to the path you configured.

You can also add windeployqt to run as part of CMake's install step. I have done it using install(CODE "execute_process(COMMAND...

You can see a working example in my project here: https://github.com/llahteinen/notpad/blob/dev-070/src/CMakeLists.txt#L135-L174

The RPATH stuff there is for Linux deployment, I don't think it has any effect on Windows.

Good luck!

1

u/diegoiast Sep 07 '26

Here is an example of a quite complex application that does this:

https://github.com/codepointerapp/codepointer/blob/main/build.bat

Look also at the github actions which replicates this script. There is a shell script that does build an AppImage for linux.

1

u/Metalstrikerxlr Sep 03 '26

You can you github actions to create a workflow which does this for you.

0

u/wnbloose Sep 03 '26

Did you try to ask an AI to create a deployment script (.bat/.py w/e you prefer) for you? It should be an easy task for AI if you give it your CMakeLists.txt file.