Reputation: 434
I'm working on C++ code called, via pybind11, from a Python (v3.8) application on Ubuntu 20.04.
Running the application I get an error
Traceback (most recent call last):
snip...
ImportError: <full-path>/<lib-name-A>.so: undefined symbol: <mangled symbol name>
ldd on lib-name-A output gives the absolute path to lib B in which the symbol is defined. nm -s --demangle on lib B shows the symbol is defined in the text section. Just to be sure, I compared the mangled name, and the one in lib B is identical to the one given in the error message.
So, given the library exists where ldd shows its expected, and the symbol is defined in it, why do I get the error message?
Upvotes: 0
Views: 2113
Reputation: 213375
nm -s --demangle` on lib B shows the symbol is defined in the text section
The function being defined in lib B is necessary, but not sufficient. The function must also be exported from lib B.
Chances are, it's not. To verify, run:
nm -D /path/to/lib-B.so | grep $mangled_symbol_name_here
If my guess is correct (function is not exported), you will get no output from above command.
Update:
Checking with
nm -D
, and the symbol is missing. Checking again with-s
, the symbol hast
(lowercase) next to it, rather thanT
Ok, so my guess was correct.
I've added
__attribute__((visibility("default")))
in front of the function declaration,
That's the correct solution.
Question is why I need to declare it explicitly as visible.
Most likely because you are building this code with -fvisibility=hidden
, which says "hide everything not explicitly declared as visible".
Building with -fvisibility=hidden
is current best practice, but you do need to mind which symbols are used outside of the shared library you are building.
Upvotes: 1