programa - proceso de compilacion en c
¿Por qué es importante separar los procesos de compilación y vinculación en C? (5)
En la práctica, no es importante en absoluto. Especialmente para programas más simples, ambos pasos se realizan con una llamada de programa como
gcc f1.c f2.c f3.c f4.c -o program
que crea el program
ejecutable a partir de estos archivos fuente.
Pero el hecho es que estos son procesos separados y en algunos casos vale la pena notar esto.
He estado programando en C por un tiempo y me pregunto por qué es importante separar estos procesos (compilar y vincular)?
¿Alguien puede explicar por favor?
Es útil para disminuir el tiempo reconstruido. Si cambia solo un archivo fuente, a menudo no es necesario volver a compilar todo el proyecto, sino solo uno o pocos archivos.
Probablemente sea menos importante en estos días que una vez.
Pero hubo un momento en que la compilación de un proyecto podía llevar literalmente días: solíamos hacer una "compilación completa" durante un fin de semana en los años ochenta. Solo analizar el código fuente de un solo archivo era un asunto bastante importante que requería una gran cantidad de tiempo y memoria, por lo que los lenguajes se diseñaron para que sus módulos (archivos fuente) pudieran procesarse de forma aislada.
El resultado fueron los "archivos de objetos": archivos .obj
(DOS / Windows / VMS) y .o
(Unix) - que contienen el código reubicable, los datos estáticos y las listas de exportaciones (objetos que hemos definido) y las importaciones (objetos que necesitamos). La etapa de vinculación une todo esto en un archivo ejecutable, o en un archivo (archivos .lib
, .a
, .so
, .dll
, etc.) para una mayor inclusión.
Hacer que la costosa tarea de compilación funcione aisladamente abrió el camino a sofisticadas herramientas de compilación incremental como make
, que produjo un aumento significativo en la productividad del programador, aún crítico para grandes proyectos de C, como el kernel de Linux.
También, de manera útil, significa que cualquier idioma que se pueda compilar en un archivo de objeto se puede vincular entre sí. Entonces, con un poco de esfuerzo, uno puede vincular C a Fortran a COBOL a C ++ y así sucesivamente.
Muchos idiomas desarrollados desde esos días han superado los límites de lo que se puede almacenar en los archivos de objetos. El sistema de plantillas de C ++ requiere un manejo especial, y los métodos sobrecargados tampoco encajan del todo, ya que los archivos .o
simples no admiten múltiples funciones con el mismo nombre (ver el cambio de nombre de C ++ ). Java y otros usan un enfoque completamente diferente, con formatos de archivo de código personalizados y un mecanismo de invocación de "código nativo" que se pega a las DLL y archivos de objetos compartidos.
Trabajé en sistemas donde lleva dos días compilarlos. No quiere hacer un pequeño cambio, entonces tiene que esperar 2 días para probar.
Debido a que la compilación es responsable de transformar el código fuente de cada archivo de código fuente en un código de objeto correspondiente. Eso es. Por lo tanto, el compilador no tiene que preocuparse por sus símbolos externos (como las bibliotecas y las variables extern
).
El enlace es responsable de encontrar esas referencias y luego producir un solo binario como si su proyecto se escribiera como un único archivo de código fuente. (También recomiendo que debe consultar la página de enlaces de wikipedia para conocer la diferencia entre los enlaces estáticos y dinámicos)
Si usa la herramienta Make
, verá que no recompila cada archivo cada vez que invoca make
, busca qué archivos se han modificado desde la última compilación y luego los vuelve a compilar. Luego se invoca el proceso de vinculación. Es un gran ahorro de tiempo cuando trabajas con grandes proyectos (por ejemplo, kernel de Linux).