Jehjoa
Jehjoa

Reputation: 561

Copying Qt DLLs to executable directory on Windows using CMake

New to CMake, and I'm having a hard time understanding how to use generator expressions. I'm trying to use add_custom_command to create a post-build command to copy Qt DLLs to the executable directory.

In Qt5WidgetsConfig.cmake I can see it creates different properties for the Qt5::Widgets target to refer to the DLL, depending on the currently active configuration. Either IMPORTED_LOCATION_DEBUG or IMPORTED_LOCATION_RELEASE. I expected to be able to use the $<CONFIG:Debug> generator expression as a condition in an if() but that doesn't work.

My CMakeLists.txt:

# minimum version required for proper support of C++11 features in Qt
cmake_minimum_required(VERSION 3.1.0)

set(CMAKE_CONFIGURATION_TYPES Debug;Release)

# project name and version
project(TPBMon VERSION 0.0.0.1)

# Qt5 libs
find_package(Qt5Widgets REQUIRED)

# run Qt's MOC when needed
set(CMAKE_AUTOMOC ON)

add_executable(
    tpbmon
    src/main.cpp
    src/mainwindow.hpp
    src/mainwindow.cpp
)
target_link_libraries(tpbmon Qt5::Widgets)
set_target_properties(
    tpbmon
    PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin
)
if(WIN32)
    if($<CONFIG:Debug>)
        get_target_property(WIDGETDLL Qt5::Widgets IMPORTED_LOCATION_DEBUG)
    else($<CONFIG:Debug>)
        get_target_property(WIDGETDLL Qt5::Widgets IMPORTED_LOCATION_RELEASE)
    endif($<CONFIG:Debug>)
    add_custom_command(
        TARGET tpbmon POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy ${WIDGETDLL} $<TARGET_FILE_DIR:tpbmon>
    )
endif(WIN32)

Upvotes: 8

Views: 9845

Answers (3)

irbis
irbis

Reputation: 31

For the future you can add all Qt5 dependencies to your executable folder:

 find_package(Qt5 COMPONENTS Core Gui Widgets)
 ...   
 add_custom_command(TARGET MyQtProj POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:MyQtProj>
        COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:MyQtProj>
        COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:MyQtProj>
        )

Upvotes: 3

jiandingzhe
jiandingzhe

Reputation: 2121

You can use windeployqt program which is part of Qt binary release. It will scan your binary and collect all used Qt DLLs, plugins and QML modules. It could be wrapped in CMake as a post-build event by add_custom_command(TARGET target_name POST_BUILD ...) signature.

Upvotes: 9

Jehjoa
Jehjoa

Reputation: 561

Figured it out myself by modifying the add_custom_command call to

add_custom_command(
    TARGET tpbmon POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        $<TARGET_FILE:Qt5::Widgets>
        $<TARGET_FILE_DIR:tpbmon>
)

It's amazing what a fresh perspective after a good night's sleep can do. ;)

Upvotes: 14

Related Questions