miércoles, agosto 26, 2015

Autotools, tutorial de uso (VII): Crear librerías dinámicas con libtool

Intruducción

En enlazado o linkado dinámico es un mecanismo implementado en la mayoría de sistemas operativos actuales que permite compartir código entre diferentes procesos ejecutándose en la máquina. se implementa normalmente con ayuda de la gestión de memoria virtual del sistema. Las librerías dinámicas son los ficheros donde se almacenan este código compartido las cuales se construyen de diferente manera en función del sistema operativo.

Para intentar aislar las particularidades en la construcción de librerías dinámicas existe la herramienta libtool que se integrar de manera sencilla con las autotools para generar las librerías dinámicas de manera portable.

libtool incluye un script,libtoolize, el que va a crear una serie de scripts y macros m4 en nuestro proyecto que nos permite generar librerías dinámicas olvidándonos de las particularidades del sistema donde lo hacemos. Estos scripts son usados por autoconf y por el script de configure para generar toda la lógica necesaria. Por defecto, los ficheros y scripts que añade son enlaces simbólicos a los mismos instalados en el sistema, pero pueden copiar a nuestros proyectos si se desea.

Voy a usar de ejemplo el código del tutorial 5 que he subido a SourceForge. El código es muy simple, crear una librería de enlace dinámico libtest con tres funciones que se llaman desde el binario principal. Los ficheros configure.ac, Makefile.am y autogen.sh con las macros necesarias para que compilen la librería y funcione el enlazado dinámico serían los siguientes:

configure.ac

El fichero de configure.ac sólo necesita añadir la macro LT_INIT. Esta macro cuando se expande para formar el fichero configure, añade toda la lógica necesaria para las opciones que controlan la creación de librerías dinámicas. Esta macro puede admitir parámetros para establecer cual debe ser el comportamiento por defecto de las opciones.

 1 dnl Esto es un comentario
 2 dnl Esta macro fuerza a una versión mínima de autoconf
 3 AC_PREREQ([2.59])
 4 AC_INIT([tut5],[1.0],[cterron@users.sourceforge.net],[tut5.tar.gz],[https://sourceforge.net/p/autotutorial/])
 5 LT_INIT
 6 dnl Necesitamos el compilador de C
 7 AC_CONFIG_HEADERS([config.h])
 8 AC_PROG_CC
 9 dnl Init automake 
10 AM_INIT_AUTOMAKE
11 AC_CONFIG_MACRO_DIR([m4])
12 dnl Debe de ir al final de la plantilla. Genera el fichero config.status
13 AC_CONFIG_FILES([Makefile])
14 AC_OUTPUT

Makefile.am

En este fichero se va a definir las plantillas que nos van a generar la libreria (llamada libtest) y el binario (tut5) que usará dicha librería. Para definir la librería usamos la variable lib_LTLIBRARIES. Esta es una lista de las librerías que vamos a crear. En nuestro caso libtest.la. Ahora se definen las fuentes que se van a usar para compilar generar la librería. Puesto que el nombre es libtest.la, la variable que hay que definir es libtest_la_SOURCES, en el caso del ejemplo libtest.c. La librería tiene un fichero de cabecera que queremos instalar para que se pueda usar por parte de otros programas,para lo que usamos la variable include_HEADER con la lista de ficheros de cabecera que se desea instalar. También añadimos una variable ACLOCAL_AMFLAGS para que incluya los ficheros de macros del directorio m4. Para que el binario se compile contra la librería dinámica, lo único que hay que definir la variable tut5_LDADD indicando que utilice libtest.la. El contenido del fichero es el siguiente:

 1 # Configurado par 
 2 # Construir la librería libtest.la con las funcioens f1,f2,f3
 3 # Instala la cabecera libtest.h en el sitio correspondiente
 4 # Compila un programa test_lib que llama a dichas funciones
 5 ACLOCAL_AMFLAGS = -I m4
 6 lib_LTLIBRARIES = libtest.la
 7 libtest_la_SOURCES = libtest.c
 8 include_HEADERS = libtest.h
 9 
10 bin_PROGRAMS = tut5
11 tut5_SOURCES = testlib.c
12 tut5_LDADD = libtest.la
autogen.sh

La única modificación necesaria en este fichero es añadir la llamada a libtoolize. Cuando se ejecute, configurará el sistema con los parámetros que deseemos pasarle

1 #!/bin/sh
2 aclocal -I m4  && \
3 rm -rf autom4te.cache/ && \
4 autoheader && \
5 automake --foreign --add-missing && \
6 libtoolize  && \
7 autoconf && \
8 ./configure $@
9 

Compilar y probar el resultado

Compilar el programa es sencillo. Se puede probar sin necesidad de instalar los binarios y las librerías con ayuda de las variables de entorno.

./autogen --prefix=/usr/local
make
env LD_LIBRARY_PATH=.libs/ .libs/tut5 # En Mac env DYLD_LIBRARY_PATH=.libs .libs/tut5

Enlaces

Actualizado 28/08/2015

No hay comentarios: