Как копировать DLL файлы времени выполнения Qt для вывода проекта
У меня есть простой проект, созданный в Qt Creator (установленный с использованием Qt SDK 1.1.4). Он отлично работает в Qt Creator, но если я затем перейду к выходному каталогу в Windows и дважды щелкните EXE, я получу ошибку, например:
The program can't start because QtCored4.dll is missing from your computer.
Try reinstalling the program to fix this problem.
Это очевидно, потому что Qt не находится в моем PATH (и я не хочу, чтобы это было, если у меня было несколько версий Qt на моем компьютере), а Qt Creator/qmake не копировал Qt DLL выход проекта.
Что бы я хотел сделать, это использовать qmake для копирования необходимых файлов Qt в выходной каталог проекта - где бы это ни было. Как это сделать?
(Я попытался создать пользовательскую цель в qmake, но я не слишком далеко...)
ОБНОВЛЕНИЕ 19 июля 2016 года:. Чтобы прояснить, вышеупомянутое сообщение касалось Qt4. На Qt5 вы должны вместо этого взглянуть на вызов windeployqt
. Этот инструмент Qt5 будет читать ваш двоичный файл, определить, какие файлы времени исполнения Qt5 вам нужны, и скопировать их в ваш двоичный каталог. Также обратите внимание, что он исправит абсолютные пути в библиотеке Qt5:: Core, специфичные для вашего ПК, поэтому использование этого инструмента в основном является обязательным, если вы не хотите предоставить qt.conf
.
Ответы
Ответ 1
ОК, здесь уродливый взлом:
# 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.)
}
Вот что мне не нравится в этом:
- Использует переменную среды% QTDIR%; эта переменная не оценивается до тех пор, пока команда копирования не будет выполнена. Кажется, что-то вроде QMAKE_LIBS_QT_DLL было бы более уместным, но я не мог заставить это работать по какой-то причине.
- Жестко закодированные имена "отладки" и "выпуска"; кажется, что для этого должна быть какая-то переменная.
- Вызов в среду с помощью команды "copy".
Я приму еще один ответ, если кто-то может это почистить, например, сократив его и/или рассмотрев некоторые из моих проблем или просто найдя лучший способ вообще.
Ответ 2
Метод очистки бит, но для make install
потребуется make install
после make
. Он будет работать на Windows, но ему потребуется настройка для других платформ.
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
Если qmake запускается только для отладки, все выходные данные войдут в. /debug. Если это просто для выпуска, вся продукция идет. /release. Если оба, то в. /bin.
Я заметил, что включение теневого здания в QtCreator заставило исполняемый файл не попасть в DESTDIR. Я не совсем понимаю, почему.
Ответ 3
Скопируйте зависимости с помощью 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}
или копировать зависимости вручную
# 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
Ссылка: http://doc.qt.io/qt-5/qmake-variable-reference.html#deployment
В случае, если вам необходимо идентифицировать предварительные требования/зависимости между кроссплатформенными, посмотрите CMake getPrerequisites()
. Он использует dumpbin
, objbin
, ldd
, otool
для идентификации зависимостей.
Ссылка: https://cmake.org/cmake/help/v3.0/module/GetPrerequisites.html
Ответ 4
Я столкнулся с той же проблемой, и jwernerny solution мне очень помог. Тем не менее, я использовал Shadow Build на Window 7, и ему нужно было немного больше tweeking.
Мне также нужно было установить DESTDIR
в соответствии с текущей конфигурацией.
В моем случае я хотел скопировать файлы *.qml
, как я это достиг:
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:
Поскольку я использую Shadow Build, мне нужно использовать $$OUT_PWD
для получения выходной папки.