gcc linker produces unexpected so (clang is fine) - c

A program is linked properly with clang, but not with gcc:
% CC=clang make
clang -I/usr/include/lua5.1 -llua5.1 -shared -fPIC -o mk_lua.so mk_lua.c
% ldd mk_lua.so
linux-vdso.so.1 => (0x00007fff4effe000)
liblua5.1.so.0 => /usr/lib/x86_64-linux-gnu/liblua5.1.so.0 (0x00007fa94b316000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa94af51000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa94ac4a000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa94aa46000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa94b752000)
GCC gives different results (of course, leads to a broken shared library).
% CC=gcc make
gcc -I/usr/include/lua5.1 -llua5.1 -shared -fPIC -o mk_lua.so mk_lua.c
% ldd mk_lua.so
linux-vdso.so.1 => (0x00007fffcf3fe000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fe2e3e06000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe2e43d9000)
gcc version 4.9.1 (Ubuntu 4.9.1-16ubuntu6)
Ubuntu clang version 3.5.0-4ubuntu2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Linker options are identical. What is going on here?
Full source is here.

Related

Including a Boost C++ header causes dlopen() to return error: _ZTVN10__cxxabiv117__class_type_infoE

The C HelloWorld.so (shared object) is created by linking in a C++ myatomic library. That C++ library uses a Boost Header:
myatomic.cpp
...
#include <boost/system/error_code.hpp>
...
Loading HelloWorld.so with dlopen() returns error: _ZTVN10__cxxabiv117__class_type_infoE
If that Boost header is commented-out, then dlopen() succeeds?
HelloWorld.yaml
...
Common:
Sources:
- Folder: src
Files:
- HelloWorld.h
- HelloWorld.c
ConanLibs:
- CONAN_PKG::myatomic
Linux:
CompilerOptions:
- -fPIC
LinkerOptions:
- -lstdc++
Does Boost C++ under linux need to built with specific options? Maybe gcc vs g++ issues?
Added -lstdc++ to HelloWorld linker options but to no avail. :(
A co-worker discovered this fix
If we're interacting with C++ materials (in this case Boost C++), we
need to be using g++. The gcc tool, even if supplied with a bunch of
-lstdc++ args - does not fill the shoes of the g++ compiler, in terms of things like 'linker/loader hints'
The reason for the error _ZTVN10__cxxabiv117__class_type_infoE is the HelloWorld.so (C program) was not loading a runtime dependent (C++ shared object) libstdc++.so.6. For example,
$ ldd HelloWorldBAD.so
linux-vdso.so.1 (0x00007ffc8a5c5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f78cf21f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f78cf431000)
$ ldd HelloWorldGOOD.so
linux-vdso.so.1 (0x00007ffd53bba000)
libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f2540003000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f253fe11000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f253fcc2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2540205000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f253fca7000)
Edit
It was also found that the ordering of the -lstdc++ option is important. (see also this link)
This command correctly includes the C++ runtime dependencies by placing the -lstdc++ option at the END of the build command
/usr/bin/cc -fPIC -O2 -g -DNDEBUG -shared -Wl,-soname,HelloWorld.so ...Lots of Boost Libraries... -lstdc++
whereas putting the option BEFORE the Boost libraries does not
/usr/bin/cc -fPIC -O2 -g -DNDEBUG -lstdc++ -shared -Wl,-soname,HelloWorld.so ...Lots of Boost Libraries...

Issue with C and Golang integration

I have a C shared library named libtest.so which in turn use another shared library lihelp.so.
The code for libtest.so use dlopen() to load the libhelp.so
I have integrated libtest.so with my GO script gotest.go
When I run gotest.go after building and installing, I am seeing libtest.so is getting loaded successfully and function in libtest is executed successfully.
But the dlopen() call in libtest.so to load libhelp.so is failining with error "undefined symbol: dlopen"
But if I write a C application which use libtest.so all execution are fine withour any error.
Here is the code snippet of my Go file
/*
#cgo CFLAGS: -I./include
#cgo LDFLAGS: -L. -ltest -ldl
*/
Here is the Makefile entry for building libtest.so
CC = gcc # C compiler
CFLAGS = -c -fPIC -I./include # C flags
LDFLAGS = -shared -L/lib -ldl # linking flags
Can any one suggest what can be the problem?
Output of ldd of my go binary
ldd app
linux-gate.so.1 => (0xb77c3000)
libtest.so => ./libtest.so (0xb77bc000)
libgo.so.5 => /usr/lib/i386-linux-gnu/libgo.so.5 (0xb6ed0000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb6eb2000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb6d03000)
/lib/ld-linux.so.2 (0xb77c4000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb6ce7000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb6ca1000)

Issue with dynamic libraries

