En esta página, se explica qué son los sistemas de compilación, qué hacen y por qué deberías usar un de compilación y por qué los compiladores y las secuencias de comandos de compilación no son la mejor opción como la organización comienza a escalar. Está dirigido a desarrolladores que no tienen con un sistema de compilación.
¿Qué es un sistema de compilación?
Básicamente, todos los sistemas de compilación tienen un propósito claro: transforman el código fuente escrito por los ingenieros en binarios ejecutables que se pueden leer debido a las máquinas. Los sistemas de compilación no son solo para código creado por humanos, También permiten para crear compilaciones automáticamente, ya sea para pruebas o versiones producción. En una organización con miles de ingenieros, es común que la mayoría de las compilaciones son activadas automáticamente en lugar de hacerlo directamente por los ingenieros.
¿No puedo usar un compilador?
La necesidad de un sistema de compilación puede no ser obvia de inmediato. La mayoría de los ingenieros
no usan un sistema de compilación mientras aprenden a programar: la mayoría comienza con la invocación de herramientas
como gcc
o javac
directamente desde la línea de comandos, o el equivalente en una
entorno de desarrollo integrado (IDE). Siempre que todo el código fuente se encuentre en
el mismo directorio, un comando como este funciona bien:
javac *.java
Esto le indica al compilador Java que tome cada archivo de origen de Java del archivo y convertirlo en un archivo de clase de objeto binario. En el caso más sencillo, es todo lo que necesitas.
Sin embargo, tan pronto como se expande el código, comienzan las complicaciones. javac
es inteligente
para buscar en los subdirectorios del directorio actual y encontrar
importar. Sin embargo, no tiene manera de encontrar el código almacenado en otras partes de la
un sistema de archivos (quizás una biblioteca compartida por varios proyectos). Además, solo conoce
cómo compilar código Java. Los sistemas grandes suelen implicar diferentes piezas escritas
una variedad de lenguajes de programación
con redes de dependencias
lo que significa que ningún compilador para un lenguaje
puede compilar todo el sistema.
Cuando estés tratando con código de múltiples lenguajes o varias compilaciones unidades, la compilación de códigos ya no es un proceso de un solo paso. Ahora debes evaluar qué tu código depende y compila esas piezas en el orden correcto, posiblemente usando un conjunto diferente de herramientas para cada pieza. Si alguna dependencia cambia, debes repetir este proceso para evitar depender de objetos binarios inactivos. Para obtener una base de código incluso de tamaño moderado, este proceso rápidamente se vuelve tedioso y propenso a errores.
El compilador tampoco sabe nada sobre cómo controlar recursos
dependencias, como archivos JAR
de terceros en Java. Sin un sistema de compilación,
Puedes administrar esto descargando la dependencia de Internet,
en una carpeta lib
del disco duro y configurando el compilador para que lea
bibliotecas de ese directorio. Con el tiempo, es difícil mantener la
actualizaciones, versiones y fuentes
de estas dependencias externas.
¿Qué ocurre con las secuencias de comandos de shell?
Supongamos que tu proyecto de pasatiempo es lo suficientemente simple como para que puedas crearlo con un compilador, pero comienzas a encontrarte con algunos de los problemas descritos anteriormente. Tal vez todavía no creas que necesitas un sistema de compilación y puedes automatizar las partes tediosas con algunas secuencias de comandos de shell simples que se encargan y crear las cosas en el orden correcto. Esto ayuda por un tiempo, pero pronto comenzarás a tener aún más problemas:
Se vuelve tedioso. A medida que el sistema se hace más complejo, comienzas a casi la misma cantidad de tiempo en trabajar en las secuencias de comandos de compilación que en el código real. Depuración de shell es problemático, y cada vez más hackeos se añaden entre sí.
Es lento. Para asegurarte de no depender accidentalmente de bibliotecas inactivas, que tu secuencia de comandos de compilación compile cada dependencia en orden cada vez que y ejecutarla. Consideras agregar lógica para detectar qué partes pero eso suena muy complejo y propenso a errores en una secuencia de comandos. O piensas en especificar qué partes hay que reconstruir cada vez, pero entonces regresas al cuadrado uno.
¡Buenas noticias! ¡Llegó la hora del lanzamiento! Mejor descubre todos los argumentos debes pasar al comando jar para hacer la compilación final. Y recuerda y cómo subirlo y enviarlo al repositorio central. Y construir y actualizar la documentación y enviar una notificación a los usuarios. Mmm... quizás esto requiera otro guion...
¡Desastre! Tu disco duro falla y ahora debes recrear tu en un sistema de archivos. Fuiste lo suficientemente inteligente como para mantener todos tus archivos de origen en la versión pero ¿qué ocurre con las bibliotecas que descargaste? ¿Puedes encontrarlas? y asegurarse de que fueran la misma versión que cuando los descargaste? Tus secuencias de comandos probablemente dependían de herramientas específicas que se instalados en lugares particulares, ¿puede restablecer ese mismo entorno para que de que las secuencias de comandos funcionen de nuevo? ¿Qué pasa con todas esas variables de entorno que hace mucho tiempo para que el compilador funcione bien y luego lo olvidé?
A pesar de los problemas, tu proyecto es lo suficientemente exitoso como para que puedas empezar a contratar más ingenieros. Ahora te das cuenta de que no hace falta un desastre para que surjan los problemas anteriores, debes pasar por el mismo problema cada vez que un desarrollador nuevo se une a tu equipo. Y a pesar de tus mejores esfuerzos, aún hay pequeñas diferencias en cada en el sistema de la persona. A menudo, lo que funciona en la máquina de una persona no funciona. en la de otra y cada vez que se necesiten unas horas de rutas de acceso a herramientas versiones de bibliotecas para descubrir dónde está la diferencia.
Decides que necesitas automatizar tu sistema de compilación. En teoría, es tan simple como comprar una nueva computadora y configurarla para ejecutar tu compilación todas las noches con cron. Aún debes pasar por el doloroso del proceso de configuración, pero no tienes el beneficio de que el cerebro humano para detectar y resolver problemas menores. Todas las mañanas, ves que la compilación de anoche falló porque ayer realizó un cambio que funcionó en su sistema, pero no en la versión automatizada de compilación. Cada vez es una solución simple, pero ocurre tan a menudo que terminan dedicando mucho tiempo cada día a descubrir y aplicar estas prácticas soluciones.
Las compilaciones se vuelven cada vez más lentas a medida que el proyecto crece. Un día, mientras esperas para que se complete una compilación, contemplas con tristeza el escritorio inactivo de tu compañero de trabajo, que está de vacaciones, y desearía que hubiera una forma de aprovechar todo ese desperdicio de potencia de procesamiento.
Te topaste con un problema clásico de escala. Para un único desarrollador que trabaja en como máximo, un par decientas líneas de código, como máximo, una o dos semanas (que podrían tener fue toda la experiencia hasta ahora de un desarrollador junior que acaba de graduarse un compilador es todo lo que necesitas. Las secuencias de comandos pueden llevarte un poco más lejos. Pero tan pronto como sea necesario coordinar con varios desarrolladores sus máquinas, ni siquiera una secuencia de comandos de compilación perfecta es suficiente y difícil dar cuenta de las pequeñas diferencias entre esas máquinas. En este punto, Este enfoque simple se desglosa y es momento de invertir en un sistema de compilación real.