¿Por qué usar un sistema de compilación?

Informar un problema Ver fuente Noche {/2/}}

En esta página, se explica qué son los sistemas de compilación, qué hacen, por qué deberías usar un sistema de compilación y por qué los compiladores y las secuencias de comandos de compilación no son la mejor opción a medida que tu organización comienza a escalar. Está dirigido a desarrolladores que no tienen mucha experiencia 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 objetos binarios ejecutables que las máquinas pueden leer. Los sistemas de compilación no son solo para código creado por personas, también permiten que las máquinas creen compilaciones automáticamente, ya sea para pruebas o actualizaciones para producción. En una organización con miles de ingenieros, es común que la mayoría de las compilaciones se activen de forma automática en lugar de hacerlo directamente por parte de 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 por invocar herramientas como gcc o javac directamente desde la línea de comandos, o su equivalente en un entorno de desarrollo integrado (IDE). Siempre que todo el código fuente se encuentre en el mismo directorio, un comando como este funcionará bien:

javac *.java

Esto le indica al compilador de Java que tome cada archivo fuente Java del directorio actual y lo convierta en un archivo de clase binaria. En el caso más simple, esto es todo lo que necesitas.

Sin embargo, tan pronto como se expande el código, comienzan las complicaciones. javac es lo suficientemente inteligente como para buscar en los subdirectorios del directorio actual el código para importar. Sin embargo, no tiene forma de encontrar el código almacenado en otras partes del sistema de archivos (quizás una biblioteca compartida por varios proyectos). Además, solo sabe cómo compilar código Java. Los sistemas grandes suelen implicar diferentes partes escritas en una variedad de lenguajes de programación con redes de dependencias entre esas partes, lo que significa que ningún compilador para un solo lenguaje puede compilar todo el sistema.

Una vez que trabajas con código de varios lenguajes o unidades de compilación, la compilación de código ya no es un proceso de un solo paso. Ahora debes evaluar de qué depende tu código y compilar esas partes en el orden adecuado, posiblemente con un conjunto de herramientas diferente para cada pieza. Si alguna dependencia cambia, debes repetir este proceso para evitar depender de objetos binarios inactivos. Para una base de código de tamaño moderado, este proceso rápidamente se vuelve tedioso y propenso a errores.

El compilador tampoco sabe nada sobre cómo controlar dependencias externas, como archivos JAR de terceros en Java. Sin un sistema de compilación, puedes administrar esto descargando la dependencia de Internet, mantenla en una carpeta lib del disco duro y configurando el compilador para que lea las bibliotecas de ese directorio. Con el tiempo, es difícil mantener las actualizaciones, las versiones y la fuente 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 compilarlo con solo 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 de compilar las cosas en el orden correcto. Esto te ayudará un tiempo, pero muy pronto comenzarás a tener aún más problemas:

  • Se vuelve tedioso. A medida que tu sistema se vuelve más complejo, comienzas a dedicar casi el mismo tiempo a trabajar en tus secuencias de comandos de compilación que en el código real. La depuración de secuencias de comandos de shell es complicada, ya que cada vez más hackeos se superponen.

  • Es lento. Para asegurarte de no depender accidentalmente de bibliotecas inactivas, haz que tu secuencia de comandos de compilación compile cada dependencia en orden cada vez que la ejecutes. Consideras agregar lógica para detectar qué partes se deben reconstruir, pero eso suena muy complejo y propenso a errores para una secuencia de comandos. O piensas en especificar qué partes se deben reconstruir cada vez, pero vuelves al cuadrado.

  • ¡Buenas noticias! ¡Llegó la hora del lanzamiento! Averigua mejor todos los argumentos que debes pasar al comando jar para hacer la compilación final. Y recuerda cómo subirlo y enviarlo al repositorio central. Además, compila y envía las actualizaciones de la documentación, y envía una notificación a los usuarios. Quizás esto requiera otra secuencia de comandos...

  • ¡Desastre! Tu disco duro falla y ahora debes volver a crear todo el sistema. Fuiste lo suficientemente inteligente como para mantener todos tus archivos de origen en el control de versión, pero ¿qué pasa con las bibliotecas que descargaste? ¿Puedes volver a encontrarlas y asegurarte de que fueran de la misma versión que cuando las descargaste por primera vez? Es probable que tus secuencias de comandos dependieran de herramientas específicas que se instalaran en lugares específicos. ¿Puedes restablecer ese mismo entorno para que las secuencias de comandos vuelvan a funcionar? ¿Qué pasa con todas esas variables de entorno que configuraste hace mucho tiempo para que el compilador funcione correctamente y, luego, te olvidaste?

  • A pesar de los problemas, tu proyecto tiene el éxito suficiente como para que puedas comenzar a contratar más ingenieros. Ahora te das cuenta de que los problemas anteriores no necesitan ningún desastre; debes pasar por el mismo proceso de inicio problemático cada vez que un desarrollador nuevo se une a tu equipo. A pesar de todos tus esfuerzos, aún existen pequeñas diferencias en el sistema de cada persona. Por lo general, lo que funciona en la máquina de una persona no funciona en el de otra, y cada vez se requieren unas horas de rutas de herramientas de depuración o versiones de biblioteca para descubrir dónde se encuentra la diferencia.

  • Decides que necesitas automatizar tu sistema de compilación. En teoría, esto es tan simple como obtener una computadora nueva y configurarla para que ejecute tu secuencia de comandos de compilación todas las noches con cron. Aún debes completar el doloroso proceso de configuración, pero ahora no tienes el beneficio de que un cerebro humano sea capaz de detectar y resolver problemas menores. Ahora, todas las mañanas, cuando ingresas, ves que la compilación de anoche falló porque ayer un desarrollador realizó un cambio que funcionaba en su sistema, pero no en el sistema de compilación automatizado. Cada vez es una solución simple, pero ocurre tan a menudo que pasas mucho tiempo cada día descubriendo y aplicando estas soluciones simples.

  • Las compilaciones se vuelven cada vez más lentas a medida que el proyecto crece. Un día, mientras esperas que se complete una compilación, observas con tristeza el escritorio inactivo de tu compañero de trabajo, que está de vacaciones, y te gustaría aprovechar toda esa capacidad de procesamiento desperdiciada.

Te topaste con un problema clásico de escala. Para un desarrollador que trabaja como máximo en doscientas líneas de código durante una o dos semanas como máximo (lo que podría haber sido toda la experiencia hasta ahora para un desarrollador júnior que acaba de graduarse de la universidad), todo lo que necesitas es un compilador. Las secuencias de comandos pueden ayudarte un poco más lejos. Sin embargo, apenas necesitas coordinar entre varios desarrolladores y sus máquinas, incluso una secuencia de comandos de compilación perfecta no es suficiente, ya que resulta muy difícil tener en cuenta las pequeñas diferencias en esas máquinas. En este punto, este enfoque simple se desglosa y es momento de invertir en un sistema de compilación real.