Подтвердить что ты не робот

G++ undefined ссылка, хотя символ присутствует в файле *.so

Я нашел ряд похожих вопросов (например, this, that или this), но никто из них не помог мне решить мою проблему. У меня есть файл *.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), с теми же самыми флагами и с тем же стандартом С++ 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. Мне что-то не хватает?

4b9b3361

Ответ 1

Педантически правильный способ проверить, что .so экспортирует символ nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>.

Без --defined-only ваша команда также отображает символы undefined.

Без --extern-only он также отображает символы с внутренней связью, которые недоступны для компоновки.

Похоже, вам нужно связать другую библиотеку, потому что Gps_Ephemeris::Gps_Ephermeris() не разрешается связыванием libgnss_system_parameters_dyn.so. Хороший способ начать - это документация и примеры библиотек.

Ответ 2

В прошлом я обнаружил, что этот тип ошибки вызван отсутствием надлежащего брекетинга extern "C" { ... } во включенном файле.