Error loading shared libraries - shared-libraries

I'm running eclipse on Ubuntu using a g++ compiler and I'm trying to run a sample program that utilizes xerces.
The build produced no errors however, when i attempted to run the program, I would receive this error:
error while loading shared libraries: libxerces-c-3.1.so: cannot open shared object file: No such file or directory
libxerces-c-3.1.so is in the directory /opt/lib which I have included as a library in eclipse. The file is there when I checked the folder. When I perform an echo $LD_LIBRARY_PATH, /opt/lib is also listed.
Any ideas into where the problem lies? Thanks.
An ldd libxerces-c-3.1.so command yields the following output:
linux-vdso.so.1 => (0x00007fffeafff000)
libnsl.so.1 => /lib/libnsl.so.1 (0x00007fa3d2b83000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007fa3d2966000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fa3d265f000)
libm.so.6 => /lib/libm.so.6 (0x00007fa3d23dc000)
libc.so.6 => /lib/libc.so.6 (0x00007fa3d2059000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fa3d1e42000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa3d337d000)

Try running ldconfig as root to see if it solves the problem.

Run ldd libxerces-c-3.1.so and examine the output to see if all dependencies can be found.

There are many ways to do this, most already mentioned here. BUT you want to avoid accidentally copying your library files into/over those of the system. This is easily done since people have little imagination in making original unique names for their libraries.
So there are a couple of things to think about:
Do you need these files to be a permanent part of your system?
Do you only need to install for testing and frequent updates?
Do you only need them for running that particular command once or twice?
Where are your native libraries located?
To find your various library locations on your system (apart from using find), look here:
cat /etc/ld.so.conf
cat /etc/ld.so.conf.d/*
On Linux there are some standard places:
/lib # for base system (don't use this!)
/usr/lib # for package manger installed apps
/usr/local/lib # for user installed apps
There are many others, but you should most likely stay with /usr/local/lib.
Next you need to tell your system where to find these libraries. The cool system dude (who knows what he is doing) way to do this is using ldconfig, however, you may do stuff you regret, if you make a mistake here. The safest way to use that command is by using the flags -v -n to make the command verbose and to specify what library directory you need to add.
sudo ldconfig -v -n /usr/local/lib/your-uber-libs
Done. But if you only wanna test something, then rather use your LD_LIBRARY_PATH directly from command line, like this:
LD_LIBRARY_PATH=/usr/local/lib/your-uber-libs ./your_uber_command
Alternatively, add the following to your .bashrc script.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/your-uber-libs
Now you can run your dynamically linked command.

I copied all the library files from /opt/lib into /usr/lib and the program works now. Thanks for the response.

Try installing the library libxerces-c3.1 as. Use the command mentioned below to install the library.
sudo apt-get install libxerces-c3.1
This worked like a charm for me.

Related

Dependensies of program and install libraries

In my Linux Mint i have a program, an executable file.
With ldd in terminal i can take dependensies of this executable.
ldd file
When move program in another system it dont runs.
ldd file gives something like ...
linux-vdso.so.1 => (0x00007ffc2a36d000)
libwx_gtk2u_stc-3.0.so.0 => /usr/lib/x86_64-linux-gnu/libwx_gtk2u_stc-3.0.so.0 (0x00007f2919d55000)
libwx_gtk2u_adv-3.0.so.0 => /usr/lib/x86_64-linux-gnu/libwx_gtk2u_adv-3.0.so.0 (0x00007f291996f000)
libwx_gtk2u_core-3.0.so.0 => /usr/lib/x86_64-linux-gnu/libwx_gtk2u_core-3.0.so.0 (0x00007f29190f5000)
libwx_baseu-3.0.so.0 => /usr/lib/x86_64-linux-gnu/libwx_baseu-3.0.so.0 (0x00007f2918c63000)
libsqlite3.so.0 => /usr/lib/x86_64-linux-gnu/libsqlite3.so.0 (0x00007f291898e000)
...............
How i can know all that libraries and install only it needs to run to other system.
Using objdump -p /path/to/program | grep NEEDED i can get only libs that i need?
Thanks!
ldd's output says that you have got all the library dependencies installed on your system.
The reason it doesn't run on another system is most likely due to the difference in linking table of those libraries, so your program simply cannot find symbols it is looking for by that addresses.
As a simple solution, I would recommend to recompile program on a new machine.

shared library not found during compilation

So I got several shared libraries that I am trying to permanently install on my Ubuntu system but I am having some difficulty with it.
I want to install the libraries and the headers in a separate folder under /usr/local/lib and /usr/local/include (for example a folder named agony) so it would be clean and removing them would just require that I delete those folders. so it looks something like this:
/usr/local/lib/agony/libbtiGPIO.so
/usr/local/lib/agony/libbtiDSP.so
...
/usr/local/include/agony/GPIO.h
/usr/local/include/agony/DSP.h
...
And I added a file here /etc/ld.so.conf.d/agony.conf which include a line describing the path to the library folder:
$ cat /etc/ld.so.conf.d/agony.conf
/usr/local/lib/agony
and I perform sudo ldconfig to update the library database.
So to double check if the library is found I do ldconfig -p | grep bti* and
I see the following result:
$ ldconfig -p | grep bti
...
libbtiGPIO.so (libc6,x86-64) => /usr/local/lib/agony/libbtiGPIO.so
libbtiDSP.so (libc6,x86-64) => /usr/local/lib/agony/libbtiDSP.so
...
At this point I should be able to use the libraries without specifying the library path. But When I attempt to compile an application without providing the library path (-L) it fails. However, when I supply gcc with the library path ex:
gcc source.c -L /usr/local/lib/agony output -lbtiGPIO -lbtiDSP
it works!!
I don't want to use LD_LIBRARY_PATH environment variable because this library is going to be used everywhere on the system and I don't want other compilers to worry about providing LD_LIBRARY_PATH.
What am I doing wrong here?
At this point I should be able to use the libraries without specifying the library path
Here lies the confusion.
You have built your shared library libbtiGPIO.so (just sticking with that one),
placed it in /usr/local/lib/agony, and updated the ldconfig database accordingly.
The effect of that is when you run a program that has been linked with libbtiGPIO
then the dynamic linker (/lib/x86_64-linux-gnu/ld-2.21.so, or similar) will know where to look
to load that library into the process and you will not need to tell it by setting an LD_LIBRARY_PATH in the environment.
However, you haven't done anything that affects the list of default library
search directories that are hardwired into your build of gcc, that it passes to
the linker (/usr/bin/ld) when you link a program with libbtiGPIO in the first place.
That list of default search directories is what you will find if your do a verbose
build of your program - gcc -v ... - and then pick out the value of LIBRARY_PATH
from the output, e.g.
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/5/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../../lib/:\
/lib/x86_64-linux-gnu/:\
/lib/../lib/:\
/usr/lib/x86_64-linux-gnu/:\
/usr/lib/../lib/:\
/usr/lib/gcc/x86_64-linux-gnu/5/../../../:\
/lib/:\
/usr/lib
/usr/local/lib/agony is not one of those and to make it one of those you
would have to build gcc from source yourself. Hence, in order to link your
program with libbtiGPIO you still need to tell ld where to find it with
-L/usr/local/lib/agony -lbtiGPIO.
man, you misunderstand the procedure of complier and link.
First, libbtiGPIO.so is a shared link library not a static link library. it is important to know those difference .
Then you need to know something else. changing ld.so.conf.d/*.conf and run sudo ldconfig, it affects the procedure of link. in other words, if you don't add agony.conf and sudo ldconfig, you will receive a error when you run ./a.out rather than gcc source.c -L ...., the gcc command can run successfully even thougth you don't ldconfig.
Finally,if you don't pollute the LD_LIBRARY_PATH environment variable, you have to add -L ... options in your gcc command. What'more, if you don't want to input too many words in your shell frequently, you can learn to use Makefile.

Building older GLIBC on newer system

I have a question and I hope some guru here could help me out :) My goal is simple : (GOAL1) build a older glibc on a newer system and (GOAL2) build old software that can run on older glibc. I am on gcc4.9, glibc2.19, amd64 system. I did compile glibc2.14 and gcc4.7.3 on my system.
(convention : /path/to/libc2.14_dir = $LIBC214, /path/to/gcc4.7.3 = $GCC473)
I am trying to compile bash4.2.53 ( and other softwares coreutil, binutil, qt3.3...) using newly built glibc2.14. My configure and make looks like this : ( I am being in object/build directory )
$ cd /path/to/build/bash-4.2.53
$ CC=$GCC473/bin/gcc CXX=$GCC473/bin/g++ CPP=$GCC473/bin/cpp \
/path/to/source/bash-4.2.53/configure \
--prefix=/path/to/installation/bash-4.2.53
$ make all V=1 \
CFLAGS="-Wl,--rpath=$LIBC214/lib -Wl,--dynamic-linker=$LIBC214/lib/ld-linux-x86-64.so.2" \
CPPFLAGS="-Wl,--rpath=$LIBC214/lib -Wl,--dynamic-linker=$LIBC214/lib/ld-linux-x86-64.so.2" \
CXXFLAGS="-Wl,--rpath=$LIBC214/lib -Wl,--dynamic-linker=$LIBC214/lib/ld-linux-x86-64.so.2"
When make is done in bash4.2.53 build (object) directory, I tried 2 scenarios :
SCENARIO1. Use system's libc2.19
$ ldd ./bash
linux-vdso.so.1 (0x00007ffe677c3000)
libtinfo.so.5 => $MY_PREBUILT_NCURSE/lib/libtinfo.so.5 (0x00007f5d108e3000)
libdl.so.2 => $LIBC214/lib/libdl.so.2 (0x00007f5d106df000)
libc.so.6 => $LIBC214/lib/libc.so.6 (0x00007f5d10354000)
$LIBC214/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f5d10b0a000)
This line is weird :$LIBC214/lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007f5d10b0a000)
$ $LIBC214/bin/ldd ./bash
not a dynamic executable
SCENARIO2. Add $LIBC214/bin to my PATH, $LIBC214/lib to my LD_LIBRARY_PATH
$ ldd ./bash
/bin/bash: $LIBC214/lib/libc.so.6: version `GLIBC_2.15' not found (required by /bin/bash)
$ export SHELL=$PWD/bash
$ ldd --version
/bin/bash: $LIBC214/lib/libc.so.6: version `GLIBC_2.15' not found (required by /bin/bash)
$ ldd ./bash
/bin/bash: $LIBC214/lib/libc.so.6: version `GLIBC_2.15' not found (required by /bin/bash)
As far as I can tell, SCENARIO2 is the right way to run commands. My assumption is that I built glibc2.14 wrongly, that it uses /bin/bash which in turn uses glibc2.19. I am not really sure.
My question:
Could you please explain for me the weird line above and the following line that out put not a dynamic executable?
Could you share me your steps to properly build glibc (GOAL1) and build software using that glibc (GOAL2) ?
What could I do next to solve 2 above scenario?
Thank you.
when you link ELFs, the absolute path to the ldso is hardcoded in it. if you want to use a different one, you can use the -Wl,--dynamic-linker=/path/to/ldso flag to override it. this path is absolute though, so if you try to move your local glibc somewhere else, the ELFs you linked will fail to execute (with errors like no such file). there's no way around this as the system, by design, must have an absolute path in it to the interpreter.
the reason you get weird not a dynamic executable output is that ldd works by actually executing the target ELF and extracting (via debug hooks) the libraries that get loaded. so when you attempt to use a diff ldd like that, glibc gets confused. if you want a stable dependency lister, you might consider something like lddtree from the pax-utils project (most distros have this bundled nowadays). or run readelf -d on the file directly and look at all the DT_NEEDED entries.
trying to build & maintain your own toolchain (glibc, gcc, etc...) is a huge hassle. unless you want to dedicate a lot of time to this, you really should use a project like crosstool-ng to manage it for you. that will allow you to build a full toolchain using an older glibc, and then you can use that to build whatever random packages you like.
if you really really want to spend time doing this all by hand, you should refer to the glibc wiki for building your own glibc and then linking apps against that glibc.

How to build a './configure && make && make install' software against a custom library which I also build?

I am building tmux-2.0 from sources on a pretty regular Linux host. First attempt failed as it turned out that the version of libevent installed is older than required, so I proceeded to download and build libevent-2.0.22 from sources (current at the time of writing) first.
Building of libevent succeeded flawlessly, and I thought I could then retry building tmux with the following:
PKG_CONFIG_PATH=$PATH_TO_MY_BUILT_LIBEVENT/lib/pkgconfig ./configure ...
The above invocation succeeded, so did subsequent make and make install.
Running my newly build tmux, however, aborts with a missing shared object, not surprisingly libevent-2.0.so.5:
tmux: error while loading shared libraries: libevent-2.0.so.5: cannot open shared object file: No such file or directory
I thought building against a custom library implies it will also be used at runtime? ldd on my tmux gives me:
linux-vdso.so.1 => (0x00007fff8f5ff000)
libutil.so.1 => /lib64/libutil.so.1 (0x0000003cf8800000)
libncurses.so.5 => /lib64/libncurses.so.5 (0x0000003cf7e00000)
libevent-2.0.so.5 => not found
librt.so.1 => /lib64/librt.so.1 (0x0000003ce8600000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x0000003cea200000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ce7600000)
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x0000003cf7200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000003ce7e00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003ce8200000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ce7200000)
So, libevent-2.0.so.5 is not found.
Do I need to resort to setting, I don't know, LIBS, LDFLAGS or some other variables or switches to configure script above, so that, I don't know, the paths to my newly built libevent are embedded in tmux binary, courtesy of ld?
I do not have root access - university Linux workstation - and frankly I don't need one, I think. I also do not want to muck about with LD_LIBRARY_PATH or the like. Suffice to say, doing LD_LIBRARY_PATH=$PATH_TO_MY_LIBEVENT/lib tmux works fine. But I want it to work "by default", locating and using my libevent.
I guess the solution would apply to pretty much any software using the "GNU build system". What's the right thing to do here?
You built against a library, but the system doesn't know where the library is. Since you don't want to install the library, but rather leave it in the place where you built it, you could solve it with -rpath= option of the linker — it embeds a search path for libraries into the executable file.
Just rebuild your application with it being added to your LDFLAGS, like LDFLAGS="-rpath=/home/mypath/to/libevent" (but note, it is a linker option, and it is possible that in the makefile as a linker used the gcc itself — gcc does not know the option, then you need to write it likeLDFLAGS="-Wl,-rpath=/home/mypath/to/libevent" to force gcc to pass the option down to the actual linker)
By the way, actually you can change rpath even without recompiling the application — there's a tool patchelf for that job.

Please could someone explain in beginners language what LD_LIBRARY_PATH is(unix)?

I've just installed SPIKEfile(fuzzer) on Ubuntu and it says the following:
Now you need to set your LD_LIBRARY_PATH to include the path to libdisasm.so and the path to libdlrpc.so
'printenv' reveals that no such variable exists.
Could someone please kindly explain to me in beginners terms what this actually means and how to solve the problem. I'm a pretty inexperienced Linux user. Thanks in advance.
P.S. I have found most stuff on the net to be unhelpful and I'd rather not copy+paste without knowing what I'm doing.
Linux has the concept of shared libraries, i.e. libraries of code that aren't baked into executables, but instead are dynamically linked when the program is executed. The executable simply contains references to names of libraries that are required.
LD_LIBRARY_PATH is an environment variable listing extra paths that the Linux load-time linker should use when locating these libraries. It's simply a colon-separated list of the form
/path/to/somewhere:/path/to/somewhere_else:/path/to/narnia
Assuming you're using Bash, you can do the following to prepend extra paths to the list (this works even if $LD_LIBRARY_PATH is initially empty or unset):
export LD_LIBRARY_PATH=/path/to/dir/containing/libdisasm.so:$LD_LIBRARY_PATH
(and similarly for libdlrpc.so).
I used LD_LIBRARY_PATH under Solaris since it seems some libraries are missing when kicking scripts sometimes. Having this variable set at the begining of a script is just a safer way to work it out.
Something worth mentioning (probably what you are looking for):
ldd /path/to/narnia
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/dir/containing/lib
(do it this way not to lose previously set dir)
Should the work when using the comand again:
ldd /path/to/narnia
librt.so.1 => /lib/librt.so.1 (0x00002b4eca08e000)
libc.so.6 => /lib/libc.so.6 (0x00002b4eca49f000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00002b4eca7df000)
/lib64/ld-linux-x86-64.so.2 (0x00002b4ec9e72000)
libmylib.so.1 => ~/myprogdir/lib/libmylib.so.1 (0x00002b4eca9fa000)
This will throw you an error if still can't find the lib
make sure to add the settings in your user profile:
# vi .bash_profile

Resources