Estoy compilando un programa en C ++ usando g++
y ld
. Tengo una .so
biblioteca que quiero usar durante la vinculación. Sin embargo, existe una biblioteca con el mismo nombre /usr/local/lib
y ld
está eligiendo esa biblioteca sobre la que estoy especificando directamente. ¿Cómo puedo arreglar esto?
Para los ejemplos siguientes, mi archivo de biblioteca es /my/dir/libfoo.so.0
. Cosas que he probado que no funcionan:
- mi comando g ++ es
g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
- agregando
/my/dir
al principio o al final de mi$PATH
variable en` - agregar
/my/dir/libfoo.so.0
como argumento a g ++
libfoo.*
archivos existen y donde -.so
w / o la.0
,.a
, etc, etc?Respuestas:
Agregue la ruta a donde está su nueva biblioteca
LD_LIBRARY_PATH
(tiene un nombre ligeramente diferente en Mac ...)Su solución debería funcionar con el uso de las
-L/my/dir -lfoo
opciones, en tiempo de ejecución use LD_LIBRARY_PATH para apuntar a la ubicación de su biblioteca.Cuidado con el uso de LD_LIBRARY_PATH - en resumen (desde el enlace):
O
Use la opción rpath a través de gcc para enlazar: se usará la ruta de búsqueda de la biblioteca en tiempo de ejecución en lugar de buscar en el directorio estándar (opción gcc):
Esto es bueno para una solución temporal. El vinculador primero busca bibliotecas en LD_LIBRARY_PATH antes de buscar en los directorios estándar.
Si no desea actualizar LD_LIBRARY_PATH de forma permanente, puede hacerlo sobre la marcha en la línea de comandos:
Puede comprobar lo que el vinculador de bibliotecas sabe sobre el uso (ejemplo):
/sbin/ldconfig -p | grep libpthread libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0
Y puede verificar qué biblioteca está usando su aplicación:
ldd foo linux-gate.so.1 => (0xffffe000) libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000) libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000) librt.so.1 => /lib/librt.so.1 (0xb7e65000) libm.so.6 => /lib/libm.so.6 (0xb7d5b000) libc.so.6 => /lib/libc.so.6 (0xb7c2e000) /lib/ld-linux.so.2 (0xb7fc7000) libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000) libz.so.1 => /lib/libz.so.1 (0xb7c18000)
fuente
LD_LIBRARY_PATH
se busca en tiempo de ejecución, en el tiempo de compilación que desea establecerLIBRARY_PATH
. Ver gcc.gnu.org/onlinedocs/gcc/Environment-Variables.htmlgcc myFile.c -o myFile.o -l myLibraryBaseName -Wl,-rpath,locationOfMyLibrary -L locationOfMyLibrary
Ésta es una vieja pregunta, pero nadie parece haberla mencionado.
Tuviste suerte de que la cosa se vincule.
Necesitabas cambiar
a esto:
Su vinculador realiza un seguimiento de los símbolos que necesita resolver. Si lee la biblioteca primero, no tiene ningún símbolo necesario, por lo que ignora los símbolos que contiene. Especifique las bibliotecas después de las cosas que deben vincularse a ellas para que su vinculador tenga símbolos para encontrar en ellas.
Además,
-lfoo
hace que busque específicamente un archivo con el nombrelibfoo.a
olibfoo.so
según sea necesario. Nolibfoo.so.0
. Por lo tanto,ln
el nombre o el cambio de nombre de la biblioteca según corresponda.Para citar la página de manual de gcc:
-l library ... 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.
Agregar el archivo directamente a
g++
la línea de comando debería haber funcionado, a menos que, por supuesto, lo pusiera antesbar.cpp
, haciendo que el enlazador lo ignore por no tener los símbolos necesarios, porque todavía no se necesitaban símbolos.fuente
Especificar la ruta absoluta a la biblioteca debería funcionar bien:
g++ /my/dir/libfoo.so.0 ...
¿Se acordó de eliminar
-lfoo
una vez que agregó la ruta absoluta?fuente
@
símbolos versionados? Ejemplo mínimo: github.com/cirosantilli/cpp-cheat/blob/…Como alternativa, puede usar las variables de entorno
LIBRARY_PATH
yCPLUS_INCLUDE_PATH
, que indican respectivamente dónde buscar bibliotecas y dónde buscar encabezados (CPATH
también funcionará), sin especificar las opciones -L y -I.Editar:
CPATH
incluye encabezado con-I
yCPLUS_INCLUDE_PATH
con-isystem
.fuente
export LIBRARY_PATH = /path/to/lib
en la misma sesión de consola donde está compilandoSi uno está acostumbrado a trabajar con DLL en Windows y le gustaría omitir los números de versión .so en linux / QT, agregar
CONFIG += plugin
eliminará los números de versión. Para usar la ruta absoluta a .so, darle al enlazador funciona bien, como mencionó el Sr. Klatchko.fuente