2011-01-07 13 views
20

g ++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"referencia indefinida" cuando se enlaza contra una biblioteca estática

Tengo el siguiente biblioteca estática llamado sdpAPI.a. Tengo problemas para intentar vincularlo con mi aplicación de prueba. Me pregunto si estoy haciendo algo mal. La biblioteca estática se ha creado con g ++;

Mi directorio es el siguiente:

/projects/unit_test/main.c 
/projects/unit_test/sdp/inc/sdpAPH.h 
/projects/unit_test/sdp/lib/sdpAPI.a 

Mi código fuente es la siguiente:

#include <stdio.h> 

#include "sdpAPI.h" 

int main(void) 
{ 
    printf("----- TEST SDP ------\n"); 

    try { 
     sdpSessionDescription sdp; 
     sdp.clear(); 
    } 
    catch(...) { 
     printf("----- TEST FAILED --------\n"); 
     return 0; 
    } 

    printf("------ TEST SUCCESSFULL ------\n"); 

    return 0; 
} 

Y mi Makefile es la siguiente:

OBJECT_FILES = main.o 
CC = g++ 
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0 
TARGET = sdp_demo 

INC_PATH = -I sdp/inc 
LIB_PATH = -L sdp/lib/sdpAPI.a 

$(TARGET): $(OBJECT_FILES) 
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) 

main.o: main.c 
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c 

clean: 
rm -f $(TARGET) $(OBJECT_FILES) *~ 

Estos son los errores del enlazador estoy obteniendo:

undefined reference to `sdpSessionDescription::sdpSessionDescription()' 
undefined reference to `sdpSessionDescription::clear()' 
undefined reference to `sdpSessionDescription::~sdpSessionDescription()' 
undefined reference to `sdpSessionDescription::~sdpSessionDescription()' 

Muchas gracias por todas las sugerencias,

Respuesta

37

-L especifica la ruta de la biblioteca , no una biblioteca específica. Probablemente desee -L sdp/lib -l sdpAPI para especificar la ruta y el nombre de la biblioteca.

Aunque intentará prefijar y fijar el nombre de su biblioteca con lib y .a o .sl (o similar).

Por lo que también puede que tenga que cambiar el nombre de la biblioteca para libsdpAPI.a según la página de manual de gcc:

-l xyz
          El enlazador busca en una lista estándar de directorios de la biblioteca, que es en realidad un archivo llamado libxyz.a.


También hay que tener en cuenta que el orden de las cosas en las materias de línea de comandos. Al hacer $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (librerías antes que los objetos), no hay símbolos sin resolver en el punto donde se incluye la biblioteca, por lo que no se traerá nada de esa biblioteca.

Luego, cuando finalmente traiga los objetos (con sus símbolos no resueltos), quedan sin resolver porque no hay bibliotecas enumeradas después de eso.

por lo general debe hacer después de bibliotecas de objetos:

$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET) 

para asegurar que todos los símbolos no resueltos son conocidos antes de comprobar las bibliotecas.

Esto no detectará todos los problemas (como las bibliotecas co-dependientes que se pueden arreglar usando otros medios) pero asegurará que se conozcan todos los símbolos no resueltos en el objeto antes de mirar las bibliotecas.

De la misma sección de la página del manual citado:

se hace una diferencia en qué parte del comando que escribe esta opción; el vinculador busca y procesa bibliotecas y archivos de objetos en el orden en que se especifican. Por lo tanto, foo.o -lz bar.o busca en la biblioteca z después del archivo foo.o pero antes de bar.o. Si bar.o se refiere a las funciones en z, esas funciones pueden no cargarse.

+0

He copiado la biblioteca estática a esto: libsdpAPI.y editó la siguiente línea LIB_PATH = -L sdp/lib -l sdpAPI. Sin embargo, sigo obteniendo la misma referencia indefinida. Gracias. – ant2009

+0

@ ant2009, eso es porque el orden es importante. Ver la respuesta actualizada. – paxdiablo

+0

Gracias, eso funcionó. Lo tenía en el orden incorrecto. Estoy tan acostumbrado a compartir que no sabía sobre el pedido con estática. Gracias. – ant2009

10
  • -L se utiliza para especificar una biblioteca ruta:

    - LdirAñadir directorio dir a la lista de directorios que se debe buscar - l.

  • -l es lo que hay que especificar qué biblioteca para enlazar contra:

    -lbibliotecabuscar en la biblioteca llamada biblioteca cuando la vinculación.

es probable que tenga -L sdp/lib/ -l sdpAPI

+0

Además, y no sé por qué de si está documentado en alguna parte, g ++/gcc puede enfadarse cuando el orden de las libs es incorrecto. –

1

Exactamente cómo funcionaron las diferentes opciones especialmente -l y -static me confundieron durante mucho tiempo. Finalmente hice un gcc para obtener más detalles que no pude encontrar en línea. Espero que esto ayude a alguien más también

-llibrary biblioteca -l buscar en la biblioteca llamada biblioteca cuando la vinculación. (La segunda alternativa con la biblioteca como un argumento separado es sólo para compatibilidad POSIX y no se recomienda.)

 It makes a difference where in the command you write this option; 
     the linker searches and processes libraries and object files in the 
     order they are specified. Thus, foo.o -lz bar.o searches library z 
     after file foo.o but before bar.o. If bar.o refers to functions in 
     z, those functions may not be loaded. 

     The linker searches a standard list of directories for the library, 
     which is actually a file named liblibrary.a. The linker then uses 
     this file as if it had been specified precisely by name. 

     The directories searched include several standard system 
     directories plus any that you specify with -L. 

     Normally the files found this way are library files---archive files 
     whose members are object files. The linker handles an archive file 
     by scanning through it for members which define symbols that have 
     so far been referenced but not defined. But if the file that is 
     found is an ordinary object file, it is linked in the usual 
     fashion. The only difference between using an -l option and 
     specifying a file name is that -l surrounds library with lib and .a 
     and searches several directories. 

-static En los sistemas que soportan la vinculación dinámica, esto impide que la vinculación con las bibliotecas compartidas. En otros sistemas, esta opción no tiene ningún efecto.

 This option will not work on Mac OS X unless all libraries 
     (including libgcc.a) have also been compiled with -static. Since 
     neither a static version of libSystem.dylib nor crt0.o are 
     provided, this option is not useful to most people. 

-Ldir Añadir directorio dir a la lista de directorios que se debe buscar -l.

-1

Tres banderas que necesita saber:

-Ldir -lLIB -static

Desde que desea vincular con la biblioteca estática, necesita la tercera bandera. De lo contrario, terminará vinculando con una biblioteca dinámica.

Cuestiones relacionadas