Wie konfiguriere ich Qt für die Cross-Kompilierung von Linux zu Windows?

81

Ich möchte die Qt-Bibliotheken (und eventuell meine Anwendung) für ein Windows x86_64-Ziel mithilfe eines Linux x86_64-Hostcomputers übergreifend kompilieren. Ich fühle mich nahe, aber ich habe möglicherweise ein grundlegendes Missverständnis einiger Teile dieses Prozesses.

Ich begann damit, alle mingw-Pakete auf meinem Fedora-Computer zu installieren und dann die win32-g++Datei qmake.conf an meine Umgebung anzupassen. Ich scheine jedoch mit einigen scheinbar offensichtlichen Konfigurationsoptionen für Qt: -platformund festzuhalten -xplatform. In der Qt-Dokumentation heißt es, dass -platformdies die Host-Computer-Architektur (auf der Sie kompilieren) und -xplatformdie Zielplattform sein sollte, für die Sie die Bereitstellung durchführen möchten. In meinem Fall, habe ich -platform linux-g++-64und -xplatform linux-win32-g++wo Linux-win32-g ++ ist mein modifizierte win32-g ++ Konfiguration.

Mein Problem ist, dass nach dem Ausführen von configure mit diesen Optionen der Compiler meines Systems anstelle des Cross-Compilers (x86_64-w64-mingw32-gcc) aufgerufen wird. Wenn ich die -xplatformOption weglasse und -platformauf meine Zielspezifikation (linux-win32-g ++) setze , wird der Cross-Compiler aufgerufen, aber Fehler, wenn einige Unix-bezogene Funktionen gefunden werden, sind nicht definiert.

Hier sind einige Ergebnisse meines letzten Versuchs: http://pastebin.com/QCpKSNev .

Fragen:

  1. Sollte der native Compiler jemals aufgerufen werden , wenn so etwas wie Qt für Windows von einem Linux-Host übergreifend kompiliert wird ? Das heißt, sollten wir während eines Cross-Compilation-Prozesses nicht nur den Cross-Compiler verwenden? Ich verstehe nicht, warum das Konfigurationsskript von Qt versucht, den nativen Compiler meines Systems aufzurufen, wenn ich die -xplatformOption spezifiziere .

  2. Wenn ich einen MingW-Cross-Compiler verwende, wann muss ich mich mit einer Spezifikationsdatei befassen? Spezifikationsdateien für GCC sind für mich immer noch ein Rätsel, daher frage ich mich, ob mir hier Hintergrundinformationen helfen werden.

  3. Was muss ich im Allgemeinen außer der Angabe eines Cross-Compilers in meiner qmake.conf noch beachten?

Mr. Shickadance
quelle
2
Ich glaube, es braucht einen lokalen Build von qmake, um den Rest des Builds zu booten. Siehe auch Links in stackoverflow.com/questions/1025687/…
Martin Beckett
Ok, das macht Sinn. Ich habe gerade ein anderes Problem gefunden, ich scheine native und Cross-Toolchains zu mischen. Der Fehler in meiner Pastebin-Ausgabe scheint auf einen Aufruf x86_64-w64-mingw32-asanstelle des nativen zurückzuführen zu sein.
Herr Shickadance
2
Ich markiere selten eine SO-Frage als Favorit, aber dies war eine einzigartige und interessante Frage mit einer coolen Antwort.
JDI

Antworten:

70

Verwenden Sie einfach M Cross Environment (MXE) . Es nimmt den Schmerz aus dem gesamten Prozess:

  • Kapiert:

    $ git clone https://github.com/mxe/mxe.git
    
  • Installieren Sie Build-Abhängigkeiten

  • Erstellen Sie Qt für Windows, seine Abhängigkeiten und die Cross-Build-Tools. Dies dauert auf einer schnellen Maschine mit angemessenem Internetzugang ungefähr eine Stunde. Der Download beträgt ca. 500 MB:

    $ cd mxe && make qt
    
  • Wechseln Sie in das Verzeichnis Ihrer App und fügen Sie die Cross-Build-Tools zur Umgebungsvariablen PATH hinzu :

    $ export PATH=<mxe root>/usr/bin:$PATH
    
  • Führen Sie das Qt Makefile Generator-Tool aus und erstellen Sie Folgendes:

    $ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make
    
  • Sie sollten die Binärdatei im Verzeichnis ./release finden:

    $ wine release/foo.exe
    

