'CMake - Copy DLLs to the runtime output directory
I am trying to create a simple CMake that retrieves the DLLs of Qt and copy it in the directory in which cmake creates my executable.
It works great using g++ or clang, but MSVC (Visual Studio 2017) creates a Debug or Release directory.
I can't find a way to retrieve the path to the real directory in which the executable is written (${CMAKE_CURRENT_BINARY_DIR} returns the directory parent of Release or Debug).
I've seen people using the target property RUNTIME_OUTPUT_DIRECTORY but it is empty when I use it.
Any idea how I can do this ? I do not want to change the output directory, I just want to know its path (so I do not want to change the value of RUNTIME_OUTPUT_DIRECTORY)
Thanks!
Solution 1:[1]
As of CMake 3.21+, the $<TARGET_RUNTIME_DLLS:tgt> generator expression can help copy dependent DLLs to the build tree. Quoting the documentation:
List of DLLs that the target depends on at runtime. This is determined by the locations of all the
SHAREDandMODULEtargets in the target's transitive dependencies. Using this generator expression on targets other than executables,SHAREDlibraries, andMODULElibraries is an error. On non-DLL platforms, it evaluates to an empty string.This generator expression can be used to copy all of the DLLs that a target depends on into its output directory in a
POST_BUILDcustom command.
An example of how to use this (adapted from the docs) follows:
find_package(foo REQUIRED)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE foo::foo)
if (WIN32)
add_custom_command(
TARGET main POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_RUNTIME_DLLS:main> $<TARGET_FILE_DIR:main>
COMMAND_EXPAND_LISTS
)
endif ()
The if (WIN32) check ensures that $<TARGET_RUNTIME_DLLS:main> won't be empty, which would cause the command to fail (rather than do nothing). COMMAND_EXPAND_LISTS makes sure that the semicolon-delimited list returned by $<TARGET_RUNTIME_DLLS:main> will be split into multiple arguments, rather than passed as a single argument with (escaped) semicolons in it.
Note also that UNKNOWN libraries will be ignored by this generator expression. These are common when using the built-in Find modules, rather than using a library's first-party CMake config-mode package. In these cases, you will have to manually inspect the module variables to find the library paths and add custom commands for each one yourself.
For Qt specifically, I would expect the newer CMake integration in Qt6 to "just work", though I haven't tested it. It might also work in Qt5, but again I haven't tested it.
Solution 2:[2]
Delete related themes and styles, usually under the path: "values-night-v31" and "values-v31"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alex Reinking |
| Solution 2 | Zheng |
