🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: es.comp.os.linux.programacion
Article #16572

[tutorial] Autoconf & Automake

#16572
From: batsman batsman
Date: Wed, 05 Apr 2000 00:00
459 lines
18201 bytes
-----BEGIN PGP SIGNED MESSAGE-----



Al fin lo he acabado, me ha costado *mucho* m�s de lo que pensaba, aqu� va.
Espero que sea suficiente, porque ya me he cansado por hoy :-)

             _                         __ 
  __ _ _   _| |_ ___   ___ ___  _ __  / _|
 / _` | | | | __/ _ \ / __/ _ \| '_ \| |_ 
| (_| | |_| | || (_) | (_| (_) | | | |  _|
 \__,_|\__,_|\__\___/ \___\___/|_| |_|_|  
                                             _                        _        
                                  __ _ _   _| |_ ___  _ __ ___   __ _| | _____ 
                                 / _` | | | | __/ _ \| '_ ` _ \ / _` | |/ / _ \
                                | (_| | |_| | || (_) | | | | | | (_| |   <  __/
                                 \__,_|\__,_|\__\___/|_| |_| |_|\__,_|_|\_\___|
                                                                               

Requisitos previos:
 * tener a mano alg�n UN*X y conocimiento b�sico de su entorno
 * autoconf y automake instalados
 * herramientas de desarrollo GNU o equivalentes para el ejemplo 
 (gcc, ld, libc...)
 * conocimiento b�sico de C/C++ para mejor seguimiento de los ejemplos

Objetivos
*********

Autoconf permite la creaci�n de scripts que facilitan la adaptaci�n del
proceso de compilaci�n a las caracter�sticas de un amplio rango de sistemas
UN*X. Otras herramientas se basaban en detectar el sistema operativo y
compilar el c�digo correspondiente, por ejemplo mediante el uso de directivas
del preprocesador de C. �sto obliga al programador a conocer las
peculiaridades de cada uno de los sistemas en los que deber� poder compilarse
su aplicaci�n. Autoconf, en cambio, permite al desarrollador conocer si tal o
cual *caracter�stica* est� presente. Se puede comprobar, por ejemplo, si
cierta funci�n de la librer�a est�ndar est� definida, o si funciona
correctamente. As�, ser� el propio script creado por Autoconf el que determine
qu� c�digo debe compilarse y c�mo.

Cuando se ejecuta el script configure, �ste realiza varias pruebas hasta
determinar las caracter�sticas del sistema. Despu�s crea uno o varios
ficheros a partir de otros ficheros de entrada (de extensi�n .in),
haciendo sustituciones en funci�n del sistema en el que se ejecute. Por
ejemplo, podemos hacer que configure cree un fichero config.h en el que
se definen las funciones presentes en la libc. Imaginemos que queremos
usar una funci�n que s�lo est� implementada en Linux, por lo que si
se compila en otro sistema lo m�s probable es que haya que definirla.
Lo que vamos a hacer es que configure verifique si *esa* funci�n est�
definida, no si est� en Linux. �Por qu�? Pues porque la funci�n en
cuesti�n podr�a estar presente en otros sistemas, aparte de Linux, sin
que lo sepamos. El uso de Autoconf permite al desarrollador olvidarse de
si tal o cual sistema operativo la define.

Funcionamiento
**************
En general, querremos que configure cree dos ficheros al ejecutarse: config.h
y el Makefile. En el primero, configure definir� s�mbolos del preprocesador en
funci�n de los resultados de las pruebas que haya realizado. El segundo es
el que usar� make para compilarlo todo.

�ste es un fragmento de config.h creado por configure:

- -----------------------------------------------------------------------------
/* config.h.  Generated automatically by configure.  */
/* config.h.in.  Generated automatically from configure.in by autoheader.  */

/* Define to empty if the keyword does not work.  */
/* #undef const */

/* Define if you have the ANSI C header files.  */
#define STDC_HEADERS 1

/* Define if you have the memcpy function.  */
#define HAVE_MEMCPY 1

/* Define if you have the strdup function.  */
#define HAVE_STRDUP 1

/* Define if you have the <unistd.h> header file.  */
#define HAVE_UNISTD_H 1

- -----------------------------------------------------------------------------

M�s tarde, en el c�digo, podremos usar cosas como


- -----------------------------------------------------------------------------
#include "config.h"
#ifndef HAVE_STRDUP

#if STDC_HEADERS
#   include <string.h>
#else
#   ifndef HAVE_MEMCPY
/* si no est� definida memcpy es que tenemos bcopy */
/* en realidad lo correcto ser�a implementarla aqu� pero :-) */
#      define memcpy(d, s, n) bcopy ((s), (d), (n))
#      define memmove(d, s, n) bcopy ((s), (d), (n))
#   endif
#endif