Einige Notizen :

  • Verwenden Sie den Hauptzweig des MXE-Repositorys. Es scheint viel mehr Liebe vom Entwicklungsteam zu bekommen.

  • Die Ausgabe ist eine statische 32-Bit-Binärdatei, die unter 64-Bit-Windows gut funktioniert.

Tshepang
quelle
17
Hinweis : Diese Anweisungen gelten für Qt 4. für Qt 5 siehe stackoverflow.com/a/14170591
tshepang
Vor der Ausführung $ cd mxe && make qtsollten Sie die Anforderungen installieren. Für Debian-Systeme bedeutet dies 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 unzip wget xz-utils. Für andere Systeme siehe mxe.cc/#requirements
Martin Thoma
16

(Dies ist ein Update von @ Tshepangs Antwort, da sich MXE seit seiner Antwort weiterentwickelt hat.)

Gebäude Qt

Anstatt make qtQt zu erstellen, können Sie MXE_TARGETSIhren Zielcomputer und Ihre Toolchain (32- oder 64-Bit) steuern. MXE begann mit .staticund .sharedals Teil des Zielnamens, um anzuzeigen , welchen Lib-Typ Sie erstellen möchten.

# 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 der ursprünglichen Antwort von @ Tshepang hat er keine angegeben MXE_TARGETS, und die Standardeinstellung wird verwendet. Zu der Zeit, als er seine Antwort schrieb, war die Standardeinstellung i686-pc-mingw32, jetzt ist es i686-w64-mingw32.static. Wenn Sie explizit MXE_TARGETSauf i686-w64-mingw32, Weglassen .static, eine Warnung ausgegeben, da diese Syntax jetzt veraltet. Wenn Sie versuchen, das Ziel auf i686-pc-mingw32festzulegen, wird ein Fehler angezeigt, da MXE die Unterstützung für MinGW.org (dh i686-pc-mingw32) entfernt hat.

Laufen qmake

Da wir das geändert haben MXE_TARGETS, <mxe root>/usr/i686-pc-mingw32/qt/bin/qmakefunktioniert der Befehl nicht mehr. Was Sie jetzt tun müssen, ist:

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

Wenn Sie nichts angegeben haben MXE_TARGETS, gehen Sie folgendermaßen vor:

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

Update: Der neue Standard ist jetzti686-w64-mingw32.static

Timothy Gu
quelle
Vielen Dank für das Update. Es ist auch gut, wenn jemand, der direkt am Projekt arbeitet, antwortet.
Tshepang
3
Dies sollte eine Bearbeitung / Aktualisierung der anderen Antwort gewesen sein, keine neue.
WhyNotHugo
3
@Hugo Auf der Bearbeitungsseite heißt es: So bearbeiten Sie: ► Grammatik- oder Rechtschreibfehler beheben ► Bedeutung klären, ohne sie zu ändern ► kleinere Fehler korrigieren ► verwandte Ressourcen oder Links hinzufügen ► immer den ursprünglichen Autor respektieren Dies ist keiner von diesen. Es ist eine Erweiterung von Tshepangs Antwort.
Timothy Gu
Ich verstehe diese Antwort nicht, wenn ich "make qt ...." eingebe, antwortet sie nur mit "keine Regel, um das Ziel qt zu machen".
Mein
4

Ok, ich glaube, ich habe es herausgefunden.

Teilweise basierend auf https://github.com/mxe/mxe/blob/master/src/qt.mk und https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak

Es scheint, dass "anfänglich" beim Ausführen von configure (mit -xtarget usw.) Ihr "hosts" -gcc konfiguriert und dann ausgeführt wird, um die lokale Binärdatei ./bin/qmake zu erstellen

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

dann läuft man normal "make" und es baut es für mingw auf

  make
  make install

damit

  1. Ja

  2. Nur wenn Sie etwas anderes als msvcrt.dll verwenden müssen (Standardeinstellung). Obwohl ich noch nie etwas anderes benutzt habe, weiß ich es nicht genau.

  3. https://stackoverflow.com/a/18792925/32453 listet einige Konfigurationsparameter auf.

Rogerdpack
quelle
4

Um Qt zu kompilieren, muss das configureSkript ausgeführt werden, wobei die Hostplattform mit -platform(z. B. -platform linux-g++-64wenn Sie mit dem g ++ - Compiler auf einem 64-Bit-Linux aufbauen) und die Zielplattform mit -xplatform(z. B. -xplatform win32-g++wenn Sie Cross-Compilieren mit Windows durchführen) angegeben werden ).

Ich habe auch diese Flagge hinzugefügt: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- Gibt das Präfix der von mir verwendeten Toolchain an, die in allen Makefiles, die Binärdateien für Windows erstellen, vor 'gcc' oder 'g ++' gestellt wird.

