Как скопировать библиотеки времени выполнения Qt в вывод проекта - PullRequest
29 голосов
/ 06 декабря 2011

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

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

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

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

Ответы [ 4 ]

8 голосов
/ 06 декабря 2011

Хорошо, вот ужасный хак:

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

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

7 голосов
/ 10 января 2012

Немного более чистый метод, но для него потребуется 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.Я не совсем уверен, почему.

6 голосов
/ 01 февраля 2015

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


В случае, если вам необходимо идентифицировать предварительные условия / зависимости между кроссплатформенными, посмотрите на getPrerequisites() CMake. Он использует dumpbin, objbin, ldd, otool для идентификации зависимостей.

Ссылка: https://cmake.org/cmake/help/v3.0/module/GetPrerequisites.html

4 голосов
/ 01 ноября 2012

Я столкнулся с той же проблемой, и решение 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, чтобы получить выходную папку.

...