Подтвердить что ты не робот

Как копировать 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.

4b9b3361

Ответ 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 для получения выходной папки.