char *strdup(char *s)
{
 int t; char *p;
 if (!s) return NULL; 
 t = strlen(s);  p = (char *) malloc (t+1);
 if (!p) return NULL;  memcpy ( p, s, t+1);
 return p;
}

#endif
	 

- -----------------------------------------------------------------------------

�Qu� es lo que hace �sto? Pues bien, si resulta que strdup no est� en la
biblioteca est�ndar, HAVE_STRDUP no estar� definida, por lo que se compilar�
la implementaci�n alternativa que hemos hecho. Pero resulta que strdup
necesita llamar a memcpy... as� que primero tenemos que asegurarnos de que la
tenemos. Si no est�, asumimos que estamos en una m�quina bsd-iana y definimos
memcpy como llamada a bcopy. As�, en alg�n otro punto del programa, ponemos

		char *cad = strdup(otra_cad);

y esto se compilar� y enlazar� correctamente en *cualquier* sistema UN*X,
aunque no tenga strdup (supuestamente los hay que no la tienen...)

Autoconf crea los ficheros Makefile y config.h a partir de unas plantillas que
(nosotros) creamos anteriormente. El config.h en general ser� sencillo, pero el
Makefile tiene que hacer muchas cosas: por ejemplo, ser�a interesante que al
hacer  make dist  se creara un fichero .tar.gz con el c�digo fuente, la
documentaci�n y los ficheros de datos necesarios para compilar el programa.
Crear el fichero Makefile.in a mano puede ser una tarea *muy* pesada.

�Y qu� pasa con Automake?
*************************
Aqu� es donde entra Automake: es el que crear� el fichero Makefile.in,
teniendo en cuenta las dependencias, librer�as, para que despu�s Autoconf lo
cambie en funci�n de las pruebas sobre el sistema, para crear finalmente el
Makefile.


Caso Pr�ctico
*************

La introducci�n de antes era un poco abstracta, pero necesaria para explicar
el porqu� de Autoconf+Automake.

Pasemos a la pr�ctica; vamos a crear un peque�o programa que haga tonter�as
con cadenas, pero nos aseguraremos de que sea portable...

Lo primero es crear el fichero configure.in, en el que definimos las pruebas
que queremos que haga el script configure... Como somos muy vagos, usaremos
autoscan para crearlo. As� que pasemos al c�digo, tenemos algo como 


- ----------------------------- chorrada.c ------------------------------------
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
	char cadena[]="No valgo para nada.\n";
	char *cad;

	cad = strdup ( cadena );
	printf ( cad );
	free (cad);
}
- -----------------------------------------------------------------------------

Ahora ejecutamos autoscan, y se crea el fichero configure.scan, como �ste:

- ------------------------------ configure.scan -------------------------------
dnl Process this file with autoconf to produce a configure script.
AC_INIT(chorrada.c)

dnl Checks for programs.

dnl Checks for libraries.

dnl Checks for header files.
AC_HEADER_STDC

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.
AC_CHECK_FUNCS(strdup)

AC_OUTPUT()
- -----------------------------------------------------------------------------

�Qu� hace cada l�nea? Vayamos paso a paso:
 - las l�neas que comienzan por 'dnl ' son comentarios
 - AC_INIT(chorrada.c) inicializa autoconf. Hay que pasar como par�metro un
	nombre de fichero que contenga c�digo fuente, no importa cu�l. En general
	pondremos el que tenga main().
 - AC_HEADER_STDC verifica si est�n presentes las cabeceras de la librer�a
	est�ndar.
 - AC_CHECK_FUNCS(strdup) verifica si strdup est� presente en la librer�a
	est�ndar.
 - AC_OUTPUT(fichero) hace que el script configure cree fichero a partir de
	fichero.in

Obviamente tendremos que hacer unos pocos cambios en el configure.scan antes
de renombrarlo a configure.in. Hacemos los cambios siguientes:
 - ponemos AM_INIT_AUTOMAKE(chorrada,1.0) despu�s de AC_INIT, para que
	automake se inicialize. "chorrada" es el nombre del programa, "1.0" es la
	versi�n.
 - ponemos AM_CONFIG_HEADER(config.h) para que se cree el fichero config.h que
	contendr� todos los s�mbolos definidos en funci�n del resultado de los
	tests
 - a�adimos AC_PROG_CC y AC_PROG_INSTALL para que configure verifique si est�n
	presentes el compilador y el programa de instalaci�n.
 - cambiamos la l�nea AC_OUTPUT() AC_OUTPUT(Makefile) para que el script
	configure que se va a crear genere el fichero Makefile a partir de
	Makefile.in (ya hemos dicho antes que Makefile.in lo crea automake).

Finalmente llegamos a este configure.in:

