Compilar tu primer programa de Allegro 4 en Linux

Si has seguido los posts anteriores sobre Allegro es probable que ahora lo tengas instalado en tu distro de Linux. Si lo instalaste desde el repositorio de software de tu distro entonces no deberías tener problemas para compilar tus programas pero si lo instalaste manualmente en una carpeta personal entonces tal vez te encuentres con algún error al intentar compilar tu programa. Este post describe algunos de los errores más comunes al intentar compilar tus programas desde la línea de comandos en Linux.

Antes que nada, aquí hay un pequeño programa de prueba para Allegro 4 que puedes usar para seguir los ejemplos en este post.

// ejemplo-allegro-4.c
#include <allegro.h>
BITMAP *offscreen;
int main() {
    allegro_init();
    install_timer();
    install_keyboard();
    set_color_depth(desktop_color_depth());
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
    offscreen = create_bitmap(640, 480);
    while (!key[KEY_ESC]) {
        circlefill(offscreen, rand() % 640, rand() % 480, rand() % 60, rand() & 0xFF0000);
        blit(offscreen, screen, 0, 0, 0, 0, 640, 480);
        rest(15);
    }
    destroy_bitmap(offscreen);
}
END_OF_MAIN()

Si intentas compilar el código anterior con la siguiente instrucción es posible que obtengas un error indicando que el compilador no pudo encontrar el archivo allegro.h. Este es un error común si nunca has compilado un programa desde la línea de comandos y significa que el compilador no pudo encontrar el archivo especificado en las rutas predeterminadas de búsqueda:

monstruosoft@PC:~/code/allegro$ gcc ejemplo-allegro-4.c 
ejemplo-allegro-4.c:1:21: fatal error: allegro.h: No existe el fichero o el directorio
 #include <allegro.h>
                     ^
compilation terminated.

Cuando compilas un programa de Allegro desde la línea de comandos, el compilador busca los archivos necesarios en las rutas predefinidas, eso quiere decir que si instalaste Allegro desde el administrador de paquetes de tu distro no deberías ver un error como el anterior ya que Allegro estará instalado en las rutas del compilador. Sin embargo, si instalaste Allegro en una ruta distinta debes indicarle al compilador las rutas en las que debe buscar aparte de las rutas predeterminadas; esto se logra con el argumento -I como en el siguiente ejemplo:

monstruosoft@PC:~/code/allegro$ gcc ejemplo-allegro-4.c -I/home/monstruosoft/libs/usr/local/include/
/tmp/cckFoA4J.o: En la función `main':
ejemplo-allegro-4.c:(.text+0x25): referencia a `_install_allegro_version_check' sin definir
ejemplo-allegro-4.c:(.text+0x2a): referencia a `install_timer' sin definir
ejemplo-allegro-4.c:(.text+0x2f): referencia a `install_keyboard' sin definir
ejemplo-allegro-4.c:(.text+0x34): referencia a `desktop_color_depth' sin definir
ejemplo-allegro-4.c:(.text+0x3b): referencia a `set_color_depth' sin definir
ejemplo-allegro-4.c:(.text+0x5a): referencia a `set_gfx_mode' sin definir
ejemplo-allegro-4.c:(.text+0x69): referencia a `create_bitmap' sin definir
ejemplo-allegro-4.c:(.text+0x132): referencia a `circlefill' sin definir
ejemplo-allegro-4.c:(.text+0x139): referencia a `screen' sin definir
ejemplo-allegro-4.c:(.text+0x168): referencia a `blit' sin definir
ejemplo-allegro-4.c:(.text+0x176): referencia a `rest' sin definir
ejemplo-allegro-4.c:(.text+0x17d): referencia a `key' sin definir
ejemplo-allegro-4.c:(.text+0x194): referencia a `destroy_bitmap' sin definir
collect2: error: ld returned 1 exit status

Como puedes ver, ahora que le has indicado al compilador la ruta en la que puede encontrar los archivos de cabecera .h ya no obtienes el error anterior, sin embargo ahora obtienes un número de referencias sin definir; éstas de hecho son un error del linker, no del compilador, como lo puedes ver en la última línea indicando que el programa ld fue el que regresó un código de error. Este tipo de errores indica que el compilador no encontró errores en el código pero a la hora de intentar generar el archivo ejecutable no pudo localizar las funciones a las que hace referencia el código. Normalmente no compilas el código de dichas funciones cada que compilas un programa; en su lugar, esas funciones ya se encuentran compiladas en un archivo comúnmente llamado biblioteca (o librería, por la extensión de archivo .lib) con el que puedes enlazar tu programa; este “enlace” es lo que hace el linker. Las bibliotecas pueden venir comúnmente en dos posibles versiones: estáticas o dinámicas. Cualquiera que sea el caso, debes indicar cuales son las bibliotecas con las que quieres enlazar tu programa; esto se logra con el argumento -l (es una letra L minúscula) para indicar las bibiliotecas con las que quieres enlazar tu programa y que se puede usar en conjunto con el argumento -L para indicar rutas alternativas en las que el linker puede encontrar las bibliotecas en caso de que hayan sido instaladas en una ruta que no sea la predeterminada del sistema. Así, siguiendo con el ejemplo anterior, debemos especificar la biblioteca de Allegro 4 (llamada simplemente alleg) así como la ruta personalizada en la que fue instalada:

monstruosoft@PC:~/code/allegro$ gcc ejemplo-allegro-4.c -I/home/monstruosoft/libs/usr/local/include/ -L/home/monstruosoft/libs/usr/local/lib/ -lalleg

Esta vez el compilador no debería generar ningún error y generará un archivo ejecutable con un nombre definido por el mismo compilador (en este caso me generó un archivo ejecutable llamado a.out). Puedes especificar el nombre del archivo ejecutable usando el argumento -o, como se muestra a continuación:

monstruosoft@PC:~/code/allegro$ gcc ejemplo-allegro-4.c -I/home/monstruosoft/libs/usr/local/include/ -L/home/monstruosoft/libs/usr/local/lib/ -lalleg -o ejemplo-allegro-4

Ahora que tienes un archivo ejecutable sólo tienes que ejecutarlo y, dependiendo de si instalaste Allegro en las rutas predeterminadas del sistema o en una carpeta personalizada, pueder ser que el programa se ejecute sin problemas o bien que recibas un error como el siguiente:

monstruosoft@PC:~/code/allegro$ ./ejemplo-allegro-4 
./ejemplo-allegro-4: error while loading shared libraries: liballeg.so.4.4: cannot open shared object file: No such file or directory

Como puedes ver, el error anterior indica que no se pudo cargar la biblioteca dinámica liballeg.so.4.4; esto se debe a que compilamos Allegro para generar bibliotecas dinámicas (es la operación predeterminada al compilar Allegro) y enlazamos nuestro programa con dichas bibliotecas dinámicas, en este caso con liballeg.so.4.4, indicada en el comando con el que compilamos nuestro programa por el argumento -lalleg (puedes ver en el listado de archivos que el archivo liballeg.so es un symlink al archivo liballeg.so.4.4). Así que si las bibliotecas dinámicas no se encuentran en las rutas del sistema, tu programa no podrá ejecutarse; para ello, así como se hizo para compilar el programa, para ejecutarlo es necesario indicar la ruta en la que se pueden encontrar las bibliotecas dinámicas.

Las rutas en las que el sistema puede buscar las bibliotecas dinámicas se pueden especificar en la variable de entorno LD_LIBRARY_PATH. Para ejecutar tu programa debes agregar la ruta de las bibliotecas dinámicas a la variable de entorno LD_LIBRARY_PATH y después hacerla visible al sistema con el comando export.

monstruosoft@PC:~/code/allegro$ echo $LD_LIBRARY_PATH

monstruosoft@PC:~/code/allegro$ LD_LIBRARY_PATH=~/libs/usr/local/lib/
monstruosoft@PC:~/code/allegro$ echo $LD_LIBRARY_PATH
/home/monstruosoft/libs/usr/local/lib/
monstruosoft@PC:~/code/allegro$ ./ejemplo-allegro-4 
./ejemplo-allegro-4: error while loading shared libraries: liballeg.so.4.4: cannot open shared object file: No such file or directory
monstruosoft@PC:~/code/allegro$ export LD_LIBRARY_PATH
monstruosoft@PC:~/code/allegro$ echo $LD_LIBRARY_PATH
/home/monstruosoft/libs/usr/local/lib/
monstruosoft@PC:~/code/allegro$ ./ejemplo-allegro-4

Nota que en el ejemplo anterior la variable de entorno LD_LIBRARY_PATH está inicialmente vacía por lo que podemos asignar un valor directamente. Si en tu distro esa variable ya tiene algún valor asignado, debes agregar la ruta sin eliminar el contenido actual de la variable de entorno, eso se logra de la siguiente manera (nota que en Linux las rutas se separan con el símbolo : a diferencia de ; como en Windows):

monstruosoft@PC:~/code/allegro$ echo $LD_LIBRARY_PATH
/home/monstruosoft/libs/usr/local/lib/
monstruosoft@PC:~/code/allegro$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/libs/usr/local/bin/
monstruosoft@PC:~/code/allegro$ echo $LD_LIBRARY_PATH
/home/monstruosoft/libs/usr/local/lib/:/home/monstruosoft/libs/usr/local/bin/

Después de haber seguido las instrucciones anteriores, esta vez el programa de ejemplo se debe ejecutar sin problemas. ¡Felicidades! Has logrado compilar y ejecutar tu primer programa de Allegro en Linux.

allegro

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s