How to copy Qt runtime DLLs to project output

后端 未结 4 1294
生来不讨喜
生来不讨喜 2021-02-01 15:46

I have a simple project created in Qt Creator (installed using Qt SDK 1.1.4). It runs just fine from within Qt Creator, but if I then browse to the output directory in Windows

相关标签:
4条回答
  • 2021-02-01 15:58

    I ran into the same problem and jwernerny's solution helped me a lot. However, I was using Shadow Build on Window 7 and it needed a bit more tweeking.

    I also needed to set the DESTDIR according to the current configuration.

    In my case I wanted to copy *.qml files, that's how I achieved it:

    CONFIG(release, debug|release): DESTDIR = $$OUT_PWD/release
    CONFIG(debug, debug|release): DESTDIR = $$OUT_PWD/debug
    
    QmlFiles.path = $$DESTDIR/Qml
    QmlFiles.files += $$files(Qml/*.qml)
    
    INSTALLS += QmlFiles
    

    EDIT :

    Since I use Shadow Build I need to use $$OUT_PWD to get the output folder.

    0 讨论(0)
  • 2021-02-01 16:14

    OK, here's an ugly hack:

    # Copy required DLLs to output directory
    CONFIG(debug, debug|release) {
        QtCored4.commands = copy /Y %QTDIR%\\bin\\QtCored4.dll debug
        QtCored4.target = debug/QtCored4.dll
        QtGuid4.commands = copy /Y %QTDIR%\\bin\\QtGuid4.dll debug
        QtGuid4.target = debug/QtGuid4.dll
    
        QMAKE_EXTRA_TARGETS += QtCored4 QtGuid4
        PRE_TARGETDEPS += debug/QtCored4.dll debug/QtGuid4.dll
    } else:CONFIG(release, debug|release) {
        QtCore4.commands = copy /Y %QTDIR%\\bin\\QtCore4.dll release
        QtCore4.target = release/QtCore4.dll
        QtGui4.commands = copy /Y %QTDIR%\\bin\\QtGui4.dll release
        QtGui4.target = release/QtGui4.dll
    
        QMAKE_EXTRA_TARGETS += QtCore4 QtGui4
        PRE_TARGETDEPS += release/QtCore4.dll release/QtGui4.dll
    } else {
        error(Unknown set of dependencies.)
    }
    

    Here's some of what I don't like about it:

    • Uses %QTDIR% environment variable; this variable isn't evaluated until the copy command is actually run. Seems like something along the lines of QMAKE_LIBS_QT_DLL would be more appropriate, but I couldn't get that working for some reason.
    • Hard-coded "debug" and "release" names; seems like there ought to be some kind of variable to use for that.
    • Calling out to the environment by using the "copy" command.

    I'll accept another answer if somebody can clean this up a good bit, for example by shortening it and/or addressing some of my concerns, or just finding a better way in general.

    0 讨论(0)
  • 2021-02-01 16:16

    A bit cleaner method, but it will require doing a make install after a make. It will work on Windows, but would need tweaking for other platforms.

    debug { DESTDIR = debug }
    release { DESTDIR = release }
    debug_and_release { DESTDIR = bin }
    
    myqtlibs.path = $$DESTDIR
    myqtlibs.files = $$QMAKE_LIBDIR_QT/*.dll junk.txt fred.out
    myqtlibs.CONFIG = no_check_exist
    
    INSTALLS += myqtlibs
    

    If qmake is run just for debug, all output will go into ./debug . If it is just for release, all output goes in ./release . If both, then into ./bin .

    I did notice that enabling shadow building in QtCreator caused the executable not to end up in the DESTDIR. I'm not quite sure why.

    0 讨论(0)
  • 2021-02-01 16:16

    Copy Dependencies with windeployqt

    # Deployment - Automatically Detect and Copy Dependencies to Build Folder
    
    TARGET_CUSTOM_EXT = .exe
    DEPLOY_COMMAND = windeployqt
    
    DEPLOY_OPTIONS = "--no-svg --no-system-d3d-compiler --no-opengl --no-angle --no-opengl-sw"
    
    CONFIG( debug, debug|release ) {
        # debug
        DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/debug/$${TARGET}$${TARGET_CUSTOM_EXT}))
        DEPLOY_OPTIONS += "--debug"
    } else {
        # release
        DEPLOY_TARGET = $$shell_quote($$shell_path($${OUT_PWD}/release/$${TARGET}$${TARGET_CUSTOM_EXT}))
        DEPLOY_OPTIONS += "--release"
    }
    
    # Uncomment the following line to help debug the deploy command when running qmake
    #message($${DEPLOY_COMMAND} $${DEPLOY_OPTIONS} $${DEPLOY_TARGET})
    
    QMAKE_POST_LINK = $${DEPLOY_COMMAND} $${DEPLOY_OPTIONS} $${DEPLOY_TARGET}
    

    or Copy dependencies manually

    # Deployment - Copy Dependencies to Build Folder
    
    dlls.path  =  $${DESTDIR}
    dlls.files += $$[QT_INSTALL_BINS]/icudt51.dll
    dlls.files += $$[QT_INSTALL_BINS]/icuin51.dll
    dlls.files += $$[QT_INSTALL_BINS]/icuuc51.dll
    dlls.files += $$[QT_INSTALL_BINS]/libgcc_s_dw2-1.dll
    dlls.files += $$[QT_INSTALL_BINS]/libstdc++-6.dll
    dlls.files += $$[QT_INSTALL_BINS]/libwinpthread-1.dll
    dlls.files += $$[QT_INSTALL_BINS]/Qt5Core.dll
    dlls.files += $$[QT_INSTALL_BINS]/Qt5Network.dll
    dlls.files += $$[QT_INSTALL_BINS]/Qt5Gui.dll
    dlls.files += $$[QT_INSTALL_BINS]/Qt5Widgets.dll
    dllA.path   += $${DESTDIR}/platforms
    dllA.files  += $$[QT_INSTALL_PLUGINS]/platforms/qwindows.dll
    dllB.path   += $${DESTDIR}/plugins/imageformats/
    dllB.files  += $$[QT_INSTALL_PLUGINS]/imageformats/qico.dll
    dllB.files  += $$[QT_INSTALL_PLUGINS]/imageformats/qwbmp.dll
    INSTALLS   += dlls dllA dllB
    

    Referencing: http://doc.qt.io/qt-5/qmake-variable-reference.html#deployment


    In case you need to identify prerequisites / dependencies cross-platform, please take a look at CMake's getPrerequisites(). It uses dumpbin, objbin, ldd, otool for the identification of dependencies.

    Referencing: https://cmake.org/cmake/help/v3.0/module/GetPrerequisites.html

    0 讨论(0)
提交回复
热议问题