- ----------------------------- configure.in ----------------------------------
dnl Process this file with autoconf to produce a configure script.
AC_INIT(chorrada.c)
AM_INIT_AUTOMAKE(chorrada,1.0)
AM_CONFIG_HEADER(config.h)

dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL

dnl Checks for libraries.

dnl Checks for header files.
AC_HEADER_STDC

dnl Checks for typedefs, structures, and compiler characteristics.

dnl Checks for library functions.
AC_CHECK_FUNCS(strdup)

AC_OUTPUT(Makefile)
- -----------------------------------------------------------------------------

Hemos usado las nuevas macros AM_*, por lo que ejecutamos aclocal para que
est�n definidas. Tambi�n se definir�n dos nuevos s�mbolos: PACKAGE y VERSION,
que indicar�n respectivamente "chorrada" y "1.0". Para que no den problemas,
creamos un archivo llamado acconfig.h como sigue:

- ------------------------------ acconfig.h -----------------------------------
#undef VERSION
#undef PACKAGE
- -----------------------------------------------------------------------------


Ahora ejecutamos autoconf para generar el script configure. Ya no queda mucho,
ahora s�lo queda modificar un poco el c�digo fuente para que use los
resultados de los tests, as� como crear los ficheros config.h.in y
Makefile.in. 

El config.h.in tampoco lo vamos a hacer nosotros, para eso est� autoheader... 
Lo ejecutamos, y obtenemos el siguiente fichero:


- --------------------------- config.h.in -------------------------------------
/* config.h.in.  Generated automatically from configure.in by autoheader.  */

/* Define if you have the ANSI C header files.  */
#undef STDC_HEADERS

#undef VERSION
#undef PACKAGE

/* Define if you have the strdup function.  */
#undef HAVE_STRDUP
- -----------------------------------------------------------------------------

Ya hemos dicho que el Makefile.in lo crea automake, pero �c�mo? El Makefile
puede llegar a ser muy complejo: se ocupar� de las interdependencias entre
ficheros, de las librer�as, de crear los archivos de distribuci�n; tambi�n hay
que hacer el make clean, make distclean... Hay que ayudar a automake,
indic�ndole qu� tiene que hacer. Esta ayuda se llama Makefile.am:


- -------------------------- Makefile.am --------------------------------------
bin_PROGRAMS = chorrada
chorrada_SOURCES = chorrada.c
- -----------------------------------------------------------------------------

Estamos indicando que vamos a crear el programa chorrada, y que el c�digo est�
contenido en chorrada.c. Adem�s, para usar automake tendremos que crear los
ficheros NEWS, README, AUTHORS y ChangeLog. Como hoy estamos vagos, lo hacemos
con touch.

Ahora ejecutamos automake --add-missing para que a�ada algunos ficheros y cree
el Makefile.in. S�lo queda modificar chorrada.c para que use los s�mbolos 
del config.h.
 
El fichero queda as�:

- -------------------------- chorrada.c ---------------------------------------
#include "config.h"
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>

#else 

void free (void *ptr);
void *malloc(int);

#define NULL (void *)0

char *strdup(char *s)
{
 int t; char *p; char *o; char *cad;
 
 t = 0;
 if (!s) return NULL;
 for(p=s; *p; p++) t++; 
 cad = o = (char *) malloc (t+1);
 if (!o) return NULL;
 for(p = s; *p; ) *o++ = *p++;
 return cad;
}

#endif

int main(int argc, char *argv[])
{
   char cadena[]="No valgo para nada.\n";
   char *cad;

   cad = strdup ( cadena );
   printf ( "%s, v%s\n", PACKAGE, VERSION);
	printf ( cad );
   free (cad);
}
- -----------------------------------------------------------------------------

�Ya hemos acabado!
Podemos probarlo todo:

