c++ - librerías - diferencia entre biblioteca y libreria en programacion
"Referencia indefinida" cuando se vincula contra una biblioteca estática (4)
Cómo funcionaron exactamente las diferentes opciones, especialmente -st y -static, me confundió durante mucho tiempo. Finalmente hice un gcc de hombre para obtener más detalles que no pude encontrar en línea. Espero que esto ayude a alguien más también
-library -l library Busca en la biblioteca denominada library al enlazar. (La segunda alternativa con la biblioteca como argumento separado es solo para el cumplimiento con 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.
-estático En los sistemas que admiten el enlace dinámico, esto evita el enlace con las bibliotecas compartidas. En otros sistemas, esta opción no tiene 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 Agregar directorio de directorio a la lista de directorios para buscar -l.
g ++ (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5
Tengo la siguiente biblioteca estática llamada sdpAPI.a. Estoy teniendo problemas al intentar vincularlo con mi aplicación de prueba. Solo me pregunto si estoy haciendo algo mal. La biblioteca estática ha sido construida 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 este:
#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 este:
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 que estoy recibiendo:
undefined reference to `sdpSessionDescription::sdpSessionDescription()''
undefined reference to `sdpSessionDescription::clear()''
undefined reference to `sdpSessionDescription::~sdpSessionDescription()''
undefined reference to `sdpSessionDescription::~sdpSessionDescription()''
Muchas gracias por las sugerencias,
Tres banderas que debes saber:
-Dirigir -LLIB-estático
Ya que quiere enlazar con la biblioteca estática, necesita la tercera bandera. De lo contrario, terminará enlazando con una biblioteca dinámica.
-L
especifica la ruta de la biblioteca, no una biblioteca específica. Probablemente desee que -L sdp/lib -l sdpAPI
especifique tanto la ruta como el nombre de la biblioteca.
Aunque intentará prefijar y colocar el nombre de su biblioteca con lib
y ya sea .a
o .sl
(o similar).
Por lo tanto, es posible que también deba cambiar el nombre de su biblioteca a libsdpAPI.a
según la libsdpAPI.a
de libsdpAPI.a
gcc:
-l xyz
El enlazador busca una lista estándar de directorios para la biblioteca, que en realidad es un archivo llamadolibxyz.a
.
También tenga en cuenta que el orden de las cosas en la línea de comando es importante. Al hacer $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
(bibliotecas antes de los objetos), no hay símbolos sin resolver en el punto donde se enumera la biblioteca, así que nada serán traídos de esa biblioteca.
Luego, cuando finalmente traes los objetos (con sus símbolos no resueltos), permanecen sin resolver porque no hay bibliotecas enumeradas después de eso.
Normalmente deberías hacer librerías después de objetos:
$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET)
para asegurar que todos los símbolos no resueltos sean conocidos antes de revisar las bibliotecas.
Esto no detectará todos los problemas (como las bibliotecas co-dependientes que pueden solucionarse por otros medios) pero garantizará que se conozcan todos los símbolos no resueltos en los archivos de objetos antes de consultar las bibliotecas.
De la misma sección de la página del manual citada anteriormente:
Hace una diferencia donde en el comando escribes esta opción; el vinculador busca y procesa las bibliotecas y los archivos de objetos en el orden en que se especifican. Por lo tanto,
foo.o -lz bar.o
busca en la bibliotecaz
después del archivofoo.o
pero antes debar.o
Sibar.o
refiere a las funciones enz
, esas funciones no se pueden cargar.
-L
se utiliza para especificar una ruta de biblioteca:-
Ldir
Agregar directorio de directorio a la lista de directorios para buscar -l.-l
es lo que necesitas para especificar con qué biblioteca enlazar:-l
biblioteca Busca en la biblioteca denominada biblioteca al vincular.
Probablemente necesites -L sdp/lib/ -l sdpAPI