Creación de bibliotecas compartidas en C
Hola,
Estoy tratando de crear unas bibliotecas compartidas que pueden o no depender una de otras y tengo algunos problemas. Os describo la estructura brevemente:
- La primera biblioteca consiste en una función que suma dos números. sum.h y sum.c, que se convierten tras compilar en libsum.so
- La segunda biblioteca consiste en dos funciones que multiplican dos números, bien directamente o con la función de suma de la biblioteca libsum. prod.h y prod.c, que se convierten tras compilar en libprod.so
Si genero las bibliotecas estáticas libsum.a y libprod.a y escribo un pequeño programa que multiplica dos números utilizando la función directa de libprod.a, todo va bien. Al generar el ejecutable no es necesario enlazar con la función que da el producto apoyándose en la función suma de libsum.a, por lo que no hay ningún error y el programa funciona sin problemas (make static && ./test con el Makefile que os adjunto). En la compilación no hace falta indicar -lsum en la línea de órdenes.
El problema es cuando genero las bibliotecas compartidas libsum.so y libprod.so. Si al compilar sólo paso el argumento -lsum (make con el Makefile que os adjunto) obtengo el error
./libprod.so: undefined reference to `sum1'
collect2: ld returned 1 exit statusParece como si intentase enlazar también con la función suma, aunque no sea utilizada por la función del programa. Para que el programa funcione hay que pasar también el argumento -lsum (make shared && export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH && ./test con el Makefile que os adjunto)
No estoy muy puesto en el tema de creación de bibliotecas dinámicas pero, ¿es esto normal? ¿Hay que pasar como argumentos todas las bibliotecas de las que haya funciones (aunque no se usen) en una biblioteca derivada? He intentado buscar información en internet, pero no doy con ella.
Os pego a continuación los ficheros de trabajo:
sum.h
#ifndef _SUM_H_
#define _SUM_H_
int sum1(int a,int b);
#endifsum.c
#include"sum.h"
int sum1(int a,int b) {
return a+b;
}prod.h
#ifndef _PROD_H_
#define _PROD_H_
int prod1(int a,int b);
int prod2(int a,int b);
#endifprod.c
#include"sum.h"
#include"prod.h"
int prod1(int a,int b)
{
return a*b;
}
int prod2(int a,int b) {
int i=0,res=0;
for(i=0;i<a;i++) {
res = sum1(res,b);
}
return res;
}El programa test.c
#include<stdio.h>
#include"prod.h"
int main() {
printf("3x4=%d\n",prod1(3,4));
return 0;
}Y el Makefile
all:
gcc -fPIC -c prod.c -o prod.o
gcc -shared -o libprod.so prod.o
gcc -fPIC -c sum.c -o sum.o
gcc -shared -o libsum.so sum.o
gcc -I. -L. test.c -o test -lprod
shared:
gcc -fPIC -c prod.c -o prod.o
gcc -shared -o libprod.so prod.o
gcc -fPIC -c sum.c -o sum.o
gcc -shared -o libsum.so sum.o
gcc -I. -L. test.c -o test -lprod -lsum
static:
gcc -c prod.c -o prod.o
gcc -c sum.c -o sum.o
ar rcs libprod.a prod.o sum.o
gcc -I. -L. test.c -o test -lprod
clean:
rm -rf *.so *.a *.o
Gracias
- Inicie sesión o regístrese para enviar comentarios
- 739 lecturas


Ok, yo suelo tratar con gcc muy amenudo.
Me explico, en tu código, por ejemplo prod.c depende de una función externa en sum.c, por lo tanto, al generar la biblioteca dinámica libprod.so debió haber sido ligada con libsum.so o con libsum.a (cualquiera de las 2 sirve). Como al momento de generar libprod.so no se ligó con libsum, entonces, cuando se genera un ejecutable real (no librería), se resuelve esta dependencia, y es por eso que necesitas ligar adicionalmente a libsum.
Espero esto te ayude. Te recomiendo Manual de C, en especial capitulo 1.8
... por lo tanto, al generar la biblioteca dinámica libprod.so debió haber sido ligada con libsum.so o con libsum.a (cualquiera de las 2 sirve). Como al momento de generar libprod.so no se ligó con libsum, entonces, cuando se genera un ejecutable real (no librería), se resuelve esta dependencia, y es por eso que necesitas ligar adicionalmente a libsum.
Muchas gracias
Justo hoy se me acaba de ocurrir otro ejemplo:
La librería gtk (libgtk2.0) también usa simbolos de la glib (libglib) y al momento de generar un binario ligado a la gtk, también debe ser ligado con la glib.