Script started on Wed Apr  5 17:19:05 2000
[/mnt/extended/tmp/chorrada-1.0]$ ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking for gcc... gcc
checking whether the C compiler (gcc  ) works... yes
checking whether the C compiler (gcc  ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for a BSD compatible install... /usr/bin/install -c
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for strdup... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
creating config.h
[/mnt/extended/tmp/chorrada-1.0]$ make
gcc -DHAVE_CONFIG_H -I. -I. -I.   -g -O2 -c chorrada.c
gcc -g -O2  -o chorrada  chorrada.o  
[/mnt/extended/tmp/chorrada-1.0]$ make dist
rm -rf chorrada-1.0
mkdir chorrada-1.0
chmod 777 chorrada-1.0
chmod -R a+r chorrada-1.0
GZIP=--best tar chozf chorrada-1.0.tar.gz chorrada-1.0
rm -rf chorrada-1.0 
[/mnt/extended/tmp/chorrada-1.0]$ ./chorrada
chorrada, v1.0
No valgo para nada.
[/mnt/extended/tmp/chorrada-1.0]$ 
Script done on Wed Apr  5 17:19:30 2000

Ahora podemos instalar con make install, limpiarlo todo con make clean o make
distclean, hacer un fichero .tgz con todo lo necesario para recompilar e
instalar con make dist...

Este ejemplo era sumamente sencillo, pero:
 - existen *muchos* m�s test para autoconf (adem�s pueden crearse otros)
 - automake tambi�n puede ocuparse del enlace de librer�as, instalaci�n de
	headers, instalaci�n de p�ginas man, ficheros texinfo, ficheros de datos...
	O dicho de otra manera: TODO.

Como siempre, se impone el RTM para todo esto...

Por �ltimo, querr�a indicar que aunque todos los pasos anteriores parecen muy
liosos, s�lo los tendremos que hacer una vez, y despu�s las cosas como la
creaci�n de .tar.gz para la distribuci�n, instalaci�n... ser�n autom�ticas.
Podremos ir seguros en la vida por conocer y usar auto*, por no hablar de
la satisfacci�n de usar el m�todo "est�ndar" de distribuci�n de programas
libres para entornos UN*X. 

Desde que uso autoconf y automake no me ha pasado nada malo(tm).
Tambi�n podr�a decir que desde que empec� a usar autoconf+automake no me ha
quedado ninguna (asignatura) :-).

Eso s�, parece que de ligar nada...

[/mnt/extended/tmp/chorrada-1.0]$ make love
make: *** No rule to make target `love'.  Stop.
[/mnt/extended/tmp/chorrada-1.0]$ exit

... parece un bug bastante gordo, �no?














Si has le�do hasta aqu� significa que el fracaso de 'make love' te ha marcado
profundamente. Algunos aseguran haber obtenido resultados positivos con una
combinaci�n de emacs + dosis elevadas de LSD. No les creas. Lo �nico cierto es
que se ha asociado emacs con la degeneraci�n de las extremidades superiores, y
con el crecimiento de protuberancias con ventosas por todo el cuerpo. Adem�s
la ingesti�n accidental de emacs puede llevar a un estado semi-comatoso en el
que el individuo s�lo puede comunicarse mediante signos como CTRL-j META-q k
SHIFT-1 ESC 2.

- -- 
              _           _                             
             | |__   __ _| |_ ___ _ __ ___   __ _ _ __  
             | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
             | |_) | (_| | |_\__ \ | | | | | (_| | | | |
             |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|

             Real email: batsman dot geo at yahoo dot com

-----BEGIN PGP SIGNATURE-----
Version: 2.6.3ia
Charset: noconv
Comment: Public key via email: send mail with Subject: [PGPKEY]

iQEVAwUBOOuDVL0Y27yr0iefAQEdBAf/XRjsDKKHyN4sQpBfgvaj9yZmoXm7vNRA
LO9TbgRbXmmvhnSvo8qFo5v/SsmQbxu58WVH2henb3WmrSAvZKP9kdKaRxZaOKKH
bIDnx4eMrTxK6foUQ7bErC5mlHA8FQkOfYsQmm8wwePbxlXhdKTk+0Tc/zAMi0Kv
d9zfZ/46btqQwa0d8y4pst5li5n+1QLkuSp1FJzT1x7zMSRPmsx4a1mtIVMKw0FD
Cr9+Y5w4bvjma1//gQqajqwO1QoHmlb7e/gQz5m9L32R36Su/HPMLEgSJ+WjE+1z
v4JO3A2Trj5jxSMnvdtEW0uHZ8LUYuCGcpn2aJsSm4Wd1VWNTROSsA==
=xCGQ
-----END PGP SIGNATURE-----
Technical Details
Message-ID: <p00gc8.j34.ln@simpsons4ever>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII
X-Google-Thread: f86c8,4383ecd6756f8970,start
X-Google-Attributes: gidf86c8,public
From: batsman@simpsons4ever. (batsman)
Subject: [tutorial] Autoconf & Automake
Date: 2000/04/05
Message-ID: <p00gc8.j34.ln@simpsons4ever>
X-Deja-AN: 607161713
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=iso-8859-1
X-Complaints-To: abuse@news.wanadoo.es
X-Trace: m2newsread.uni2.es 954956379 62.36.24.67 (Wed, 05 Apr 2000 19:39:39 MET DST)
Organization: Wanadoo Usenet News - Visita http://www.wanadoo.es/
Keywords: autoconf automake tutorial tocho gnu compilar desarrollo web
Mime-Version: 1.0
Reply-To: see_signature-mira_firma
NNTP-Posting-Date: Wed, 05 Apr 2000 19:39:39 MET DST
Newsgroups: es.comp.os.linux.programacion