2012-06-07 8 views
68

Desidero compilare le librerie Qt (e eventualmente la mia applicazione) per una destinazione Windows x86_64 utilizzando un computer host Linux x86_64. Mi sento come se fossi vicino, ma potrei avere una fondamentale incomprensione di alcune parti di questo processo.Come configurare Qt per la cross-compilation da Linux a Windows target?

Ho iniziato installando tutti i pacchetti mingw sulla mia macchina Fedora e quindi modificando il fileqmake.conf per adattarlo al mio ambiente. Tuttavia, mi sembra di essere bloccato con alcune opzioni di configurazione apparentemente ovvia per Qt: -platform e -xplatform. La documentazione Qt dice che -platform dovrebbe essere l'architettura della macchina host (dove si sta compilando) e -xplatform dovrebbe essere la piattaforma di destinazione per la quale si desidera distribuire. Nel mio caso, ho impostato -platform linux-g++-64 e -xplatform linux-win32-g++ dove linux-win32-g ++ è la mia configurazione win32-g ++ modificata.

Il mio problema è che, dopo aver eseguito la configurazione con queste opzioni, vedo che richiama il compilatore del mio sistema invece del cross-compilatore (x86_64-w64-mingw32-gcc). Se ometto l'opzione -xplatform e imposta -platform sulla mia specifica di destinazione (linux-win32-g ++), richiama il cross compiler ma poi gli errori quando trova alcune funzioni relative a Unix non sono definite.

Ecco alcuni risultati del mio ultimo tentativo: http://pastebin.com/QCpKSNev.

Domande:

  1. Quando cross-compilazione qualcosa come Qt per Windows da un host Linux, dovrebbe il compilatore nativo mai essere richiamato? Cioè, durante un processo di compilazione incrociata, non dovremmo usare solo il crosscompiler? Non vedo perché lo script configure di Qt tenti di richiamare il compilatore nativo del mio sistema quando specifico l'opzione -xplatform.

  2. Se sto utilizzando un cross-compiler mingw, quando sarà necessario gestire un file di specifiche? I file delle specifiche per GCC sono ancora una specie di mistero per me, quindi mi chiedo se qualche sfondo qui mi aiuterà.

  3. In generale, oltre a specificare un cross-compilatore nel mio qmake.conf, cos'altro avrei potuto prendere in considerazione?

+2

Credo che sia necessaria una build locale di qmake per eseguire il bootstrap del resto della build. vedere anche i link in http://stackoverflow.com/questions/1025687/cross-compile-in-linux-or-windows –

+0

Ok, questo ha senso. Ora ho appena trovato un altro problema, mi sembra di mischiare toolchain nativi e cross. L'errore nel mio output pastebin sembra essere dovuto alla chiamata 'x86_64-w64-mingw32-as' al posto di quella nativa. –

+2

Raramente contrassegno una domanda SO come preferita, ma questa era una domanda unica e interessante con una bella risposta. – jdi

risposta

54

Basta usare M cross environment (MXE).Si prende il dolore di tutto il processo:

  • garantita:

    $ git clone https://github.com/mxe/mxe.git 
    
  • Installare build dependencies

  • generare Qt per Windows, le sue dipendenze, e gli strumenti di cross-build; ci vorrà circa un'ora su una macchina veloce con un discreto accesso a internet; il download è di circa 500MB:

    $ cd mxe && make qt 
    
  • Passare alla directory della vostra applicazione e aggiungere gli strumenti cross-build per il PATH variabile di ambiente:

    $ export PATH=<mxe root>/usr/bin:$PATH 
    
  • Eseguire il generatore di Qt Makefile quindi creare:

    $ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make 
    
  • Si dovrebbe trovare il file binario in./Directory di rilascio:

    $ wine release/foo.exe 
    

Alcune note:

  • Usa ramo principale del repository MXE; sembra ottenere molto più amore dal team di sviluppo.

  • L'output è un binario statico a 32 bit, che funzionerà bene su Windows a 64 bit.

+15

** nota **: queste istruzioni si applicano a Qt 4; per Qt 5, consultare http://stackoverflow.com/a/14170591 – Tshepang

+0

Vedere la risposta seguente per un aggiornamento. –

+0

Prima di eseguire '$ cd mxe && make qt' è necessario installare i requisiti.Per i sistemi Debian questo significa 'sudo apt-get install autoconf automake autopoint bash bison bzip2 cmake flex gettext git g ++ gperf intltool libffi-dev libtool libltdl-dev libssl-dev libxml-parser-perl make openssl patch perl pkg-config python ruby ​​scons sed decomprimere wget xz-utils'. Per altri sistemi, vedi http://mxe.cc/#requirements –

3

Ok penso di aver capito.

basato in parte sul https://github.com/mxe/mxe/blob/master/src/qt.mk e https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak

Sembra che "inizialmente" quando si esegue configure (con -xtarget, ecc), si configura quindi esegue il gcc "padroni di casa" per costruire il file binario locale./bin/qmake

./configure -xplatform win32-g++ -device-option CROSS_COMPILE=$cross_prefix_here -nomake examples ... 

poi si esegue normale "fare" e si costruisce per minGW

make 
    make install 

così

  1. solo se avete bisogno di usare qualcosa di diverso msvcrt.dll (il valore predefinito). Anche se non ho mai usato altro, quindi non lo so per certo.

  2. https://stackoverflow.com/a/18792925/32453 elenca alcuni parametri di configurazione.

12

(Questo è un aggiornamento di @ risposta di Tshepang, come MXE è evoluta da quando la sua risposta)

costruzione Qt

Piuttosto che usare make qt per costruire Qt, è possibile utilizzare MXE_TARGETS per controllare la vostra macchina target e toolchain (32 o 64 bit). MXE ha iniziato a utilizzare .static e .shared come parte del nome di destinazione per mostrare il tipo di lib che si desidera creare.

# The following is the same as `make qt`, see explanation on default settings after the code block. 
make qt MXE_TARGETS=i686-w64-mingw32.static # MinGW-w64, 32-bit, static libs 

# Other targets you can use: 
make qt MXE_TARGETS=x86_64-w64-mingw32.statiC# MinGW-w64, 64-bit, static libs 
make qt MXE_TARGETS=i686-w64-mingw32.shared # MinGW-w64, 32-bit, shared libs 

# You can even specify two targets, and they are built in one run: 
# (And that's why it is MXE_TARGET**S**, not MXE_TARGET ;) 
# MinGW-w64, both 32- and 64-bit, static libs 
make qt MXE_TARGETS='i686-w64-mingw32.static x86_64-w64-mingw32.static' 

In @ risposta originale di Tshepang, egli non ha specificato un MXE_TARGETS, e l'impostazione predefinita viene utilizzato. Al momento in cui ha scritto la sua risposta, il valore predefinito era i686-pc-mingw32, ora è i686-w64-mingw32.static. Se si imposta esplicitamente MXE_TARGETS su i686-w64-mingw32, omettendo .static, viene stampato un avviso perché questa sintassi è ora deprecata. Se si tenta di impostare il target su i686-pc-mingw32, verrà visualizzato un errore poiché MXE ha rimosso il supporto per MinGW.org (ad esempio i686-pc-mingw32).

Esecuzione qmake

Come abbiamo cambiato il MXE_TARGETS, il comando <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake non funzionerà più. Ora, ciò che è necessario fare è:

<mxe root>/usr/<TARGET>/qt/bin/qmake 

Se non è stato specificato MXE_TARGETS, fare questo:

<mxe root>/usr/i686-w64-mingw32.static/qt/bin/qmake 

Update: La nuova impostazione predefinita è ora i686-w64-mingw32.static

+0

Grazie mille per l'aggiornamento. È anche bello avere qualcuno che lavora direttamente sul progetto rispondere. – Tshepang

+2

Questa dovrebbe essere una modifica/aggiornamento all'altra risposta, non una nuova. – WhyNotHugo

+2

@Hugo La pagina di modifica dice: Come modificare: ► Correggere gli errori grammaticali o di ortografia ► chiarire il significato senza cambiarla ► correggere piccoli errori ► aggiungere le relative risorse o link ► sempre rispettare l'autore originale Questo è non nessuno di quelli. È un'estensione della risposta di Tshepang. –

2

Al fine per compilare Qt, è necessario eseguire lo script configure, specificando la piattaforma host con -platform (ad esempio -platform linux-g++-64 se si sta costruendo su un linux a 64 bit con il compilatore g ++) e la piattaforma di destinazione con -xplatform (ad es. -xplatform win32-g++ se si esegue la compilazione incrociata su Windows).

