Distribuir programas con Autotools
Cuando nos enfrentamos a un proyecto nuevo siempre debemos crear un sistema automático para compilar nuestra "obra". Este paso puede ser más o menos complejo dependiendo del tamaño de nuestro proyecto y de otros factores tales como su portabilidad, etc. Unas herramientas muy apañadas que facilitan en gran medida esto (cuando las conoces, si no se pueden volver un tanto "engorrosas") son las autotools. Y de eso va esta receta... a petición del pueblo, el tonto'las'autotools hará un pequeño programilla que será compilado con estas herramientas.
Qué son las autotools
Bueno, como dijimos en la introducción, las autotools son un conjunto de herramientas de GNU que facilitan la compilación de proyectos software en plataformas tipo Unix, MacOS-X, Cygwin e incluso Windows. Las herramientas concretamente son:- Autoconf: genera el "famoso" script configure a partir de unas macros en lenguaje M4.
- Automake: a partir de unas sencillas reglas descritas en Makefile.am, genera un complejo Makefile.in con el que configure creará los Makefiles finales.
- Autoheader: crea el archivo config.h.in con el que configure generará un archivo config.h que contendrá una serie de macros dependientes de la arquitectura que podremos usar en nuestro proyecto.
- Libtool: si nuestro proyecto no es programa, sino una librería, estas herramientas nos facilitarán en gran medida su compilación e instalación.
Cómo trabajar con las autotools
Una vez tenemos las herramientas (los paquetes Debian/Ubuntu tienen el mismo nombre...) tenemos que usarlas, para ello primero explicaré cómo se debe hacer (o cómo lo hago yo) y luego haremos un pequeño ejemplo. Las Autotools trabajan con una importante cantidad de scripts, macros y archivos de definiciones... sin embargo (y aquí viene lo bueno) nosotros sólo debemos crear DOS archivos. Además una herramienta nos generará automágicamente una versión inicial de uno de esos dos ficheros. Los ficheros en concreto son:- configure.ac: contiene información relativa al proyecto en general.
- Makefile.am: contiene instrucciones simples sobre los componentes que forman el proyecto.
- Ejecutar autoscan para obtener el configure.ac incial.
- Modificar configure.ac para adaptarlo a nuestras necesidades.
- Crear Makefile.am según las necesidades de nuestro proyecto. Y ya está! a partir de ahora todos los pasos son automáticos:
- Ejecutar aclocal para generar las macros M4 utilizadas en los scripts para nuestro proyecto.
- Lanzar autoheader para generar el archivo config.h.in basado en nuestro configure.ac.
- Ejecutar automake para generar los ficheros Makefile.in utilizados por configure para crear los Makefiles.
- Finalmente lanzamos autoconf para generar el script configure.
- AM_INIT_AUTOMAKE: indica que, como salida, autotool debe generar un Makefile. Esto será necesario en nuestro caso.
- AC_CONFIG_AUX_DIR(directorio): por defecto, todos los ficheros generados por las Autotools estarán en la raíz del proyecto, con esta macro especificamos otro directorio.
- AC_CONFIG_MACRO_DIR(directorio): los archivos con las descripciones de las macros M4 los alojará en este directorio.
- AC_CONFIG_FILES([Makefile src/Makefile]): indica los archivos de salida que creará Autotools.
- Directorio donde el programa mir se instalará. El nombre de la variable es importante, si definimos la variable pruebaprgdir, automake buscará la variable pruebaprg_PROGRAMS.
- De qué programas consta el proyecto. La siguiente variable establece una lista de ejecutables que hay que crear en el proyecto. Por cada programa que especifiquemos, automake buscará una variable con nombre programa_SOURCES.
- Qué archivos fuentes son necesarios para compilar un programa. La última variable contendrá una lista de archivos fuente necesarios para crear nuestro ejecutable.
- Opcionalmente podemos especificar librerías externas que necesite nuestro programa (en nuestro configure.ac deberíamos haber comprobado que existan) :
mir_LIBADD=-lbluetooth
- También podremos indicar opciones de linkado y compilación adicionales para cada programa mediante las variables mir_LDFLAGS y mir_CFLAGS.
- Un tutorial en el Developing Programmers. Esta receta es básicamente una traducción.
- Manual Autoconf
- M4 Macro Processor (por curiosidad y para ver macros más complejas).
- Corregir y completar esta receta (help!) :P
- Generar librerías con libtool
#!/bin/sh aclocal autoheader automake -ac autoconfSin embargo hay por ahí muchos autogen.sh mejores que hacen cosas como limpiar todos los archivos generados, etc. Algunos paquetes fuente de Debian tienen estos scripts que podéis probar.
Nuestro ejemplo
Vamos a suponer que nuestro proyecto consta de un programa fuente, llamado mir_kernel.c. Lo primero es hacer un poco de limpieza, si tenemos el directorio ~/mir con dicho fuente, crearemos el subdirectorio src y dejaremos ahí el fichero (el nombre es un simple convenio):# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([src/mir_kernel.c]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_OUTPUTTodo eso que vemos ahí son macros M4, en los enlaces del final podéis ver de qué va eso (aunque para usar autotools no es necesario). La primera macro obliga a que la versión de autotools necesaria para ejecutar estos scripts sea la 2.64, podemos bajarla un poco si no queremos ser demasiado restrictivos, puesto que no todo el mundo tiene porqué usar Debian Unstable :P. La siguiente macro establece el nombre del proyecto, su versión y una dirección de e-mail a la que envíar bugs. Rellenemos los campos con la información apropiada. Las dos macros siguientes establecen el directorio de nuestro código y cómo se debe llamar el archivo de macros C por si queremos usarlo en nuestro proyecto (por ejemplo, crea una macro con la versión que indiquemos arriba para poder usarlo en nuestro código). El resto de macros sirve para dar instrucciones sobre dependencias exernas, por ejemplo: AC_PROG_CC indica que nuestro proyecto requiere un compilador de C. Existen muchas macros más, por ejemplo: AC_PROG_INSTALL comprueba que exista un programa que nos permita instalar nuestro proyecto en el sistema. Además, existen otras macros útiles, por ejemplo:
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) AC_INIT([MIR Kernel], [2.0], [billgates@vigilando.org]) AC_CONFIG_AUX_DIR([config]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/mir_kernel.c]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL # Checks for libraries. AC_CHECK_LIB([bluetooth]) # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUTY este archivo será nuestro configure.ac:
AC_CHECK_LIB([bluetooth])Ahí podemos indicar una serie de librerías con que debe contar nuestro sistema para poder compilar y ejecutar nuestro proyecto. Ahora escribimos nuestro Makefile.am, uno por cada subdirectorio de nuestro proyecto. Primero el del directorio padre:
SUBDIRS=srcSólo tenemos que indicar dónde hay subdirectorios con otros Makefile.am. Ahora el del del directorio hijo:
mirprgdir=/usr/local/bin/ mirprg_PROGRAMS=mir mir_SOURCES=mir_kernel.cEste archivo indica lo siguiente:
Conclusiones
Quizás os haya podido parecer un poco enrevesado, pero haced vosotros el ejemplo, veréis que todo esto se resume en modificar el fichero configure.ac y crear los archivos Makefile.am que son muy simples. Acto seguido ejecutamos las Autotools (buscad un autogen.sh que están más chulos) y listo. Muy sencillo. :PEnlaces
Trabajo futuro
[ show comments ]
blog comments powered by Disqus