web-dev-qa-db-fra.com

Comment configurer Qt pour la compilation croisée de Linux vers la cible Windows?

Je souhaite effectuer une compilation croisée des bibliothèques Qt (et éventuellement de mon application) pour une cible Windows x86_64 utilisant un ordinateur hôte Linux x86_64. Je me sens proche, mais je peux avoir une incompréhension fondamentale de certaines parties de ce processus.

J'ai commencé par installer tous les packages mingw sur ma machine Fedora, puis par modifier le fichier win32-g++ qmake.conf pour l'adapter à mon environnement. Cependant, il semble que je me retrouve avec des options de configuration apparemment évidentes pour Qt: -platform et -xplatform. La documentation de Qt indique que -platform devrait être l'architecture de la machine hôte (où vous compilez) et -xplatform devrait être la plate-forme cible que vous souhaitez déployer. Dans mon cas, j'ai défini -platform linux-g++-64 et -xplatform linux-win32-g++ où linux-win32-g ++ est ma configuration modifiée win32-g ++.

Mon problème est que, après avoir exécuté configure avec ces options, je vois qu'il appelle le compilateur de mon système au lieu du compilateur croisé (x86_64-w64-mingw32-gcc). Si j'omets l'option -xplatform et que je fixe -platform à ma spécification cible (linux-win32-g ++), il appelle le compilateur croisé, mais des erreurs surviennent lorsqu'il détecte que certaines fonctions liées à Unix ne sont pas définies.

Voici quelques résultats de ma dernière tentative: http://Pastebin.com/QCpKSNev .

Des questions:

  1. Lors de la compilation croisée de quelque chose comme Qt pour Windows à partir d'un hôte Linux, le compilateur natif ever doit-il être appelé? En d’autres termes, lors d’un processus de compilation croisée, ne devrions-nous pas utiliser only le compilateur croisé? Je ne vois pas pourquoi le script de configuration de Qt tente d'appeler le compilateur natif de mon système lorsque je spécifie l'option -xplatform.

  2. Si j'utilise un compilateur croisé Mingw, quand devrai-je gérer un fichier de spécifications? Les fichiers de spécification pour GCC sont toujours un mystère pour moi, alors je me demande si un peu de contexte ici va m'aider.

  3. En général, à part spécifier un compilateur croisé dans mon qmake.conf, que devrais-je encore considérer?

73
Mr. Shickadance

Utilisez simplement M cross environment (MXE) . Cela simplifie tout le processus:

  • Trouver:

    $ git clone https://github.com/mxe/mxe.git
    
  • Installer dépendances de construction

  • Construisez Qt pour Windows, ses dépendances et les outils de construction croisée; Cela prendra environ une heure sur une machine rapide avec un accès Internet correct.

    $ cd mxe && make qt
    
  • Accédez au répertoire de votre application et ajoutez les outils de génération croisée à la variable d'environnement PATH:

    $ export PATH=<mxe root>/usr/bin:$PATH
    
  • Exécutez l’outil générateur de Qt Makefile puis construisez:

    $ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make
    
  • Vous devriez trouver le binaire dans le répertoire ./release:

    $ wine release/foo.exe
    

Quelques notes:

  • Utilisez la branche principale du référentiel MXE. il semble que l’équipe de développement suscite beaucoup plus d’amour.

  • La sortie est un binaire statique 32 bits, qui fonctionnera bien sous Windows 64 bits.

61
Tshepang

(Ceci est une mise à jour de la réponse de @ Tshepang, car MXE a évolué depuis sa réponse.)

Bâtiment Qt

Plutôt que d'utiliser make qt pour construire Qt, vous pouvez utiliser MXE_TARGETS pour contrôler votre machine cible et votre chaîne d'outils (32 ou 64 bits). MXE a commencé à utiliser .static et .shared en tant que partie du nom de la cible pour indiquer le type de bibliothèque que vous souhaitez créer.

# 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'

Dans la réponse initiale de @ Tshepang, il n'a pas spécifié de MXE_TARGETS et la valeur par défaut est utilisée. Au moment où il a écrit sa réponse, la valeur par défaut était i686-pc-mingw32, maintenant c'est i686-w64-mingw32.static. Si vous définissez explicitement MXE_TARGETS sur i686-w64-mingw32, en omettant .static, un avertissement est imprimé car cette syntaxe est désormais obsolète. Si vous essayez de définir la cible sur i686-pc-mingw32, une erreur s'affichera, car MXE a supprimé la prise en charge de MinGW.org (c'est-à-dire i686-pc-mingw32).

En cours qmake

Comme nous avons changé le MXE_TARGETS, la commande <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake ne fonctionnera plus. Maintenant, ce que vous devez faire c'est:

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

Si vous n'avez pas spécifié MXE_TARGETS, procédez comme suit:

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

Mise à jour: La nouvelle valeur par défaut est maintenant i686-w64-mingw32.static

16
Timothy Gu

Ok, je pense que j'ai compris.

Basé en partie sur https://github.com/mxe/mxe/blob/master/src/qt.mk et https://www.videolan.org/developers/vlc/contrib/src/ qt4/rules.mak

Il semble que "initialement" lorsque vous exécutez configure (avec -xtarget, etc.), il configure puis exécute votre "hôtes" gcc pour construire le fichier binaire local ./bin/qmake

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

alors vous lancez un "make" normal et il le construit pour mingw

  make
  make install

alors

  1. oui

  2. uniquement si vous devez utiliser autre chose que msvcrt.dll (sa valeur par défaut). Bien que je n’ai jamais utilisé autre chose, je ne le sais pas avec certitude.

  3. https://stackoverflow.com/a/18792925/32453 répertorie certains paramètres de configuration.

3
rogerdpack

Pour compiler Qt, vous devez exécuter son script configure en spécifiant la plate-forme hôte avec -platform (par exemple, -platform linux-g++-64 si vous construisez sur un Linux 64 bits avec le compilateur g ++) et la plate-forme cible avec -xplatform (par exemple, -xplatform win32-g++ si vous ' recompiler en compilant vers windows).

J'ai aussi ajouté l'indicateur suivant: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- Qui spécifie le préfixe de la chaîne d'outils que j'utilise, qui sera préfixé par 'gcc' ou 'g ++' dans tous les fichiers de compilation qui construisent des fichiers binaires pour Windows.

Enfin, vous pourriez avoir des problèmes lors de la construction de icd , qui est apparemment quelque chose qui est utilisé pour ajouter le support ActiveX à Qt. Vous pouvez éviter cela en transmettant l'indicateur -skip qtactiveqt au script configure. J'ai celui-ci sur ce rapport de bogue: https://bugreports.qt.io/browse/QTBUG-38223

Voici la commande de configuration complète que j'ai utilisée:

    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

En ce qui concerne vos questions:

1 - Oui Le compilateur natif sera appelé afin de générer certains outils nécessaires au processus de construction. Peut-être que des choses comme qconfig ou qmake, mais je ne suis pas tout à fait sûr de quels outils, exactement.

2 - Désolé. Je n'ai aucune idée de ce que sont les fichiers specs dans le contexte des compilateurs = /. Mais pour autant que je sache, vous n’auriez pas à vous en occuper.

3 - Vous pouvez spécifier le préfixe du compilateur croisé dans la ligne de commande de configure au lieu de le faire dans le fichier qmake.conf, comme mentionné ci-dessus. Et il y a aussi ce problème avec idc, dont j'ai déjà parlé de la solution de contournement.

2
user986730

La chaîne d'outils mingw-w64 sur Archlinux est un autre moyen de compiler de manière croisée des logiciels pour Windows sous Linux. Il est facile à utiliser et à maintenir. Il fournit les versions récentes du compilateur et de nombreuses bibliothèques. Personnellement, je trouve cela plus facile que MXE et il semble adopter les nouvelles versions de bibliothèques plus rapidement.

Vous aurez d’abord besoin d’une machine archivée (une machine virtuelle ou un conteneur de menu fixe suffira). Il n’est pas nécessaire que ce soit Arch Linux, les dérivés feront aussi bien. J'ai utilisé Manjaro Linux . La plupart des paquets mingw-w64 ne sont pas disponibles dans les dépôts officiels d'Arch, mais il y a much dans AUR . Le gestionnaire de packages par défaut pour Arch (pacman) ne prend pas en charge l’installation directement à partir d’AUR; vous devez donc installer et utiliser un wrapper AUR tel que pacaur ou yaourt. Puis installer la version mingw-w64 des bibliothèques Qt5 et Boost est aussi simple que:

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

Cela installera également la chaîne d'outils mingw-w64 (mingw-w64-gcc) et d'autres dépendances . La compilation croisée d'un projet Qt pour windows (x64) est alors aussi simple que:

x86_64-w64-mingw32-qmake-qt5
make

Pour déployer votre programme, vous devrez copier les DLL correspondants à partir de /usr/x86_64-w64-mingw32/bin/.

Pour obtenir une version 32 bits, vous devez simplement utiliser i686-w64-mingw32-qmake-qt5 à la place. Les projets basés sur Cmake fonctionnent tout aussi facilement avec x86_64-w64-mingw32-cmake. Cette approche a très bien fonctionné pour moi. Elle était la plus facile à configurer, à maintenir et à étendre . Elle convient également aux services d'intégration continue. Docker images sont également disponibles.

Par exemple, supposons que je souhaite construire l'interface graphique de téléchargeur de sous-titres QNapi. Je pourrais le faire en deux étapes:

1) Démarrer le conteneur de docker:

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

2) Cloner et compiler QNapi

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

C'est tout! Dans de nombreux cas, ce sera aussi simple que cela. L'ajout de vos propres bibliothèques au référentiel de packages (AUR) est également simple. Vous devez écrire un fichier PKBUILD , aussi intuitif que possible, voir mingw-w64-rapidjson , par exemple.

0
Mykola Dimura