c++ - g++ referencia indefinida aunque el símbolo está presente en el archivo*.so
undefined-reference name-mangling (2)
Encontré varias preguntas similares (por ejemplo, this , that o this ), pero ninguna de ellas me ayudó a resolver mi problema. Tengo un archivo * .so (desde el núcleo de gnss-sdr ) que, como lo indica:
$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph
contiene el símbolo Gps_Ephemeris::Gps_Ephemeris()
, que se supone que es un constructor.
He escrito un código mínimo:
#include <iostream>
#include <core/system_parameters/gps_ephemeris.h>
int main(int argc,const char* argv[])
{
Gps_Ephemeris ge;
return 0;
}
con el que compilo
g++ main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`
El enlazador se queja:
/tmp/ccHCvldG.o: In function `main'':
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()''
collect2: error: ld returned 1 exit status
También probé cmake , pero la línea que generó fue similar a eso (acaba de agregar -rdynamic
antes de vincular), y aún generó exactamente el mismo error de enlazador.
Tenga en cuenta que tanto la biblioteca como mi código mínimo se compilan con el mismo compilador (g ++ - 5), con los mismos indicadores y el mismo estándar de c ++ 0x.
Dirigiéndose a la respuesta de Maxim Egorushkin, la línea:
nm --demangle --defined-only --extern-only libgnss_system_parameters.so |grep Gps_Eph
no produce nada Sin embargo, el símbolo se define en la biblioteca estática ( es decir, la biblioteca * .a):
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
Sabiendo que ambos son generados por cmake , de la siguiente manera:
add_library(lib_name SHARED ${sources_etc}) #for the *.so
add_library(lib_name_2 ${sources_etc}) #for the *.a
no debería haber diferencia en los símbolos contenidos / definidos en esas bibliotecas, ¿verdad? No noté nada en la documentación de add_library
en add_library
. ¿Me estoy perdiendo algo obvio?
He encontrado en el pasado que este tipo de error es causado por la falta de una adecuada extern "C" { ... }
en un archivo de inclusión.
La forma pedantemente correcta de verificar que a .so
exporte un símbolo es nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>
nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>
.
Sin --defined-only
su comando también muestra símbolos indefinidos .
Sin --extern-only
también muestra símbolos con enlaces internos que no están disponibles para vincular.
Parece que necesita vincular otra biblioteca porque Gps_Ephemeris::Gps_Ephermeris()
no se resuelve al vincular libgnss_system_parameters_dyn.so
. Una buena manera de comenzar es la documentación y ejemplos de la biblioteca.