Schließlich können beim Erstellen von icd Probleme auftreten. Dies wird anscheinend verwendet, um Qt ActiveX-Unterstützung hinzuzufügen. Sie können dies vermeiden, indem Sie das Flag -skip qtactiveqtan das Konfigurationsskript übergeben. Ich habe diesen aus diesem Fehlerbericht herausgeholt: https://bugreports.qt.io/browse/QTBUG-38223

Hier ist der gesamte Konfigurationsbefehl, den ich verwendet habe:

    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

Was Ihre Fragen betrifft:

1 - Ja. Der native Compiler wird aufgerufen, um einige Tools zu erstellen, die im Erstellungsprozess benötigt werden. Vielleicht Dinge wie qconfig oder qmake, aber ich bin mir nicht ganz sicher, welche Tools genau.

2 - Entschuldigung. Ich habe keine Ahnung, welche Spezifikationsdateien im Kontext von Compilern sind = /. Aber soweit ich weiß, müssten Sie sich nicht darum kümmern.

3 - Sie können das Cross-Compiler-Präfix in der Befehlszeile configure angeben, anstatt es wie oben erwähnt in der Datei qmake.conf auszuführen. Und es gibt auch dieses Problem mit idc, dessen Problemumgehung ich ebenfalls erwähnt habe.

user986730
quelle
4

Eine andere Möglichkeit, Software für Windows unter Linux zu kompilieren, ist die Toolchain mingw-w64 unter Archlinux. Es ist einfach zu bedienen und zu warten und bietet aktuelle Versionen des Compilers und viele Bibliotheken. Ich persönlich finde es einfacher als MXE und es scheint, dass neuere Versionen von Bibliotheken schneller übernommen werden.

Zuerst benötigen Sie eine archbasierte Maschine (virtuelle Maschine oder Docker-Container reichen aus). Es muss nicht Arch Linux sein, Derivate auch. Ich habe Manjaro Linux verwendet. Die meisten der mingw-w64-Pakete sind nicht in den offiziellen Arch-Repositories verfügbar, aber es gibt viele in AUR . Der Standardpaketmanager für Arch (pacman) unterstützt die Installation nicht direkt von AUR aus. Daher müssen Sie einen AUR-Wrapper wie yay oder yaourt installieren und verwenden. Die Installation der mingw-w64-Version der Qt5- und Boost-Bibliotheken ist dann so einfach wie:

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

Dadurch werden auch die Toolchain mingw-w64 ( mingw-w64-gcc) und andere Abhängigkeiten installiert . Das Cross-Kompilieren eines Qt-Projekts für Windows (x64) ist dann so einfach wie:

x86_64-w64-mingw32-qmake-qt5
make

Um Ihr Programm bereitzustellen, müssen Sie die entsprechenden DLLs von kopieren /usr/x86_64-w64-mingw32/bin/. Zum Beispiel werden Sie in der Regel kopieren müssen /usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/qwindows.dllzu program.exe_dir/platforms/qwindows.dll.

Um eine 32-Bit-Version zu erhalten, müssen Sie i686-w64-mingw32-qmake-qt5stattdessen einfach verwenden . Cmake-basierte Projekte funktionieren genauso einfach x86_64-w64-mingw32-cmake. Dieser Ansatz hat bei mir sehr gut funktioniert und war am einfachsten einzurichten, zu warten und zu erweitern. Es passt auch gut zu kontinuierlichen Integrationsdiensten. Es sind auch Docker-Bilder verfügbar.

Angenommen, ich möchte eine QNapi-GUI für Untertitel-Downloader erstellen. Ich könnte es in zwei Schritten tun:

  1. Starten Sie den Docker-Container:

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

  2. Klonen und kompilieren Sie QNapi

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

Das ist es! In vielen Fällen wird es so einfach sein. Das Hinzufügen eigener Bibliotheken zum Paket-Repository (AUR) ist ebenfalls unkompliziert. Sie müssten eine PKBUILD-Datei schreiben , die so intuitiv wie möglich ist, siehe z. B. mingw-w64-rapidjson .

Mykola Dimura
quelle
Für die Bereitstellung müssen Sie alle erforderlichen Qt-DLLs (oder doc.qt.io/qt-5/windows-deployment.html ) kopieren . Stellen Sie sicher, dass /mingw64/share/qt5/plugins/platforms/qwindows.dll in die Plattform / qwindows.dll kopiert wird.
Entwickeln Sie