Never said it was pretty, but here is the code I use for Qt4 based projects. I think I had to revamp a lot of this for Qt5. I call it like so:
CMP_COPY_QT4_RUNTIME_LIBRARIES( "QtCore;QtGui;QtNetwork") # -------------------------------------------------------------------- #-- Copy all the Qt4 dependent DLLs into the current build directory so that #-- one can debug an application or library that depends on Qt4 libraries. #-- This macro is really intended for Windows Builds because windows libraries #-- do not have any type of rpath or install_name encoded in the libraries so #-- the least intrusive way to deal with the PATH issues is to just copy all #-- the dependend DLL libraries into the build directory. Note that this is #-- NOT needed for static libraries. macro(CMP_COPY_QT4_RUNTIME_LIBRARIES QTLIBLIST) # message(STATUS "CMP_COPY_QT4_RUNTIME_LIBRARIES") set(SUPPORT_LIB_OPTION 1) if(MSVC_IDE) set(SUPPORT_LIB_OPTION 0) elseif(APPLE) # Apple systems do NOT need this so just skip this entirely set(SUPPORT_LIB_OPTION 2) elseif(UNIX AND NOT MSVC) set(SUPPORT_LIB_OPTION 3) endif() if(NOT DEFINED QT_QMAKE_EXECUTABLE) message(FATAL_ERROR "Qt is REQUIRED to use this Function or macro. Make sure Qt is found on your system.") endif() if(SUPPORT_LIB_OPTION EQUAL 0) set(TYPE "d") FOREACH(qtlib ${QTLIBLIST}) GET_FILENAME_COMPONENT(QT_DLL_PATH_tmp ${QT_QMAKE_EXECUTABLE} PATH) # message(STATUS "CMAKE_GENERATOR: ${CMAKE_GENERATOR}") # We need to copy both the Debug and Release versions of the libraries into their respective # subfolders for Visual Studio builds add_custom_target(ZZ_${qtlib}-Debug-Copy ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_DLL_PATH_tmp}/${qtlib}${TYPE}4.dll ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/ COMMENT "Copying ${qtlib}${TYPE}4.dll to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/") set_target_properties(ZZ_${qtlib}-Debug-Copy PROPERTIES FOLDER ZZ_COPY_FILES) # message(STATUS "Generating Copy Rule for Qt Release DLL Library ${QT_DLL_PATH_tmp}/${qtlib}d4.dll") add_custom_target(ZZ_${qtlib}-Release-Copy ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_DLL_PATH_tmp}/${qtlib}4.dll ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/ COMMENT "Copying ${qtlib}4.dll to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/") set_target_properties(ZZ_${qtlib}-Release-Copy PROPERTIES FOLDER ZZ_COPY_FILES) ENDFOREACH(qtlib) elseif(SUPPORT_LIB_OPTION EQUAL 1) set(TYPE "") if( ${CMAKE_BUILD_TYPE} STREQUAL "Debug") set(TYPE "d") endif() FOREACH(qtlib ${QTLIBLIST}) GET_FILENAME_COMPONENT(QT_DLL_PATH_tmp ${QT_QMAKE_EXECUTABLE} PATH) #message(STATUS "Generating Copy Rule for Qt DLL: ${QT_DLL_PATH_tmp}/${qtlib}d4.dll") add_custom_target(ZZ_${qtlib}-Debug-Copy ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QT_DLL_PATH_tmp}/${qtlib}${TYPE}4.dll ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ COMMENT "Copying ${qtlib}${TYPE}4.dll to ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/") set_target_properties(ZZ_${qtlib}-Debug-Copy PROPERTIES FOLDER ZZ_COPY_FILES) ENDFOREACH(qtlib) endif() endmacro() On Oct 31, 2014, at 3:37 PM, Robert Dailey <rcdailey.li...@gmail.com> wrote: > If it were only a matter of style / visual annoyance, I wouldn't mind. > However it complicates dependency management when you have to specify > "ZZ_QT_LIB1", "ZZ_QT_LIB2", etc... instead of just "QT" when calling > target_link_libraries(). > > Unless you do it differently... > > On Fri, Oct 31, 2014 at 2:28 PM, Michael Jackson > <mike.jack...@bluequartz.net> wrote: >> It sucks, but I do that with Qt's libraries. One target for each library. I >> prefix the target with "ZZ_" so that in IDEs like Visual Studio and Xcode >> those targets fall to the bottom of the list. I also group them in folders >> if Visual Studio will allow it. I use the "copy if different" argument to >> the CMake command for the copy. Seems to work. >> >> Mike Jackson >> >> On Oct 31, 2014, at 3:11 PM, Robert Dailey <rcdailey.li...@gmail.com> wrote: >> >>> I like this idea but it doesn't seem like it will work for targets >>> with multiple DLLs... for example boost. It has several DLLs. I don't >>> want to define 1 target for each DLL either. Sometimes that doesn't >>> make sense. >>> >>> On Wed, Oct 29, 2014 at 10:45 AM, Hendrk Sattler >>> <p...@hendrik-sattler.de> wrote: >>>> Am 2014-10-28 18:25, schrieb Robert Dailey: >>>>> >>>>> I have a third party library like OpenSSL prebuilt for each platform >>>>> and in my own structure in version control. I have a CMake script that >>>>> creates an INTERFACE library target for it. I setup the include >>>>> directories and link targets. However, I don't see a way to configure >>>>> DLLs in the interface library target. How would you do this, and what >>>>> would CMake do to these targets to make sure they are copied to the >>>>> output directory of the executable I run from Visual Studio for >>>>> debugging? >>>> >>>> >>>> I have this for ZLib: >>>> if ( ZLIB_FOUND ) >>>> if ( WIN32 ) >>>> get_filename_component( ZLIB_LIBDIR "${ZLIB_LIBRARY}" PATH ) >>>> get_filename_component ( ZLIB_BASENAME "${ZLIB_LIBRARY}" NAME_WE ) >>>> get_filename_component ( ZLIB_LIBDIR_BASE "${ZLIB_LIBDIR}" PATH ) >>>> find_file ( ZLIB_DLL >>>> "${CMAKE_SHARED_LIBRARY_PREFIX}${ZLIB_BASENAME}${CMAKE_SHARED_LIBRARY_SUFFIX}" >>>> HINTS >>>> "${ZLIB_LIBDIR_BASE}" >>>> PATH_SUFFIXES >>>> bin >>>> NO_DEFAULT_PATH >>>> ) >>>> mark_as_advanced ( ZLIB_DLL ) >>>> if ( ZLIB_DLL ) >>>> add_library ( zlib SHARED IMPORTED GLOBAL ) >>>> set_property ( TARGET zlib PROPERTY IMPORTED_IMPLIB "${ZLIB_LIBRARY}" >>>> ) >>>> set_property ( TARGET zlib PROPERTY IMPORTED_LOCATION "${ZLIB_DLL}" ) >>>> else ( ZLIB_DLL ) >>>> add_library ( zlib STATIC IMPORTED GLOBAL ) >>>> set_property ( TARGET zlib PROPERTY IMPORTED_LOCATION >>>> "${ZLIB_LIBRARY}" ) >>>> endif ( ZLIB_DLL ) >>>> else( WIN32 ) >>>> add_library ( zlib UNKNOWN IMPORTED GLOBAL ) >>>> set_property ( TARGET zlib PROPERTY IMPORTED_LOCATION "${ZLIB_LIBRARY}" >>>> ) >>>> endif( WIN32 ) >>>> set_property ( TARGET zlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES >>>> "${ZLIB_INCLUDE_DIR}" >>>> ) >>>> >>>> set ( ZLIB_LIBRARIES zlib ) >>>> set ( ZLIB_INCLUDE_DIRS "${ZLIB_INCLUDE_DIR}" ) >>>> endif ( ZLIB_FOUND ) >>>> >>>> The .lib goes into IMPORTED_IMPLIB and the .dll goes into >>>> IMPORTED_LOCATION. >>>> The way to find the .dll from the location of the .lib might differ for >>>> different libraries. >>>> For ZLib, the base name is the same. >>>> >>>> Later, you can use this imported target: >>>> add_custom_command ( TARGET myTarget POST_BUILD >>>> COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:zlib> >>>> $<TARGET_FILE_DIR:myTarget> >>>> ) >>>> Now, zlib.dll is in the same directory as myTarget.dll. >>>> >>>> HS >>>> >>>>> On Tue, Oct 28, 2014 at 12:21 AM, Hendrik Sattler >>>>> <p...@hendrik-sattler.de> wrote: >>>>>> >>>>>> Hi, >>>>>> >>>>>> you can use generator expression in a post build rule to copy the dll >>>>>> file to the same target dir as the target you link it with. The easiest >>>>>> way >>>>>> to do this is to properly define all 3rd party libraries as imported >>>>>> targets >>>>>> that contains both, the lib and the dll file. >>>>>> Sadly, the FindQt4 on Windows doesn't do this and thus make life harder >>>>>> than needed. CMake configuration files should always do this right. >>>>>> >>>>>> OTOH, you could also write a wrapper batch file or change VS properties >>>>>> to modify PATH to include all libraries before the regular path. >>>>>> >>>>>> HS >>>>>> >>>>>> >>>>>> Am 28. Oktober 2014 02:55:08 MEZ, schrieb Robert Dailey >>>>>> <rcdailey.li...@gmail.com>: >>>>>>> >>>>>>> This actually used to be a very difficult problem to solve. However, >>>>>>> to debug in visual studio it's essential. >>>>>>> >>>>>>> If I have DLLs located in third party directories OR from targets that >>>>>>> I depend on, those must all be copied to the directory of the >>>>>>> executable I'm debugging in order for those DLLs to be found and >>>>>>> loaded. >>>>>>> >>>>>>> Using CMake 3.0.2, I hope this task is simpler, especially with the >>>>>>> introduction of a nice suite of generator expressions. Can anyone >>>>>>> recommend a good way to do this? >>>>>> >>>>>> >>>>> -- >>>>> >>>>> Powered by www.kitware.com >>>>> >>>>> Please keep messages on-topic and check the CMake FAQ at: >>>>> http://www.cmake.org/Wiki/CMake_FAQ >>>>> >>>>> Kitware offers various services to support the CMake community. For >>>>> more information on each offering, please visit: >>>>> >>>>> CMake Support: http://cmake.org/cmake/help/support.html >>>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html >>>>> CMake Training Courses: http://cmake.org/cmake/help/training.html >>>>> >>>>> Visit other Kitware open-source projects at >>>>> http://www.kitware.com/opensource/opensource.html >>>>> >>>>> Follow this link to subscribe/unsubscribe: >>>>> http://public.kitware.com/mailman/listinfo/cmake >>>> >>>> -- >>>> >>>> Powered by www.kitware.com >>>> >>>> Please keep messages on-topic and check the CMake FAQ at: >>>> http://www.cmake.org/Wiki/CMake_FAQ >>>> >>>> Kitware offers various services to support the CMake community. For more >>>> information on each offering, please visit: >>>> >>>> CMake Support: http://cmake.org/cmake/help/support.html >>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html >>>> CMake Training Courses: http://cmake.org/cmake/help/training.html >>>> >>>> Visit other Kitware open-source projects at >>>> http://www.kitware.com/opensource/opensource.html >>>> >>>> Follow this link to subscribe/unsubscribe: >>>> http://public.kitware.com/mailman/listinfo/cmake >>> -- >>> >>> Powered by www.kitware.com >>> >>> Please keep messages on-topic and check the CMake FAQ at: >>> http://www.cmake.org/Wiki/CMake_FAQ >>> >>> Kitware offers various services to support the CMake community. For more >>> information on each offering, please visit: >>> >>> CMake Support: http://cmake.org/cmake/help/support.html >>> CMake Consulting: http://cmake.org/cmake/help/consulting.html >>> CMake Training Courses: http://cmake.org/cmake/help/training.html >>> >>> Visit other Kitware open-source projects at >>> http://www.kitware.com/opensource/opensource.html >>> >>> Follow this link to subscribe/unsubscribe: >>> http://public.kitware.com/mailman/listinfo/cmake >> >> -- >> >> Powered by www.kitware.com >> >> Please keep messages on-topic and check the CMake FAQ at: >> http://www.cmake.org/Wiki/CMake_FAQ >> >> Kitware offers various services to support the CMake community. For more >> information on each offering, please visit: >> >> CMake Support: http://cmake.org/cmake/help/support.html >> CMake Consulting: http://cmake.org/cmake/help/consulting.html >> CMake Training Courses: http://cmake.org/cmake/help/training.html >> >> Visit other Kitware open-source projects at >> http://www.kitware.com/opensource/opensource.html >> >> Follow this link to subscribe/unsubscribe: >> http://public.kitware.com/mailman/listinfo/cmake -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake