Linux Shared Library That Uses a Shared Library Undefined Symbol

Linux shared library that uses a shared library undefined symbol

You can easily check where libb.so is expected to be with ldd command:

 $ ldd liba.so
linux-gate.so.1 => (0xb77b0000)
libb.so.1 => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
/lib/ld-linux.so.2 (0xb77b1000)

If it's not found, libb.so's path should be added to /etc/ld.so.conf or shell variable LD_LIBRARY_PATH.

Another way is setting rpath in the liba.so itself - it's basically hardcoding its path so when the binary is started the dynamic linker would know where to search for the shared libraries.

If rpath is not set it will first search in LD_LIBRARY_PATH, then the paths mentioned in /etc/ld.so.conf (or /etc/ld.so.conf.d/). After adding to ls.so.conf don't forget to execute /sbin/ldconfig

Dynamic linker searches the dependent shared libraries by their soname (if it's set) - if soname is not set (with -Wl,-soname,libb.so.1 for example), it will be searched by library's name.

Example: libb.so.1.0 is your actual library, having soname - libb.so.1. You would normally have the following files structure:

libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0

where libb.so and libb.so.1 are symlinks.

You usually link to libb.so, when building some application or other library, depending on libb.so.

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb

When the application is started (or dlopen is executed - your case) - the dynamic linker will search for file with name libb.so.1 - the soname of dependent library, if the soname is set, not libb.so.

That's why you need that symlink libb.so.1, pointing to the actual library.

If you use ld.so.conf and ldconfig, it will create the symlink with soname's name, pointing to the library file, if this symlink is missing.

You can see ld-linux man page for more useful info.


If the library is found but some of the symbols are missing, try building libb.so with -Wl,--no-undefined option

gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

It should give you an error if you missed to define some symbol.

Why do I get an undefined symbol when linking shared library that links static (gSoap) library?

Thanks to Mike Kinghan for pointing out what I should have seen.

The issue here was an old version of the shared library in /usr/lib that remained after I changed LD_LIBRARY_PATH to point to a project-specific lib directory. Deleting the library in /usr/lib resolved the immediate problem and caused the correct library instance to be accessed.

Shared Library undefined symbol

You can check /lib/libsdkpolicer.so.1 with ldd command, maybe the libpolicercomlib.so file which you copy just is a link file, and check it on your machine without yum GCC. If everything is correct, you can copy the /lib64/ld-linux-x86-64.so.2 loader from your complie machine to your new machine(backup it before) and try it.

undefined symbols remain, but shared libraries compile and seem to function properly

You have undefined symbol with ldd because the so files were created without the -lm option. However it will not be a problem as long as the final executable is linked with -lm option. It is what is done for tests like test_nvector_serial which is linked with -lm -lrt.

You can see all this by running the make in a verbose mode with make VERBOSE=1.
If you try to generate the executable without -lm you will have collect2: error: ld returned 1 exit status and the linker complaining about exp, pow and sqrt.
if you add -lm when creating the so files ( I did it ). you will see :

ldd -r ./src/nvec_ser/libsundials_nvecserial.so
linux-vdso.so.1 (0x00007ffe1a769000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fe4a5c19000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe4a5828000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe4a61bd000)

And in this case you can link your tests ( only to do some test for yourself if you want) without -lm.

To compile your so files with -lm. You can do it by running the command line with -lm option after entering the right folder (just for test purpose). The other way is by modifying the CMakeLists.txt which generate the so files. For libsundials_nvecserial.so for example, you modify sundials-2.7.0/src/nvec_ser/CMakeLists.txt by adding target_link_libraries(sundials_nvecserial_shared -lm) after the ADD_LIBRARY(sundials_nvecserial_shared SHARED ${nvecserial_SOURCES} ${shared_SOURCES}).

For the LD_LIBRARY_PATH, it does not have to contain something necessarily if you are looking in standard places. The linker use also /etc/ld.so.cache and search also in default path unless you use -z nodeflib. you can find more details in https://man7.org/linux/man-pages/man8/ld.so.8.html

For the nm -D. It is normal , try to compile a hello world gcc -o exec hello.c you will see that printf is undefined. Take a look at dynamic linking, and also to the -rdynamic option used to build the so files.

Fortran shared lib .so shows undefined symbol error

You must use -assume 2underscore in both compilations, using/not using the option cannot be mixed.
Also extra_fluid2.f90 should be compiled with option -fpic. It's generally a bad idea to use different sets of flags for files that are supposed to go into the same executable or shared object.



Related Topics



Leave a reply



Submit