Ho anche aggiunto questo flag: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- che specifica il prefisso del toolchain che sto utilizzando, che andranno anteporre al 'gcc' o 'g ++' in tutti i makefile che stanno costruendo i binari per le finestre.

Infine, si potrebbero avere problemi durante la creazione di icd, che apparentemente è qualcosa che viene utilizzato per aggiungere il supporto ActiveX a Qt. Puoi evitarlo passando il flag -skip qtactiveqt allo script configure. Ho questo uno su questo bug report: https://bugreports.qt.io/browse/QTBUG-38223

Ecco l'intero comando configure che ho usato:

cd qt_source_directory 
    mkdir my_build 
    cd my_build 
    ../configure \ 
     -release \ 
     -opensource \ 
     -no-compile-examples \ 
     -platform linux-g++-64 \ 
     -xplatform win32-g++ \ 
     -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- \ 
     -skip qtactiveqt \ 
     -v 

Per quanto riguarda le domande yout:

1 - Sì. Il compilatore nativo verrà chiamato per creare alcuni strumenti necessari nel processo di compilazione. Forse cose come qconfig o qmake, ma non sono del tutto sicuro di quali strumenti, esattamente.

2 - Siamo spiacenti. Non ho idea di quali file di specifiche sono nel contesto di compilatori = /. Ma per quanto ne so, non avresti dovuto affrontarlo.

3 - È possibile specificare il prefisso del cross compilator nella riga di comando configure anziché farlo nel file qmake.conf, come menzionato sopra. E c'è anche quel problema con idc, il cui workaround ho menzionato pure.

0

Un altro modo per eseguire la compilazione incrociata di software per Windows su Linux è la toolchain mingw-w64 su Archlinux. È facile da usare e mantenere, e fornisce versioni recenti del compilatore e molte librerie. Personalmente trovo più facile di MXE e sembra adottare più rapidamente le versioni più recenti delle librerie.

Per prima cosa è necessaria una macchina basata su arco (è sufficiente una macchina virtuale o un contenitore docker). Non deve essere Arch Linux, anche i derivati ​​lo faranno. Ho usato Manjaro Linux. La maggior parte dei pacchetti mingw-w64 non sono disponibili nei repository ufficiali di Arch, ma c'è plenty in AUR. Il gestore di pacchetti predefinito per Arch (pacman) non supporta l'installazione direttamente da AUR, quindi sarà necessario installare e utilizzare un wrapper AUR come pacaur o yaourt. Poi l'installazione della versione mingw-W64 di QT5 e Boost librerie è facile come:

pacaur -Sy mingw-w64-qt5-base mingw-w64-boost 
#yaourt -Sy mingw-w64-qt5-base mingw-w64-qt5-boost #if you use yaourt 

Questo sarà anche installare il toolchain mingw-W64 (mingw-w64-gcc) e altre dipendenze. cross-compilazione di un progetto di Qt per Windows (x64) è poi così semplice come:

x86_64-w64-mingw32-qmake-qt5 
make 

Per distribuire si programma è necessario copiare le DLL corrispondenti da /usr/x86_64-w64-mingw32/bin/.

Per ottenere una versione a 32 bit è sufficiente utilizzare i686-w64-mingw32-qmake-qt5. I progetti basati su Cmake funzionano altrettanto facilmente con x86_64-w64-mingw32-cmake. Questo approccio ha funzionato molto bene per me, è stato il più semplice da configurare, mantenere ed estendere. Si adatta anche ai servizi di integrazione continua. Sono disponibili anche docker images.

Ad esempio, supponiamo di voler creare una GUI per il download dei sottotitoli QNapi. Potrei farlo in due fasi:

1) Avviare il contenitore finestra mobile:

sudo docker run -it burningdaylight/docker-mingw-qt5 /bin/bash 

2) Clone e compilare QNapi

git clone --recursive 'https://github.com/QNapi/qnapi.git' 
cd qnapi/ 
x86_64-w64-mingw32-qmake-qt5 
make 

Questo è tutto! In molti casi sarà così facile. Anche aggiungere le proprie librerie al pacchetto di repository (AUR) è semplice. Avresti bisogno di write a PKBUILD file, che è tanto intuitivo quanto può, vedi mingw-w64-rapidjson, per esempio.

Problemi correlati