Skip to content

Instantly share code, notes, and snippets.

@Rod-Persky
Last active January 31, 2024 12:57
Show Gist options
  • Star 31 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save Rod-Persky/e6b93e9ee31f9516261b to your computer and use it in GitHub Desktop.
Save Rod-Persky/e6b93e9ee31f9516261b to your computer and use it in GitHub Desktop.
Example cmake for windows including auto copy dll
# _______ __ __ _______ ______ _______ _______ _______ ______ #
#| || | | || || | | _ || || || | #
#| _ || | | ||_ _|| _ || |_| ||_ _|| ___|| _ |#
#| | | || |_| | | | | | | || | | | | |___ | | | |#
#| |_| || | | | | |_| || | | | | ___|| |_| |#
#| || | | | | || _ | | | | |___ | |#
#|_______||_______| |___| |______| |__| |__| |___| |_______||______| #
# #
# Modern CMake practices and importing the QT scripts by adding it to #
# your module path makes things a lot better than it used to be #
cmake_minimum_required(VERSION 2.8.11)
project(testproject)
set(CMAKE_PREFIX_PATH "C:/Qt/5.3/msvc2013_64/lib/cmake")
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
# Find the QtWidgets library
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
QT5_WRAP_UI(UI_HEADERS mainwindow.ui)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} )
# Tell CMake to create the helloworld executable
add_executable(helloworld main.cpp mainwindow.cpp ${UI_HEADERS})
target_link_libraries(helloworld Qt5::Widgets)
add_custom_target(Qt5CopyBinaries
# todo: check if debug and release folder exist
# debug version
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/libEGLd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/libGLESv2d.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Cored.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Guid.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Declaratived.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Networkd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5OpenGLd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Scriptd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Sqld.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Widgetsd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Xmld.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5XmlPatternsd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuin52.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuuc52.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icudt52.dll ${CMAKE_BINARY_DIR}/Debug
# release version
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/libEGL.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/libGLESv2.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Core.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Gui.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Declarative.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Network.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5OpenGL.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Script.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Sql.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Widgets.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Xml.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5XmlPatterns.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuin52.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuuc52.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icudt52.dll ${CMAKE_BINARY_DIR}/Release
# Output Message
COMMENT "Copying Qt binaries from '${Qt5Core_DIR}/../../bin/' to '${CMAKE_BINARY_DIR}'" VERBATIM
)
add_dependencies(helloworld Qt5CopyBinaries)
Copy link

ghost commented Aug 21, 2015

I see you have a TODO in your file. What you can do is to do a custom_command instead of a custom target and execute it after building is done, with that you avoid checking if Debug/Release exists and the add_dependencies is not needed anymore. Here is what I did

ADD_CUSTOM_COMMAND (TARGET MyApp POST_BUILD
# DEBUG
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Sqld.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Widgetsd.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuin51.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuuc51.dll ${CMAKE_BINARY_DIR}/Debug
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icudt51.dll ${CMAKE_BINARY_DIR}/Debug

# RELEASE
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Sql.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/Qt5Widgets.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuin51.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icuuc51.dll ${CMAKE_BINARY_DIR}/Release
COMMAND ${CMAKE_COMMAND} -E copy ${Qt5Core_DIR}/../../../bin/icudt51.dll ${CMAKE_BINARY_DIR}/Release

# Output Message
COMMENT "Copying Qt binaries" VERBATIM)

Hope that helps

@sploner
Copy link

sploner commented Sep 12, 2016

Here are some further changes to the add_custom_command part:

  • Copy Debug and Release dlls only when the according build configuration is selected
  • Get the dll file paths through ...Config.cmake files
  • cmake -E copy_if_different instead of cmake -E copy
# find the release *.dll file
get_target_property(Qt5_CoreLocation Qt5::Core LOCATION)
# find the debug *d.dll file
get_target_property(Qt5_CoreLocationDebug Qt5::Core IMPORTED_LOCATION_DEBUG)
# 
add_custom_command(TARGET MyApp POST_BUILD
                   COMMAND ${CMAKE_COMMAND} -E copy_if_different $<$<CONFIG:Debug>:${Qt5_CoreLocationDebug}> $<$<NOT:$<CONFIG:Debug>>:${Qt5_CoreLocation}> $<TARGET_FILE_DIR:MyApp>)

@KindDragon
Copy link

KindDragon commented Nov 14, 2016

Rewrited as macros

macro(qt5_copy_dll APP DLL)
    # find the release *.dll file
    get_target_property(Qt5_${DLL}Location Qt5::${DLL} LOCATION)
    # find the debug *d.dll file
    get_target_property(Qt5_${DLL}LocationDebug Qt5::${DLL} IMPORTED_LOCATION_DEBUG)

    add_custom_command(TARGET ${APP} POST_BUILD
       COMMAND ${CMAKE_COMMAND} -E copy_if_different $<$<CONFIG:Debug>:${Qt5_${DLL}LocationDebug}> $<$<NOT:$<CONFIG:Debug>>:${Qt5_${DLL}Location}> $<TARGET_FILE_DIR:${APP}>)
endmacro()

qt5_copy_dll(MyApp Core)

@KindDragon
Copy link

My solution to using app windeployqt instead

if (WIN32)
    get_target_property(QT5_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION)
    get_filename_component(QT5_WINDEPLOYQT_EXECUTABLE ${QT5_QMAKE_EXECUTABLE} PATH)
    set(QT5_WINDEPLOYQT_EXECUTABLE "${QT5_WINDEPLOYQT_EXECUTABLE}/windeployqt.exe")

    add_custom_command(TARGET foot_scanner POST_BUILD
       COMMAND ${QT5_WINDEPLOYQT_EXECUTABLE} --qmldir ${CMAKE_SOURCE_DIR} $<TARGET_FILE_DIR:foot_scanner>)
endif(WIN32)

@jcelerier
Copy link

This could be simplified quite a bit with

COMMAND ${CMAKE_COMMAND} -E copy_if_different
    $<TARGET_FILE:Qt5::Core>
    $<TARGET_FILE:Qt5::Widgets>
    ... etc ... 

instead

@aaichert
Copy link

aaichert commented Jul 19, 2017

So now I have all the right files in one place. But I still want things copied upon INSTALL. How would I achieve that?

.... elegantly, that is.

@cboulay
Copy link

cboulay commented Aug 23, 2017

@aaichert , I don't know if this qualifies as 'elegant' for you, but I found this code that works for me. I put it in a macro that I use for my apps.

@DineshRajanT
Copy link

This could be simplified quite a bit with

COMMAND ${CMAKE_COMMAND} -E copy_if_different
    $<TARGET_FILE:Qt5::Core>
    $<TARGET_FILE:Qt5::Widgets>
    ... etc ... 

instead

How can I link opencv dll like this?

@Anton-V-K
Copy link

Beware that qml-related dependencies aren't covered by this script, and the app will fail to run, unless you use windeployqt.exe to copy all necessary modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment