¿Por qué los compiladores generalmente solo generan ejecutables para la plataforma en la que están instalados?

10

Soy desarrollador de C ++ y en un intento por comprender mejor el desarrollo multiplataforma, estoy tratando de comprender mejor algunos detalles de implementación de los compiladores y cómo crean exactamente los archivos binarios específicos del sistema operativo. En medio de mi estudio, me di cuenta de que, al menos por un tiempo, la mayoría de los compiladores que descargaste para una plataforma específica solo compilaron binarios para esa plataforma. Entonces, si descargó un IDE que vino con un compilador exe para Windows, entonces ese compilador solo podría compilar su programa para aplicaciones de Windows x86-x64 y no para aplicaciones Linux o Mac.

Ahora entiendo que las diferentes plataformas requieren diferentes formatos binarios, pero ¿qué dificulta que el compilador visual de C ++ en Windows genere un archivo ejecutable binario de Linux? Mientras tenga las instrucciones de ensamblaje para la CPU en la que se está ejecutando, así como las bibliotecas específicas del sistema operativo, ¿no debería poder compilar ejecutables para cualquier plataforma en cualquier máquina?

Jason
fuente
55
Hay muchos compiladores cruzados: no estoy seguro de por qué piensas que la compilación cruzada es poco común. Visual C ++ tiene sentido dado que Microsoft quiere el bloqueo de Windows, pero incluso proporcionan herramientas de compilación de Android en VS2017.
Bueno, muchos otros sitios parecían funcionar como un compilador de compilación cruzada que es muy difícil de implementar y solo hasta hace poco han surgido más compiladores multiplataforma. Si esto es cierto, me pregunto qué dificultaría la compilación cruzada si solo necesita ciertas instrucciones de ensamblaje de la CPU y llamadas a sistemas nativos para el sistema operativo correspondiente
Jason
Creo que tiene un problema de comprensión de terminología aquí que puede ser confuso. Estás utilizando el "compilador cruzado" y el "compilador multiplataforma" indistintamente, pero son cosas diferentes (aunque relacionadas): un compilador cruzado es un compilador para una plataforma que es diferente a la que estás usando, y tales cosas han estado disponibles durante tanto tiempo como los compiladores. Un compilador multiplataforma es un compilador que utiliza un paso intermedio para separar el procesamiento y la optimización del lenguaje fuente de la generación de código específico de la plataforma para que pueda usarse. ..
Jules
... para compilar código para múltiples plataformas de destino con cambios mínimos. Tales cosas son una innovación más reciente y mucho más compleja.
Jules

Respuestas:

18

¿Qué dificulta que el compilador visual de C ++ en Windows genere un archivo ejecutable binario de Linux?

Aparte de la falta de voluntad para hacer eso por parte de Microsoft, absolutamente nada. Los obstáculos no son técnicos.

Las cadenas de herramientas de desarrollo son solo programas que toman datos y producen resultados. Visual C ++ produce un ensamblado x86 y luego usa un ensamblador para convertirlo en un archivo de objeto COFF. Si Microsoft quería que generara ELF, es solo código: el ensamblaje entra, ELF se apaga. No hay nada mágico en los archivos de objetos o bibliotecas; son solo bloques de datos en un formato bien entendido.

En la edad de piedra, la compilación cruzada era mucho más difícil porque la mayoría de las veces, habría estado escribiendo la cadena de herramientas para su plataforma de destino en el ensamblaje de la plataforma donde se ejecutaría. Esto significaba que si todo lo que había en el mundo fueran las arquitecturas VAX, M68K y Alpha, un conjunto completo de compiladores cruzados requeriría escribir nueve de ellos, la mayoría desde cero. (VAX-to-VAX, VAX-to-M68K, VAX-to-Alpha, M68K-to-VAX, M68K-to-M68K, etc.) Eso es un poco exagerado ya que partes del compilador VAX podrían reutilizarse y conectado a generadores de código para cada objetivo (por ejemplo, VAX, M68K y Alpha, cada uno escrito para VAX).

Ese problema desapareció cuando comenzamos a escribir compiladores en un lenguaje que no estaba vinculado a un procesador específico, como C. Seguir esa ruta significa que escribes toda la cadena de herramientas una vez en C y usas una plataforma escrita para la plataforma local. C compilador para construirlo. (A menudo se usa el compilador para volver a compilarse después de haber sido inicializado en el compilador de la plataforma local, pero esa es otra discusión). El resultado de esto es que construir un compilador cruzado se convirtió esencialmente en el mismo esfuerzo que construir un compilador nativo en La plataforma local. La única diferencia significativa es que en algún lugar del proceso de compilación, usted le dijo que compilara en el generador de código para su plataforma de destino en lugar del de la plataforma local, lo que habría sido la elección lógica.

A medida que evolucionó la arquitectura de los compiladores, se volvió conveniente incluir y construir todos los generadores de código con el producto y seleccionar cuál se usa en el tiempo de ejecución. Clang / LLVM hace esto, y estoy seguro de que hay otros.

Una vez que tiene una cadena de herramientas en funcionamiento (compilador, ensamblador, enlazador), las bibliotecas se crean a partir de fuentes y, finalmente, termina con todo lo que necesita para producir un archivo ejecutable para alguna otra plataforma.

Blrfl
fuente
Esta es ahora la mejor y más profunda respuesta. Creo que la historia realmente ayuda a entender el contexto.
Jason
3
@ Jason A veces vale la pena ser viejo. :-)
Blrfl
44
"Aparte de la falta de voluntad para hacer eso por parte de Microsoft, absolutamente nada". - No lo llamaría "falta de voluntad". Microsoft es una empresa orientada al lucro que cotiza en bolsa; tienen ciertas responsabilidades con sus accionistas y partes interesadas. Tendrían que contratar, entrenar y pagar a los desarrolladores para el backend de Linux, necesitarían contratar, entrenar y pagar a los probadores para el backend de Linux, tendrían que contratar, entrenar y pagar al personal de soporte familiarizado con el backend de Linux, tendrían que diseñar, desarrollar, mantener, respaldar y extender el código, todo para una plataforma que sea ...
Jörg W Mittag el
... fuera de su negocio principal. Y todo eso solo para agregar un compilador n + 1 a los compiladores n ya existentes que también podría usar. ¿Cuál sería el beneficio comercial para que Microsoft compita con GCC, Clang, ICC (Intel), xlc (IBM), Digital Mars, tcc, pcc, TenDRA, Metrowerks, PathScale, ...? Personalmente, no creo que haya ninguno.
Jörg W Mittag el
3
@ JörgWMittag What would be the business benefit ... I don't think there is any.: eso parece una buena razón para no estar dispuesto a hacerlo.
Blrfl
8

Sí, si tiene toda la información sobre su plataforma de destino, entonces no debería importar en qué plataforma se esté ejecutando realmente.

Hay dos problemas que tienden a surgir:

  1. La gente no se enfoca en eso porque es un escenario menos común. A menudo, lo único que compila en forma cruzada es un compilador para poder detener la compilación cruzada. Menos concentración significa peor apoyo.
  2. Los programas no triviales necesitan más que solo código. Tratar con la inclusión / vinculación de la biblioteca se vuelve un poco más fácil cuando tiene bibliotecas para la plataforma en la que se está ejecutando. Estarán en una ubicación conocida, en una codificación bien conocida.

Esos no son insuperables, por supuesto. Principalmente, obtienes compiladores que se dirigen a la plataforma en la que se ejecutan porque eso es lo que la gente quiere.

Telastyn
fuente
Veo. Gracias por la aclaración. Definitivamente tiene más sentido para mí ahora.
Jason
Le culpo al intellisense.
JeffO
2

No estoy de acuerdo con tu premisa. Hay millones de desarrolladores de Android e iOS. Y todos usan compiladores que se ejecutan en Windows o Mac, produciendo código para una computadora completamente diferente.

No obtendrá un compilador cruzado si no hay demanda en el mercado. Las personas que desarrollan código para un escritorio Linux, por ejemplo, en su mayoría tienen un escritorio Linux disponible y usarán un compilador basado en Linux, mucho más rápido si puede ejecutar su aplicación directamente en la máquina donde se compila sin transportarla a través de la red, mucho más fácil y más rápido tener un depurador ejecutándose en la misma máquina y así sucesivamente.

Entonces, ¿cuánto más dinero ganaría Microsoft si sus compiladores también construyeran para Linux? Aproximadamente $ 0. ¿Cuánto más software para Windows se crearía? Ninguna. ¿Cuánto más software de Linux se crearía? No tengo idea, pero no es algo que a Microsoft le importe. ¿Cuál sería el costo? Bastante considerable. Los compiladores deben estar libres de errores. Deben ser probados.

Otro problema: si escribe un compilador escribiendo en Windows, necesita a alguien que sepa cómo escribir el software de Windows. Si escribe un compilador para Linux, necesita a alguien que sepa cómo escribir software de Linux. Si escribe un compilador para Linux que se ejecuta en Windows, de repente necesita el pan de desarrollador mucho más raro que conoce Windows y Linux.

gnasher729
fuente
"Hay millones de desarrolladores de Android e iOS. Y todos usan compiladores que se ejecutan en Windows o Mac, produciendo código para una computadora completamente diferente". Um no, no lo hacen. Muchos, muchos desarrolladores de Android usan Linux, y de hecho es la plataforma más popular para desarrolladores según la propia encuesta de StackExchange.
Miles Rout