Distribuzione dell’app Qt 5 su Windows

Ho scritto un paio di applicazioni in QML (parte di Qt 5). In una domanda che ho fatto prima ( https://softwareengineering.stackexchange.com/questions/213698/deploying-qt-based-app-on-mac-os-x ), ho trovato la soluzione per la distribuzione della mia app su OS X (utilizzando lo strumento macdeployqt).

La distribuzione di app Qt4 su Windows è stata semplice:

  1. Lo hai compilato in modalità di rilascio.
  2. Hai copiato le librerie necessarie (DLL).
  3. Hai provato e ha funzionato.

Sfortunatamente, questo approccio non ha funzionato in Qt5 (ho persino incluso la cartella delle piattaforms con il file qwindows.dll e non ha funzionato). Dopo alcuni giorni di tentativi, ho rinunciato e ho compilato una versione statica di Qt5.

Di nuovo, non ha funzionato. L’app funziona su un PC con Qt installato, ma si blocca su PC “puliti”. Come nota a margine, i sistemi Windows 8 / 8.1 non forniscono un avvertimento o un messaggio che mi informi del crash dell’applicazione. Ma in Windows 7 un messaggio mi avvisa che l’applicazione si è bloccata.

Ho provato a eseguire Dependency Walker (depends.exe) e tutte le librerie nella build statica della mia applicazione sembravano soddisfacenti.

In Windows 8, non ho alcun errore. Ma dopo aver profilato l’app in depends.exe, ottengo una violazione di accesso proveniente da QtGui.dll. L’errore esatto è

L’eccezione della seconda possibilità 0xC0000005 (violazione di accesso) si è verificata in “QT5GUI.DLL” all’indirizzo 0x61C2C000.

C’è qualcosa che mi manca (ad esempio una DLL aggiuntiva o un file di configurazione)?

Informazioni sull’applicazione:

  • Scritto e compilato con Qt 5.2.1
  • Utilizza Quick / QML.
  • Utilizza il modulo di rete.
  • Utilizza il modulo webkit.
  • Usa il modulo bluetooth.
  • I file QML sono scritti in Quick 2.2

A partire da Qt 5.2, è ansible utilizzare lo strumento windeployqt . Basta eseguirlo dalla riga di comando per ottenere aiuto. Ma l’uso di base è, dargli il file .exe, copierà le dipendenze Qt per andare con esso.

Dovrai usare --qmldir opzione --qmldir per far sapere allo strumento dove sono i tuoi file QML, in modo che possa capire le dipendenze QML necessarie.

Nota sui test: per assicurarsi di avere tutto, testare sul computer senza Qt SDK, o rinominare temporaneamente la directory Qt. Altrimenti l’applicazione potrebbe trovare file mancanti da lì …

Dopo alcune ore di ricerca nei forum di Qt, ho scoperto che ho bisogno di copiare la cartella “qml” (normalmente situata in C: /Qt/5.2.1/qml) nella directory principale dell’applicazione. Dopo averlo fatto, entrambe le versioni dinamiche e statiche della mia applicazione hanno funzionato su sistemi vanilla.


Directory del programma (MinGW 4.8 a 32 bit, dynamic):

Come spiegato da hyde , utilizzare lo strumento windeployqt ( \\bin\windeployqt.exe ) per copiare i file necessari nella cartella dell’applicazione. Successivamente, copia i componenti QML richiesti da \\qml\ nella cartella dell’applicazione. La cartella risultante dovrebbe essere simile a:

  • piattaforms (cartella)
  • QtQuick (cartella)
  • QtQuick.2 (cartella)
  • Qualsiasi altro componente QML di cui hai bisogno
  • app.exe
  • icudt51.dll
  • icuin51.dll
  • icuuc51.dll
  • libgcc_s_dw2-1.dll
  • libstdc ++ – 6.dll
  • libwindthread-1.dll
  • Qt5Core.dll
  • Qt5Gui.dll
  • Qt5Qml.dll
  • Qt5Quick.dll
  • Qt5Network.dll
  • Qt5Widgets.dll

Directory del programma (statica)

Compilare staticamente l’applicazione, quindi copiare i componenti QML richiesti da \\qml\ nella cartella dell’applicazione. La cartella risultante dovrebbe essere simile a:

  • QtQuick (cartella)
  • QtQuick.2 (cartella)
  • Qualsiasi altro componente QML di cui hai bisogno
  • app.exe

Penso che la causa del crash sia stata che il Qt5Gui.dll (dinamico e statico) ha “provato” a caricare le cartelle QtQuick * durante il tempo di esecuzione, ma non è stato in grado di trovarle (bloccando quindi l’applicazione durante il caricamento).