2012-06-07 15 views
68

Quiero realizar una compilación cruzada de las bibliotecas de Qt (y, finalmente, de mi aplicación) para un destino de Windows x86_64 utilizando una máquina host Linux x86_64. Siento que estoy cerca, pero puedo tener un malentendido fundamental de algunas partes de este proceso.¿Cómo configuro Qt para la compilación cruzada de Linux a Windows?

Comencé instalando todos los paquetes mingw en mi máquina Fedora y luego modifiqué el archivo win32-g++ qmake.conf para adaptarme 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 arquitectura de máquina host (donde se está compilando) y -xplatform debe ser la plataforma de destino para la que desea implementar. En mi caso, establecí -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 compilador de mi sistema en lugar del compilador cruzado (x86_64-w64-mingw32-gcc). Si omito la opción -xplatform y establezco -platform en mi especificación de destino (linux-win32-g ++), invoca el compilador cruzado pero luego los errores cuando se encuentran algunas funciones relacionadas con Unix no están definidas.

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

Preguntas:

  1. Cuando compilación cruzada algo así como Qt para Windows desde un servidor Linux, si el compilador nativo vez ser invocados? Es decir, durante un proceso de compilación cruzada, ¿no deberíamos usar solo el compilador cruzado? No veo por qué el script de configuración de Qt intenta invocar el compilador nativo de mi sistema cuando especifico la opción -xplatform.

  2. Si uso un compilador cruzado de mingw, ¿cuándo tendré que tratar 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 compilador cruzado en mi qmake.conf, ¿qué más podría tener que considerar?

+2

Creo que necesita una compilación local de qmake para arrancar el resto de la compilación. ver también enlaces en http://stackoverflow.com/questions/1025687/cross-compile-in-linux-or-windows –

+0

Ok, eso tiene sentido. Ahora acabo de encontrar otro problema, parece que estoy mezclando cadenas de herramientas nativas y cruzadas. El error en mi salida pastebin parece deberse a la llamada 'x86_64-w64-mingw32-as' en lugar de la nativa. –

+2

Raramente marcó una pregunta de SO como favorita, pero esta fue una pregunta única e interesante con una respuesta genial. – jdi

Respuesta

54

Simplemente use M cross environment (MXE).Se elimina la dificultad de todo el proceso:

  • conseguirlo:

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

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

    $ cd mxe && make qt 
    
  • Ir al directorio de la aplicación y añadir las herramientas de compilación cruzada a la ambiente variable PATH:

    $ export PATH=<mxe root>/usr/bin:$PATH 
    
  • Ejecutar el generador de Qt Makefile herramienta luego construir:

    $ <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake && make 
    
  • Debe encontrar el binario en el./Release directorio:

    $ wine release/foo.exe 
    

Algunas notas:

  • Uso de la rama principal del repositorio 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.

+15

** nota **: estas instrucciones se aplican a Qt 4; para Qt 5, consulte http://stackoverflow.com/a/14170591 – Tshepang

+0

Consulte mi respuesta a continuación para obtener una actualización. –

+0

Antes de ejecutar '$ cd mxe && make qt' debes instalar los requisitos.Para sistemas Debian esto 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-analizador-perl make openssl patch perl pkg-config python ruby ​​scons sed descomprimir wget xz-utils'. Para otros sistemas, consulte http://mxe.cc/#requirements –

3

Ok, creo que lo tengo resuelto.

basa 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.), se configura entonces funciona de gcc "hosts" para construir el archivo binario local./bin/qmake

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

entonces se corre normal "hacer" y se construye para MinGW

make 
    make install 

por lo

  1. sólo si es necesario utilizar algo más que msvcrt.dll (su valor por defecto). 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.

12

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

Edificio Qt

En lugar de utilizar make qt para construir Qt, puede utilizar MXE_TARGETS para controlar su máquina de destino y cadena de herramientas (32 o 64 bits). MXE comenzó a usar .static y .shared como parte del nombre de destino 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 @ respuesta original de Tshepang, que no ha especificado un MXE_TARGETS, y se utiliza el valor 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 sintaxis ahora está en desuso. Si intenta establecer el destino en i686-pc-mingw32, se mostrará un error ya que MXE ha eliminado la compatibilidad con MinGW.org (es decir, i686-pc-mingw32).

Correr qmake

Como hemos cambiado el MXE_TARGETS, el comando <mxe root>/usr/i686-pc-mingw32/qt/bin/qmake ya no funcionará. Ahora, lo que hay que hacer es:

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

Si no se ha especificado MXE_TARGETS, haga lo siguiente:

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

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

+0

Muchas gracias por la actualización. También es bueno que alguien que trabaja directamente en el proyecto responda. – Tshepang

+2

Esto debería haber sido una edición/actualización de la otra respuesta, no una nueva. – WhyNotHugo

+2

@Hugo La página de edición dice: Cómo editar: ► corregir los errores gramaticales o de ortografía ► aclarar el significado sin cambiarlo ► pequeños errores correctos ► añadir recursos relacionados o enlaces ► Siempre respeto al autor original Este es ninguno de esos. Es una extensión de la respuesta de Tshepang. –

2

Con el fin para compilar Qt, se debe ejecutar su script configure, especificando la plataforma de host con -platform (por ejemplo, -platform linux-g++-64 si está construyendo en un Linux de 64 bits con el compilador g ++) y la plataforma de destino con -xplatform (p. -xplatform win32-g++ si está compilando cruzado a Windows).

También he añadido esta bandera: -device-option CROSS_COMPILE=/usr/bin/x86_64-w64-mingw32- que especifica el prefijo de la cadena de herramientas que estoy usando, que conseguirá colocado al comienzo de 'gcc' o 'g ++' en todos los archivos MAKE que están construyendo los binarios para Windows.

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

Aquí está todo el comando configure 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 las preguntas yout:

1 - Sí. Se llamará al compilador nativo para construir algunas herramientas que se necesitan en el proceso de compilació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 compiladores = /. Pero hasta donde yo sé, no tendrías que lidiar con eso.

3 - Puede especificar el prefijo del compilador 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.

0

Otra forma de compilació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 compilador 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 bastarán). 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 repositorios oficiales de Arch, pero hay plenty in 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 de instalar la versión MinGW-W64 de QT5 y Boost bibliotecas 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 se instalará la cadena de herramientas MinGW-W64 (mingw-w64-gcc) y otras dependencias. -Cruz compilar un proyecto de Qt para Windows (x64) es tan sencillo como:

x86_64-w64-mingw32-qmake-qt5 
make 

Para implementar programar tendrá que copiar archivos DLL correspondientes de /usr/x86_64-w64-mingw32/bin/.

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

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

1) Iniciar el contenedor ventana acoplable:

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

2) Clon y compilar QNapi

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

Eso es todo! En muchos casos será así de fácil. Agregar sus propias bibliotecas al repositorio de paquetes (AUR) también es sencillo. Necesitaría write a PKBUILD file, que es lo más intuitivo posible, consulte mingw-w64-rapidjson, por ejemplo.

Cuestiones relacionadas