Aprende GNU/Linux, Programación 1

Creando librerías estáticas y compartidas en Linux con gcc

Logo gcc

En el artículo “Las librerías compartidas en Linux, que son y como gestionarlas” hablé sobre los dos tipos de librerías que podemos usar, sobre sus características principales y entré en más detalle con las librerías compartidas, pero faltó hablar sobre como crearlas y usarlas. En este artículo voy a intentar explicar de forma resumida y metódica el proceso de creación de tanto las librerías estáticas como de las compartidas, ademas de hacer una prueba de rendimiento para intentar ver la diferencia entre ambas en cuestión del tiempo de ejecución.

Para realizar este proceso vamos a utilizar el compilador de C gcc, este compilador viene incluido por defecto en todas las distribuciones de Linux, de forma que no tendremos que instalar ningún programa ni compilador adicional. Si quieres más información sobre este compilador de GNU puedes acceder a su pagina oficial ( en Ingles ) . Sin más que decir, paso a especificar los pasos que hay que seguir para crear y ligar las librerías a nuestros programas.

La librería

El código que vamos a utilizar para las pruebas es una sencilla función que nos calcula el numero pi en base al numero de iteraciones que indiquemos como parámetro, el código es el siguiente:

libreriaPi.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void funcion (double *t, double *k, double *l)
{
              (*t) += (*l)/(*k); 
              (*k) += 2.0; 
              (*l) *= -1.0; 

}

Además de crear la librería tenemos que crear su fichero cabecera:

libreriaPi.h

void funcion (double *t, double *k, double *l);

Creando la librería estática

Una librería estática  se crea con el archiver (ar) a partir de un archivo tipo objeto que creamos desde nuestro código en C. Los pasos a seguir son los siguientes :

Creamos un objeto a partir de nuestro código en C:

gcc -c libreriaPi.c -o libreriaPi.o

Una vez tenemos nuestro fichero objeto llamamos al archiver(ar) para que nos genere la librería:

ar rcs libpi.a libreriaPi.o

La librería tiene que empezar obligatoriamente con las tres letras lib y tiene que tener la extensión .a

Nombre de la librería

 Creando la librería compartida

En el caso de las librerías compartidas también es necesario crear un fichero objeto, hay que tener en cuenta que al crear el fichero con el mismo nombre que en el caso de la librería estática, estamos sobrescribiendo y eliminando el fichero anterior, algo conveniente teniendo en cuenta que la librería estática ya esta creada.

Creamos el objeto:

gcc -c -fPIC libreriaPi.c -o libreriaPi.o

Una vez creado el objeto procedemos a crear la librería dinámica :

gcc -shared -Wl,-soname,libpi.so.1 -o libpi.so.1.0.1  libreriaPi.o

El nombre de la librería tiene que empezar por lib

Nombre de la librería

El programa principal

Evidentemente para utilizar la librería necesitamos un programa, en este caso vamos a utilizar un programa que simplemente recoge el parámetro que le pasamos ( numero de iteraciones ) e imprime por pantalla el valor de pi calculado por la función de la librería, ademas nos imprime el valor que da math.h de pi y la diferencia entre ambos. El código es el siguiente:

programaPi.c

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#include "libreriaPi.h"

  
int main(int argc, char *argv[])
{
   double t, k = 3.0, l = -1.0;
   int i, s;

   if(argc < 2){
     fprintf(stderr, "%s <no. de iteracines>\n", argv[0]);
     exit(1);
   }
       
   t = 1.0; 
   for(i = 0, s = atoi(argv[1]); i < s; i++)
   {
      funcion(&t, &k, &l);
   }
   t *= 4; 

   printf("Valor de Pi calculado: %1.16f,  Valor de Pi en math.h: %.16f\n", t, M_PI); 
   printf("Diferencia: %.16f\n", fabs(M_PI - t)); 

   return 0; 
}

Ligando la librería estática

Para ligar la librería estática a nuestro programa utilizamos la siguiente instrucción:

gcc -static programaPi.c -L. -lpi -o piEstatico

El parámetro -lpi indica el nombre de la librería sin las tres letras lib y sin su extensión. -l + nombre (sin lib y extensión )

Ligando la librería compartida

Para ligar la librería dinámica usamos:

gcc main.c -o dynamically_linked -L. -lpi

Como en el caso anterior el parámetro -lpi indica el nombre de la librería sin las tres letras lib y sin su extensión. -l + nombre (sin lib y extensión )

Pruebas de tiempo de ejecución

Una vez tenemos el mismo programa compilado con una librería estática y otra compartida vamos a probar cual de los dos tiene un tiempo de ejecución mayor. Para ello vamos a utilizar la instrucción time que nos va indicar esto mismo, primero vamos a realizar la prueba con 1000000 iteraciones, el resultado es el siguiente:

Rendimiento Librerias

Como podemos observar la diferencia es nula, teniendo en cuenta que existen muchos factores que pueden afectar al tiempo de ejecución. Aun así realizamos una segunda prueba con 950000000 iteraciones, los resultados es el siguiente :

Rendimiento librerias

Podemos concluir que en el caso de esta librería y programa no afecta utilizar una librería estática o compartida en cuestión de tiempo de ejecución. Aun así existen otras ventajas que ya mencionamos en el anterior artículo.

Espero que os sea de ayuda esta guiá de creación de librerías estáticas y dinámicas.

Aquí tenéis la principal fuente del artículo

Sobre el autor / 

AsierPH

Entusiasta de las tecnologías libres y fundador de OvToaster.com | “Las obras de conocimiento deben ser libres, no hay excusas para que no sea así“

Articulos relacionados

1 comentario

  1. Jules 21 septiembre, 2016 at 4:10 pm -  Responder

    Hola Asier,

    muchas gracias por el articulo. Emulando tu ejemplo, todo va bien. Pero tratando de hacer algo mas complejo en donde introduzco varios includes, no encuentra la libreria dinamica para linkar en el ultimo paso.

    /usr/bin/ld: cannot find -lpi
    collect2: error: ld returned 1 exit status

    Cuando le decimos -L. estamos indicando que busque en el directorio actual, y ahi esta la libreria, pero no la encuentra. He modificado LD_LIBRARY_PATH tambien. Se te ocurre algo?. Hay que linkar esta libraria con algun otro directorio?.

    Gracias y un saludo.

Deja tu comentario

Tu correo no sera publicado. Los campos requeridos están marcados *