Compilación de programas en C

Author
Por Darío Rivera
Publicado el en Lenguaje C

En un post anterior vimos cómo crear nuestro primer programa en C, el clásico Hola Mundo!. Sin embargo, vimos una manera muy sencilla de compilar y ejecutar dicho programa. El día de hoy veremos un poco más a fondo cómo compilar programas en lenguaje C.

Proceso de compilación

Antes que nada veamos un poco el proceso mediante el cual un programa se convierte en un ejecutable en C.

diagrama compilación

Todo comienza con la edición del programa mediante un edior con el cual guardamos el archivo con extensión .c. Este archivo es el punteo de entrada para el compilador el cual lo convierte en un archivo objeto con extensión .o o .obj en algunos compiladores. Finalmente el enlazador o editor de enlace lo transforma en un archivo ejecutable por la máquina. Generalmente si no se especifica la extensión será un archivo .out.

Adicionalmente, este archivo puede ser tomado por el depurador para hacer debug cuando obtenemos resultados inesperados o cuando queremos verificar que todo está bien ejecutando el programa paso a paso.

El proceso de compilación suele ser un poco más complejo que el mostrado anteriormente. Cuando se invoca al compilador, el preprocesador es el encargado (antes de compilar) de procesar las directrices del compilador. Esto es, todas las líneas que empiezen con el caracter #. Una vez hecho esto, se pasa el archivo al compilador para realizar el proceso de compilación.

diagrama compilación

Instalación del compilador

La mayoría de sistemas Linux cuentan con compiladores de C y C++. En sistemas basados en GNU/Linux Debian basta ejecutar el siguiente comando para instalar el compilador GCC.

sudo apt-get install gcc

Si utilizas Ubuntu puedes seguir este tutorial que te da todo lo necesario para empezar con C.

- Empezar con C en Ubuntu 22.04 (Jammy Jellyfish)

Compilación sencilla

Recordemos que para compilar un programa solo basta ejecutar el comando de compilación, en nuestro caso gcc y espeficar el nombre del archivo.

gcc program.c

Esto creará por defecto el archivo de salida llamado a.out. Para especificar el nombre del archivo de salida podemos utilizar la opción -o.

gcc program.c -o program

En donde program.c es el archivo con código C y program será el archivo compilado que será generado. Aún cuando nuestro programa tenga referencias a otros archivos de cabecera solo necesitaremos compilar nuestro archivo principal. Ejemplo:

main.c

#include <stdio.h>
#include "variables.c"

int main()
{
    printf("PI is %.4f\n", pi);
    return 0;
}

variables.c

float pi = 3.1516;

Este programa hace un include del archivo variables.c. Lo que hace el preprocesador en estos casos es incluir el contenido del archivo en nuestro archivo principal para procesarlo como si fuera uno solo. Entender esto es muy importante ya que si tenemos programas realmente grandes puede ser un dolor de cabeza compilar todo el programa de esta manera.

Compilación de múltiples archivos

La compilación de múltiples archivos ocurre cuando agregamos archivos de cabecera que generalmente provienen de librerías externas. Veamos el siguiente ejemplo:

main.c

#include <stdio.h>
#include "mylib.h"

int main()
{
    printf("PI is %.4f\n", pi);
    return 0;
}

mylib.h

extern float pi;

mylib.c

float pi = 3.1516;

para compilar este programa debemos correr el siguiente comando referenciando a nuestros dos archivos con extensión .c.

gcc main.c mylib.c

Nota que se ha utilizado extern para referenciar a variables creadas en otro archivo. Este modificador tiene la ventaja de no crear un nuevo espacio en memoria y permitir modularizar nuestro programa. Este mismo ejemplo lo pudieras compilar por pasos, algo que sería muy útil en aplicaciones grandes en donde si hacemos un cambio en un archivo tendríamos que compilar toda la aplicación nuevamente.

gcc -c mylib.c
gcc -c main.c
gcc main.o mylib.o

Al ejecutar gcc -c archivo.c se genera un archivo objeto. Esto es así ya que el parámetro -c evita que el compilador enlace los archivos, por lo cual, generá los archivos objeto para que nosotros mismos hagamos el enlace.

Los archivos con extensión .o son archivos objeto que el compilador ha procesado y son pasados al linker (enlazador) para generar un programa ejecutable.

Si tuvieramos un número muy grande de dependencias y realizaramos un cambio en la dependencia X, el paso a seguir para compilar sería el mismo.

gcc -c X.c
gcc -c main.c
gcc main.o X.o A.o B.o C.o

En donde A.o, B.o, C.o son otras dependencias generadas.

Ejecución

Para correr el programa basta ejecutarlo de la siguiente manera:

./output

Acerca de Darío Rivera

Author

Application Architect at Elentra Corp . Quality developer and passionate learner with 10+ years of experience in web technologies. Creator of EasyHttp , an standard way to consume HTTP Clients.

LinkedIn Twitter Instagram

Sólo aquellos que han alcanzado el éxito saben que siempre estuvo a un paso del momento en que pensaron renunciar.