Issue
I have distilled this very simple CMake project that uses vcpkg and builds a dead simple Qt gui application just showing a main window. I can get it to build successfully in Visual Studio 2022 but I cannot get it to run seamlessly. The problem arises because the Qt platform DLL isn't copied to the output location with the other DLL dependencies in the post build step.
The qwindows.dll
(or qwindowsd.dll
) file is meant to be copied to the output location with the executable and other DLLs but in a platforms\
subdirectory. This does not happen during a build, but if I create the directory and copy it manually then the application works.
To me this is something that should work seamlessly as part of the build process so I'm curious to know if I'm doing something wrong or I've set something up incorrectly.
Now I know that the simplest hacky solution would be to manually put a CMake post build step to copy the appropriate DLL from the vcpkg_installed
directory to the output directory. But this seems like a hack as the system should handle this already otherwise many other people would be having this issue as well.
So the questions I'm asking:
- Am I missing something trivial here in the configuration?
- Am I not understanding something with how CMake + Qt work?
- Is this combination of CMake, vcpkg, and Qt a supported configuration that is expected to work?
The CMakeLists.txt
is (and mostly taken from Qt's own example):
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(QtTest LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
qt_standard_project_setup()
add_executable(QtGuiTest
Source/Main.cpp
Source/MainWindow.cpp
Source/MainWindow.hpp
)
target_link_libraries(QtGuiTest PRIVATE Qt6::Core Qt6::Gui Qt6::Widgets)
set_target_properties(QtGuiTest PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON)
The CMakePresets.json
is:
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 22,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default",
"generator": "Visual Studio 17 2022",
"architecture": "x64",
"toolchainFile": "$env{VCPKG_ROOT}\\scripts\\buildsystems\\vcpkg.cmake"
}
]
}
The vcpkg.json
is:
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"name": "qtguitest",
"version": "0.1",
"dependencies": [
"qtbase"
]
}
Then I execute CMake to build out of the source tree with the default
preset.
The code for the application is literally this:
// MainWindow.hpp
#pragma once
#include <QtGui>
class MainWindow : public QWindow
{
Q_OBJECT
public:
explicit MainWindow(QWindow* parent = nullptr);
};
// MainWindow.cpp
#include "MainWindow.hpp"
MainWindow::MainWindow(QWindow* parent)
: QWindow(parent)
{}
// Main.cpp
#include <QApplication>
#include "MainWindow.hpp"
int main(int argc, char* argv[])
{
QApplication q_application{argc, argv};
MainWindow main_window;
main_window.show();
return q_application.exec();
}
For reference I'm using:
- The latest Visual Studio 2022 Community Edition (as of 1/10/2022)
- CMake 3.22 installed (though vcpkg downloads 3.24 and uses that)
- vcpkg (as of 1/10/2022)
- Qt 6.3.2 is being installed
Solution
Thanks to help from the other answers here I was able to figure this snippet out to add to the CMake configuration I had above.
add_custom_command(TARGET QtGuiTest POST_BUILD
COMMAND Qt6::windeployqt
ARGS $<TARGET_FILE:QtGuiTest>
)
Which ends up calling the windeployqt
application in the simplest manner in a post-build step.
Answered By - Dominik Grabiec Answer Checked By - Mildred Charles (WPSolving Admin)