42

I found a number of similar questions (e.g. this, that or this), but none of them helped me solve my problem. I have a *.so file (from the core of gnss-sdr) that, as indicated by:

$nm libgnss_system_parameters_dyn.so  | c++filt  |grep Gps_Eph

contains the symbol Gps_Ephemeris::Gps_Ephemeris(), which is supposed to be a constructor.

I've written some minimal code:

#include <iostream>
#include <core/system_parameters/gps_ephemeris.h>

int main(int argc,const char* argv[])
{
    Gps_Ephemeris ge;
    return 0; 
}

which I compile with:

g++  main.cpp -std=c++0x -I some_include_path -L some_lib_path -l gnss_system_parameters_dyn`

The linker then complains:

/tmp/ccHCvldG.o: In function `main':
main.cpp:(.text+0x33): undefined reference to `Gps_Ephemeris::Gps_Ephemeris()'
collect2: error: ld returned 1 exit status

I also tried cmake, but the line it generated was similar to that (it just added -rdynamic before linking), and it still generated the exact same linker error.

Note that both the library and my minimal code are being compiled with the same compiler (g++-5), with the exact same flags and the same c++0x standard.


Addressing the answer by Maxim Egorushkin, the line:

nm --demangle --defined-only --extern-only libgnss_system_parameters.so  |grep Gps_Eph

doesn't output anything. However, the symbol is defined in the static library (i.e. the *.a library):

00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()
00000000000006b0 T Gps_Ephemeris::Gps_Ephemeris()

Knowing that both are generated by cmake, in the following way:

add_library(lib_name SHARED ${sources_etc}) #for the *.so
add_library(lib_name_2 ${sources_etc}) #for the *.a

there should be no difference in symbols contained/defined in those libraries, right? I didn't notice anything in cmake's documentation on add_library. Am I missing something obvious?

Community
  • 1
  • 1
Ash
  • 4,611
  • 6
  • 27
  • 41
  • 3
    You said the output _contains the symbol `Gps_Ephemeris::Gps_Ephermeris()`_, but don't show the actual output. This is relevant, and would be useful. Also, you clearly haven't copied-and-pasted that symbol into the question, because you misspelt it. I'm mistrustful of written summaries of this kind, because if you were a reliable judge of what to exclude from your summary, you probably wouldn't be asking the question. – Useless Apr 06 '17 at 14:23
  • Thanks for noticing that, I fixed it. I mostly do high-level computer vision, so yes, I feel unqualified to judge what has to be excluded. I will post the output as soon as I can. – Ash Apr 06 '17 at 15:58
  • Without looking at the source code it is hard to tell why the .so and .a built from the same sources export different symbols. Conditional compilation may be involved. – Maxim Egorushkin Apr 10 '17 at 09:11
  • What are the mangled symbol names in both main.o and in libgnss_system_parameters_dyn.so? G++ has changed name mangling on occasion when the ABI has changed. Perhaps libgnss_system_parameters_dyn.so was not compiled the same as how you're compiling main.cpp. Try `g++ -std=c++0x -c main.cpp; nm main.o` and compare the mangled names to what's in the lib. – Waxrat Apr 11 '17 at 03:06

2 Answers2

37

The pedantically correct way to check that a .so exports a symbol is nm --demangle --dynamic --defined-only --extern-only <lib.so> | grep <symbol>.

Without --defined-only your command also shows undefined symbols.

Without --extern-only it also shows symbols with internal linkage which are unavailable for linking.

It looks like you need to link another library because Gps_Ephemeris::Gps_Ephermeris() is not resolved by linking libgnss_system_parameters_dyn.so. A good way to start is that library's documentation and examples.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • Thanks a lot! You were right. However, the symbols are present in the (equivalent) static library. I updated the question with some information at the end. Could you please take a look? – Ash Apr 06 '17 at 17:59
6

I have found in the past that this type of error is caused by the lack of proper extern "C" { ... } bracketing in an include file.

Nicole
  • 699
  • 1
  • 5
  • 15