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
optiongcc -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
Glibc: Elf File Os Abi Invalid
One Command to Create a Directory and File Inside It Linux Command
Identifying Received Signal Name in Bash
How to Remove All Non-Numeric Characters from a String in Bash
Device Tree Compiler Not Recognizes C Syntax for Include Files
How to Launch a New Process That Is Not a Child of the Original Process
How to Delete the First Column ( Which Is in Fact Row Names) from a Data File in Linux
List Supported Ssl/Tls Versions for a Specific Openssl Build
Use Perf Inside a Docker Container Without --Privileged
Convert Bash 'Ls' Output to JSON Array
Linux Serial Port Listener and Interpreter
Rename Files in Multiple Directories to the Name of the Directory
What Do the Counters in /Proc/[Pid]/Io Mean
Loading Multiple Shared Libraries with Different Versions
Why Does C99 Complain About Storage Sizes
Centos Error - Sudo: Effective Uid Is Not 0, Is Sudo Installed Setuid Root