I've compiled source file on host-machine:
g++ -I./source/utils -m32 ./source/services/library_version_info.cpp -o version_info $DAALROOT/lib/ia32_lin/libdaal_core.so $DAALROOT/lib/ia32_lin/libdaal_thread.so -ltbb -liomp5 -lpthread -ldl
# echo $DAALROOT
# /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/
When I'm trying to invoke this on target-machine I get such error:
./version_info: error while loading shared libraries: /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so: cannot open shared object file: No such file or directory
# echo $DAALROOT
# /media/sdcard/daalroot/daal
$LD_LIBRARY_PATH on target-machine contains path to libdaal_core.so, but program does not see that. How can I fix this error?
upd. host g++: 5.4.0, target: 4.9.1
upd2.
ldd version_info
linux-gate.so.1 (0xb77db000)
/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so => not found
/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_thread.so => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x4332e000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x43221000)
libc.so.6 => /lib/libc.so.6 (0x42e7d000)
libm.so.6 => /lib/libm.so.6 (0x43003000)
/lib/ld-linux.so.2 (0x42e50000)
env LD_DEBUG=all ./version_info
408:
408: file=/opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so [0]; needed by ./version_info [0]
./version_info: error while loading shared libraries: /opt/intel/compilers_and_libraries_2016.3.210/linux/daal/lib/ia32_lin/libdaal_core.so: cannot open shared object file: No such file or directory
echo $LD_LIBRARY_PATH
/media/sdcard/daalroot/daal/lib/ia32_lin:/media/sdcard/daalroot/daal/../tbb/lib/ia32_lin/gcc4.4
Solution:
g++ -I./source/utils -m32 ./source/services/library_version_info.cpp -o version_info -l daal_core -l daal_thread -ltbb -liomp5 -lpthread -ldl

Linux linking a shared object

I am linking an so, that depends on libmxml.so. However I have no rights install libmxml.so.
So thats what I am doing
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -L ../../../../system/addonlibs/ -lmxml -lpthread
ldd shows me
ldd ServiceProvider.so
libmxml.so.1 => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x40026000)
libc.so.6 => /lib/libc.so.6 (0x40046000)
the second try was
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o ../../../../system/addonlibs/libmxml.so -lpthread
and still ldd shows me
ldd ServiceProvider.so
libmxml.so.1 => not found
libpthread.so.0 => /lib/libpthread.so.0 (0x40026000)
libc.so.6 => /lib/libc.so.6 (0x40046000)
Consequently, ldd does not find the library, since I only have "libmxml.so", but no "libmxml.so.1". How do I get rid of this ".1" suffix? Why is it comming?
When you link with a dynamic library, you should not do :
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o ../../../../system/addonlibs/libmxml.so -lpthread
Instead, make sure that /yourpath/system/addonlibs (you should use the full path instead of a relative one) is in you LIBRARY_PATH. Then change you link command.
export LIBRARY_PATH=/yourpath/system/addonlibs:$LIBRARY_PATH
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -lmxml -lpthread
You can also write that:
gcc -shared -m32 -o ServiceProvider.so ServiceProvider.o -L/yourpath/system/addonlibs -lmxml -lpthread
However, to run your program, you will need to have your library path in LD_LIBRARY_PATH.
If you have issues with .soand .so.1 stuff, then rename your .so to .so.1 and make a symlink from .so.1 to .so.
Edit:
If you do objdump -p libmxml.so | grep SONAME you will probably get libmxml.so.1.
It is where you get the libmxml.so.1 identifier.

How correct link program with libperl.so

How correct linking with libperl.so
I use Fedora Core 16 and try to compile program with embedding perl follows way:
gcc -W -Wall -g -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -I. -I/usr/include -I/usr/lib/include -I/usr/lib/perl5/CORE -c program.c
gcc -L/lib -L/usr/lib/perl5/CORE -lperl -o program.run program.o
After trying to run program I getting following message:
error while loading shared libraries: libperl.so: cannot open shared object file: No such file or directory
if execute following command 'ldd program.run' then it output to console
ldd ./program.run
linux-gate.so.1 => (0xb7751000)
libperl.so => not found
libc.so.6 => /lib/libc.so.6 (0x4eea5000)
/lib/ld-linux.so.2 (0x4ee80000)
Yes i can set LD_LIBRARY_PATH environment variable and program will be work, but if i execute same command for '/usr/bin/perl' library will be found without setting specific environment variable e.g
ldd `which perl`
linux-gate.so.1 => (0xb77f4000)
libperl.so => /usr/lib/perl5/CORE/libperl.so (0xb767b000)
libresolv.so.2 => /lib/libresolv.so.2 (0x4f22f000)
libnsl.so.1 => /lib/libnsl.so.1 (0x42eaf000)
libdl.so.2 => /lib/libdl.so.2 (0x4f055000)
libm.so.6 => /lib/libm.so.6 (0x4f085000)
libcrypt.so.1 => /lib/libcrypt.so.1 (0x41ee6000)
libutil.so.1 => /lib/libutil.so.1 (0x42ecc000)
libpthread.so.0 => /lib/libpthread.so.0 (0x4f05c000)
libc.so.6 => /lib/libc.so.6 (0x4eea5000)
/lib/ld-linux.so.2 (0x4ee80000)
libfreebl3.so => /lib/libfreebl3.so (0x42492000)
How correct link program with libperl.so
Adding -Wl,-rpath -Wl,/usr/lib/perl5/CORE (when linking) should help.
You need to set LD_LIBRARY_PATH at runtime for the dynamic linker to find libperl:
LD_LIBRARY_PATH=/usr/lib/perl5/CORE ./program

Resources