How to copy Qt runtime DLLs to project output

James Johnston picture James Johnston · Dec 5, 2011 · Viewed 15.2k times · Source

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 and double-click the EXE, I'll get an error like:

The program can't start because QtCored4.dll is missing from your computer.
Try reinstalling the program to fix this problem.

That's obviously because Qt isn't in my PATH (and I don't want it to be, in case I have multiple versions of Qt on my computer), and Qt Creator / qmake didn't copy the Qt DLLs to the project output.

What I would like to do is use qmake to copy the necessary Qt files to the project output directory - wherever it may be. How do I do this?

(I tried creating a custom target in qmake, but I'm not getting too far...)

UPDATE July 19, 2016: Just to clarify, the above post was concerning Qt4. On Qt5, you should instead look into calling windeployqt. This Qt5 tool will read your binary, determine which Qt5 runtime files you need, and copy them to your binary directory. Also note that it will fix absolute paths in the Qt5::Core library that are specific to your PC - so use of this tool is basically mandatory unless you want to provide a qt.conf file yourself.

Answer

James Johnston picture James Johnston · Dec 6, 2011

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.