Как скопировать библиотеки Qt runtime DLL в вывод проекта

У меня есть простой проект, созданный в 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 DLLs в выходной каталог проекта.

Что я хотел бы сделать, так это использовать qmake для копирования необходимых файлов Qt в выходной каталог проекта - где бы он ни находился. Как мне это сделать?

(Я пытался создать пользовательскую цель в qmake, но у меня ничего не получается...)

UPDATE July 19, 2016: Просто чтобы уточнить, вышеприведенное сообщение касалось Qt4. На Qt5 вместо этого вам следует обратиться к windeployqt. Этот инструмент Qt5 прочитает ваш двоичный файл, определит, какие файлы среды выполнения Qt5 вам нужны, и скопирует их в ваш двоичный каталог. Также обратите внимание, что он исправит абсолютные пути в библиотеке Qt5::Core, которые специфичны для вашего ПК - поэтому использование этого инструмента является обязательным, если вы не хотите предоставлять qt.conf файл самостоятельно.

30
задан James Johnston 19 July 2016 в 22:29
поделиться

3 ответа

Хорошо, вот уродливый взлом:

# 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 было бы более подходящим, но я не мог заставить это работать по какой-то причине.
  • Жестко закодированные имена «debug» и «release»; похоже, что для этого должна быть какая-то переменная.
  • Вызов в окружающую среду с помощью команды «копировать».

Я приму другой ответ, если кто-нибудь сможет это исправить, например, сократив его и / или решив некоторые из моих проблем, или просто найдя лучший способ в целом.

8
ответ дан 28 November 2019 в 00:23
поделиться

Копировать зависимости с помощью 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

6
ответ дан 28 November 2019 в 00:23
поделиться

Я столкнулся с той же проблемой, и решение jwernerny мне очень помогло. Тем не менее, я использовал Shadow Build в Windows 7, и ему нужно было немного больше настроек.

Мне также нужно было установить 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

РЕДАКТИРОВАТЬ:

Поскольку я использую Shadow Build, мне нужно использовать $OUT_PWD, чтобы получить выходную папку.

4
ответ дан 28 November 2019 в 00:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: