¿Cómo configuro Qt para la comstackción cruzada de Linux a Windows?

Quiero realizar una comstackción cruzada de las bibliotecas de Qt (y, finalmente, de mi aplicación) para un destino de Windows x86_64 con una máquina host Linux x86_64. Siento que estoy cerca, pero puedo tener un malentendido fundamental de algunas partes de este proceso.

Comencé por instalar todos los paquetes mingw en mi máquina Fedora y luego modifiqué el archivo win32-g++ qmake.conf para adaptarlo a mi entorno. Sin embargo, parece que me estoy quedando atrapado con algunas opciones de configuración aparentemente obvias para Qt: -platform y -xplatform . La documentación de Qt dice que -platform debe ser la architecture de máquina host (donde se está comstackndo) y -xplatform debe ser la plataforma de destino para la que se desea implementar. En mi caso, configuro -platform linux-g++-64 y -xplatform linux-win32-g++ donde linux-win32-g ++ es mi configuración win32-g ++ modificada.

Mi problema es que, después de ejecutar configure con estas opciones, veo que invoca el comstackdor de mi sistema en lugar del comstackdor cruzado (x86_64-w64-mingw32-gcc). Si -xplatform opción -xplatform y configuro -platform en mi especificación de destino (linux-win32-g ++), invoca el comstackdor cruzado pero luego los errores cuando se encuentran algunas funciones relacionadas con Unix no están definidas.

Aquí hay algunos resultados de mi último bash: http://pastebin.com/QCpKSNev .

Preguntas:

  1. Al comstackr de forma cruzada algo como Qt para Windows desde un host Linux, ¿debería invocarse alguna vez el comstackdor nativo? Es decir, durante un proceso de comstackción cruzada, ¿no deberíamos usar solo el comstackdor cruzado? No veo por qué el script de configuración de Qt intenta invocar el comstackdor nativo de mi sistema cuando especifico la opción -xplatform .

  2. Si estoy usando un comstackdor cruzado de mingw, ¿cuándo tendré que lidiar con un archivo de especificaciones? Los archivos de especificación para GCC todavía son una especie de misterio para mí, así que me pregunto si algún fondo aquí me ayudará.

  3. En general, más allá de especificar un comstackdor cruzado en mi qmake.conf, ¿qué más podría necesitar considerar?

Solo usa M cross environment (MXE) . Elimina el dolor de todo el proceso:

  • Consíguelo:

     $ git clone https://github.com/mxe/mxe.git 
  • Instalar dependencias de comstackción

  • Build Qt para Windows, sus dependencias y las herramientas de construcción cruzada; esto tomará aproximadamente una hora en una máquina rápida con acceso decente a internet; la descarga es de aproximadamente 500 MB:

     $ cd mxe && make qt 
  • Vaya al directorio de su aplicación y agregue las herramientas de construcción cruzada a la variable de entorno PATH :

     $ export PATH=/usr/bin:$PATH 
  • Ejecute la herramienta generadora Qt Makefile y luego compile:

     $ /usr/i686-pc-mingw32/qt/bin/qmake && make 
  • Deberías encontrar el binario en el directorio ./release:

     $ wine release/foo.exe 

Algunas notas :

  • Use la twig principal del repository MXE; parece obtener mucho más amor del equipo de desarrollo.

  • La salida es un binario estático de 32 bits, que funcionará bien en Windows de 64 bits.

(Esta es una actualización de la respuesta de @ Tshepang, ya que MXE ha evolucionado desde su respuesta)

Construyendo Qt

En lugar de usar make qt para construir Qt, puede usar MXE_TARGETS para controlar su máquina objective y su cadena de herramientas (32 o 64 bits). MXE comenzó a usar .static y .shared como parte del nombre del objective para mostrar qué tipo de lib que desea generar.

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

En la respuesta original de @ Tshepang, él no especificó un MXE_TARGETS , y se usa el predeterminado. En el momento en que escribió su respuesta, el valor predeterminado era i686-pc-mingw32 , ahora es i686-w64-mingw32.static . Si establece explícitamente MXE_TARGETS en i686-w64-mingw32 , omitiendo .static , se imprime una advertencia porque esta syntax ya no está disponible. Si intenta establecer el destino en i686-pc-mingw32 , se mostrará un error ya que MXE ha eliminado el soporte para MinGW.org (es decir, i686-pc-mingw32).

Ejecutando qmake

Cuando cambiamos MXE_TARGETS , el /usr/i686-pc-mingw32/qt/bin/qmake ya no funcionará. Ahora, lo que debes hacer es:

 /usr//qt/bin/qmake 

Si no especificó MXE_TARGETS , haga esto:

 /usr/i686-w64-mingw32.static/qt/bin/qmake 

Actualización: el nuevo valor predeterminado ahora es i686-w64-mingw32.static

Ok, creo que lo tengo resuelto.

Basado en parte en https://github.com/mxe/mxe/blob/master/src/qt.mk y https://www.videolan.org/developers/vlc/contrib/src/qt4/rules.mak

Parece que “inicialmente” cuando ejecuta configure (con -xtarget, etc.), configura luego ejecuta su gcc “hosts” para construir el archivo binario local ./bin/qmake

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

luego ejecutas el “make” normal y lo construye para mingw

  make make install 

asi que

  1. solo si necesita usar algo que no sea msvcrt.dll (su valor predeterminado). Aunque nunca he usado otra cosa, no lo sé con certeza.

  2. https://stackoverflow.com/a/18792925/32453 enumera algunos parámetros de configuración.

Para comstackr Qt, se debe ejecutar su script de configure , especificando la plataforma del host con -platform (por ejemplo, -platform linux-g++-64 si está construyendo en un Linux de 64 bits con el comstackdor g ++) y la plataforma de destino con -xplatform (por ejemplo, -xplatform win32-g++ si está comstackndo cruzado a Windows).

También agregué este indicador: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- que especifica el prefijo de la cadena de herramientas que estoy usando, que se agregará a ‘gcc’ o ‘g ++’ en todos los makefiles que están construyendo binarios para Windows.

Finalmente, puede tener problemas al generar icd , que aparentemente es algo que se usa para agregar soporte ActiveX a Qt. Puede evitar eso pasando el indicador – -skip qtactiveqt al script de configuración. Tengo este de este informe de error: https://bugreports.qt.io/browse/QTBUG-38223

Aquí está todo el comando de configuración que he usado:

  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 cuanto a tus preguntas:

1 – Sí. Se llamará al comstackdor nativo para construir algunas herramientas que se necesitan en el proceso de comstackción. Tal vez cosas como qconfig o qmake, pero no estoy del todo seguro de qué herramientas, exactamente.

2 – Lo siento No tengo idea de qué archivos de especificaciones están en el contexto de los comstackdores = /. Pero hasta donde yo sé, no tendrías que lidiar con eso.

3 – Puede especificar el prefijo del comstackdor cruzado en la línea de comandos de configuración en lugar de hacerlo en el archivo qmake.conf, como se mencionó anteriormente. Y también está ese problema con idc, cuya solución también he mencionado.

Otra forma de comstackción cruzada de software para Windows en Linux es la cadena de herramientas mingw-w64 en Archlinux. Es fácil de usar y mantener, y proporciona versiones recientes del comstackdor y muchas bibliotecas. Personalmente, me resulta más fácil que MXE y parece adoptar versiones más recientes de bibliotecas más rápido.

Primero necesitará una máquina basada en arco (la máquina virtual o el contenedor Docker serán suficientes). No tiene que ser Arch Linux, los derivados también lo harán. Usé Manjaro Linux. La mayoría de los paquetes de mingw-w64 no están disponibles en los repositorys oficiales de Arch, pero hay muchos en AUR . El administrador de paquetes predeterminado para Arch (pacman) no admite la instalación directamente desde AUR, por lo que deberá instalar y usar un contenedor AUR como pacaur o yaourt. Luego, instalar la versión mingw-w64 de las bibliotecas Qt5 y Boost es tan fácil como:

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

Esto también instalará la cadena de herramientas mingw-w64-gcc ( mingw-w64-gcc ) y otras dependencias. La comstackción cruzada de un proyecto de Qt para Windows (x64) es tan simple como:

 x86_64-w64-mingw32-qmake-qt5 make 

Para implementar su progtwig, deberá copiar los dlls correspondientes de /usr/x86_64-w64-mingw32/bin/ .

Para obtener una versión de 32 bits, simplemente necesita usar i686-w64-mingw32-qmake-qt5 en i686-w64-mingw32-qmake-qt5 lugar. Los proyectos basados ​​en Cmake funcionan igual de bien con x86_64-w64-mingw32-cmake . Este enfoque funcionó extremadamente bien para mí, fue el más fácil de configurar, mantener y extender. También funciona bien con servicios de integración continua. Hay imágenes acoplables disponibles también.

Por ejemplo, supongamos que quiero comstackr la GUI del descargador de subtítulos de QNapi. Podría hacerlo en dos pasos:

1) Comience el contenedor del acoplador:

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

2) Clona y comstack QNapi

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

¡Eso es! En muchos casos será así de fácil. Agregar sus propias bibliotecas al repository de paquetes (AUR) también es sencillo. Debería escribir un archivo PKBUILD , que es lo más intuitivo posible, consulte mingw-w64-rapidjson , por ejemplo.