Automake fácil
Con frecuencia me preguntan qué entorno de desarrollo utilizo para programar en Linux, y se sorprenden cuando respondo que uso Vim para editar el código y Automake para compilarlo. En este post explicaré lo mínimo necesario para hacer funcionar a Automake.
La principal dificultad que encuentras cuando lees el manual de Automake es que depende de Autoconf. Y este último es un sistema complicado y algo extraño. Es importante comprender antes de nada la diferencia entre ambos.
Autoconf es un mecanismo que descubre la configuración y peculiaridades de tu sistema y modifica el entorno de compilacion apropiadamente. Detecta, entre otras muchas cosas, qué compiladores hay, qué librerías y qué versiones tienes instaladas, ficheros de cabeceras (.h) disponibles, llamadas al sistema, funciones no estándar disponibles, etc. Es por lo tanto, esencialmente, una herramienta de portabilidad.
Automake se encarga de determinar que comandos hay que ejecutar para construir el programa. Controla las dependencias entre ficheros fuente, entre librerías y ejecutables, etc. Puede considerarse una extensión de make.
En muchos casos no necesitamos la portabilidad que proporciona Autoconf, ya sea porque el proyecto que vamos a desarrollar se va a restringir a un entorno más o menos conocido, o bien porque es un proyecto privado, que solo queremos compilar nosotros. Si es así, nos interesa dejar al Autoconf en lo mínimo necesario para que funcione Automake.
Como Autoconf y Automake van a crear varios ficheros en el directorio raíz del proyecto, es una buena idea guardar los fuentes en un subdirectorio, por ejemplo src.
Autoconf requiere un fichero llamado configure.ac (antes configure.in) en el directorio raíz del proyecto. Es en realidad un script de shell con muchas extensiones, tantas que casi no lo parece (en realidad son macros M4).
Automake necesita un fichero de nombre [CC]Makefile.am[CC] en cada uno de los directorios del proyecto.
Un configure.ac minimalista es algo así:
1 2 3 4 5 6 7 8 9 10 | AC_INIT([cosa], [1.0]) AC_CONFIG_AUX_DIR([auxdir]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_PROG_CXX AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT |
Si estás pensando que todos esos corchetes ([]) parecen que se usasen como comillas, ¡estás en lo cierto! En muchos casos no son obligatorios, pero como no es fácil saber cuándo, es mejor ponerlos siempre y jugar sobre seguro.
En la línea 1 se indica el nombre del proyecto y la versión. En la línea 2 se especifica un directorio donde guardar unos cuantos archivos auxiliares. No es obligatorio, pero es preferible a tenerlos tirados en la raíz del proyecto.
En la línea 3 se dice que vamos a usar Automake, por supuesto (nótese el prefijo AM en lugar de AC), y se indican qué opciones queremos pasarle. La más importante es foreign, que dice que no somos de GNU, y por lo tanto no tenemos que cumplir sus estrictos criterios de estilo.
Las líneas 5 y 6 listas las herramientas que vamos a utilizar en este proyecto, en este caso los compiladores de C y de C++.
La línea 8 le indica que cree un fichero config.h con una macro con cada cosa que haya descubierto de tu sistema. Así se pueden compilar condicionalmente trozos de código según convenga. No es obligatoria, pero conviene ponerla, aunque luego no uses este fichero para nada.
La línea 9 enumera todos los archivos de Automake, pero sin la terminación .am.
La línea 10… simplemente tiene que estar ahí.
Cada Makefile.am en un directorio que tenga subdirectorios con más ficheros Makefile.am, debe tener una línea listándolos. Así que el del directorio raíz del proyecto puede ser simplemente:
1 | SUBDIRS=src |
El contenido de src/Makefile.am podría ser así:
1 2 3 4 5 6 7 8 9 10 11 12 13 | AM_CFLAGS="-Wall" AM_CXXFLAGS="-Wall" AM_CPPFLAGS="-I/usr/include/SDL" LDADD="-lSDL" #AM_LDFLAGS="" bin_PROGRAMS=cosa cosa_SOURCES=cosa.cpp cosa.h \ utils.cpp utils.h \ textos.cpp textos.h \ constantes.h |
Las líneas 1 y 2 definen las opciones para el compilador de C y para el de C++, respectivamente.
La línea 3 define las opciones para el precompilador de C y C++. En general aquí se incluyen solamente las opciones -I y -D.
La línea 5 indica las librerías que se usarán en el linker. Deben ser solo opciones -l y -L.
Las demás opciones del linker se incluyen en la variable de la línea 6, que he comentado porque no tiene ninguna.
En la línea 8 se dice qué programas se van a compilar. En este caso uno solo, pero podrían añadirse los que fueran necesarios, separados por comas.
Finalmente, en las líneas 10 y siguientes se listan los fuentes del programa. El nombre de la variable es el nombre del programa más _SOURCES, y el valor asignado es la lista de ficheros fuentes. Si la línea es muy larga se puede continuar en la siguiente usando una barra invertida (\). Se deben incluir también los ficheros de cabecera (.h) si queremos que Automake calcule las dependencias automáticamente.
Ahora solo tenemos que movernos al directorio raíz del proyecto y ejecutar:
~/cosa$ autoreconf --install
¡Y eso es todo!
Antes de compilar el proyecto es necesario ejectuar el script configure que habrá aparecido en el mismo directorio. Este es el que chequea el sistema y construye los verdaderos Makefiles. Suele ser buena idea, salvo en proyectos muy pequeños, compilar en un directorio aparte, para que no se mezclen los fuentes con los ficheros objeto y para poder mantener varias compilaciones simultáneamente (debug, release, profile, etc.). Aquí además se pueden añadir opciones adicionales:
~/cosa$ mkdir debug ~/cosa$ cd debug ~/cosa/debug$ ../configure CCFLAGS='-O0 -g' CXXFLAGS='-O0 -g' ~/cosa/debug$ make
Si configure termina correctamente, basta con ejecutar make para construir el proyecto y make clean para borrar los ficheros generados.
A partir de aquí, si modificamos los ficheros configure.ac o Makefile.am, al ejecutar make los Makefiles se actualizarán automáticamente a sí mismos. Si esto dejara de funcionar (a veces pasa) basta con moverte al raíz del proyecto y ejecutar ahí:
~/cosa$ autoreconfY todo debería volver a funcionar normalmente.
Naturalmente, Automake tiene muchísimas más posibilidades, pero con esto debería ser suficiente para empezar.
Artículos relacionados:
- Colorear la salida del compilador con sed ¿Alguna vez te has perdido intentando distinguir los errores entre...
- Scripts de inicio de Bash profile, bash_profile, bashrc… Hay tantos ficheros de inicialización que lee...
RSS
Deja un comentario