Uri Raz
Uri Raz

Reputation: 434

Symbol from shared library not found, though defined

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

Answers (1)

Employed Russian
Employed Russian

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 has t (lowercase) next to it, rather than T

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

Related Questions