g++ неопределенная ссылка, хотя символ присутствует в файле *.so
Я нашел несколько похожих вопросов (например, это, то или это), но ни один из них не помог мне решить мою проблему. У меня есть файл *.so (из ядра gnss-sdr), который, как указано:
$nm libgnss_system_parameters_dyn.so | c++filt |grep Gps_Eph
содержит символ Gps_Ephemeris::Gps_Ephemeris()
, который должен быть конструктором.
Я написал минимальный код:
#include <iostream>
#include <core/system_parameters/gps_ephemeris.h>
int main(int argc,const char* argv[])
{
Gps_Ephemeris ge;
return 0;
}
который я собираю с:
g++ main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`
Затем компоновщик жалуется:
/tmp/ccHCvldG.o: In function `main':
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()'
collect2: error: ld returned 1 exit status
Я также попробовал cmake, но сгенерированная строка была похожа на эту (просто добавила -rdynamic
перед связыванием), и он по-прежнему генерировал точно такую же ошибку компоновщика.
Обратите внимание, что и библиотека, и мой минимальный код компилируются с помощью одного и того же компилятора (g++-5), с точно такими же флагами и тем же стандартом C++0x.
Обращаясь к ответу Максима Егорушкина, строчка:
nm --demangle --defined-only --extern-only libgnss_system_parameters.so |grep Gps_Eph
ничего не выводит. Однако символ определяется в статической библиотеке (то есть библиотеке *.a):
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
Зная, что оба сгенерированы cmake, следующим образом:
add_library(lib_name SHARED ${sources_etc}) #for the *.so
add_library(lib_name_2 ${sources_etc}) #for the *.a
не должно быть никакой разницы в символах, содержащихся / определенных в этих библиотеках, верно? Я ничего не заметил в документации cmake по add_library
, Я что-то упускаю из виду?
2 ответа
Педантически правильный способ проверить, что .so
экспортирует символ nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>
,
Без --defined-only
Ваша команда также показывает неопределенные символы.
Без --extern-only
он также показывает символы с внутренней связью, которые недоступны для связывания.
Похоже, вам нужно связать другую библиотеку, потому что Gps_Ephemeris::Gps_Ephermeris()
не разрешается путем ссылки libgnss_system_parameters_dyn.so
, Хороший способ начать - это документация и примеры этой библиотеки.
Я обнаружил в прошлом, что этот тип ошибки вызван отсутствием надлежащего extern "C" { ... }
брекетинг во включаемом файле.