Can't find libGLU.so.1 when trying to run VisIt - shared-libraries

General Problem
I have been trying to run multiple programs (VisIt and Athena) and am having similar issues on both - an inability to find shared libraries, although they do exist in a different spot.
Code Output/Errors
Trying to run Athena gives me
[~athena/working]$ ~/athena/bin/athena -i athinput.blast >log
/nethome/myname/athena/bin/athena: error while loading shared libraries: libhdf5.so.103
or, when running VisIt
[~/local/visit/bin]$ ./visit
Running: gui3.0.2
/localdata/myname/visit/3.0.2/linux-x86_64/bin/gui: error while loading shared libraries: libGLU.so.1: cannot open shared object file: No such file or directory
What I've attempted
If I use find -iname I can find both of these libraries
[~/local/anaconda2]$ find -iname 'libhdf5.so.103'
./lib/libhdf5.so.103
./pkgs/hdf5-1.10.4-nompi_h3c11f04_1106/lib/libhdf5.so.103
./pkgs/hdf5-1.10.4-hb1b8bf9_0/lib/libhdf5.so.103
and
[~/local/anaconda2]$ find -iname 'libGLU.so.1'
./lib/libGLU.so.1
./pkgs/libglu-9.0.0-hf484d3e_1/lib/libGLU.so.1
What do I need to do to point to them. I've tried updating my compiler path using export CPATH and I've tried adding LDLIBS := -L/nethome/sferrel6/local/anaconda2/lib -lhdf5 to the Athena Makefile (which earlier helped me find the hdf5 library)

What do I need to do to point to them
Since these libraries are not installed in the default system location(s), you must tell the dynamic loader where to find them. See man ld.so on your system.
Assuming you are on Linux, here are the ways you could do it:
export LD_LIBRARY_PATH=$HOME/local/anaconda2/lib
Re-link athena binary with -Wl,-rpath=$HOME/local/anaconda2/lib
(Requires root access). Edit /etc/ld.so.conf, add $HOME/local/anaconda2/lib to it, run /sbin/ldconfig to update /etc/ld.so.cache.

Related

Is it possible to permanently add directories to the default ld search path?

I'm attempting to install a library that will be used generally on this node. Currently the library is installed in a location that includes it's version name /opt/sample-x.y.z/lib/libsample.so. Ideally I'd like to be able to update the library, change the sys configs and not bother other devs with needing to change paths on trivial changes. I've added the library directory to the /etc/ld.so.conf.d/sample.conf and run ldconfig, but this only seems to affect loading not linking.
When I run ldconfig -v | grep sample, I correctly see libsample.so.
However, whenever I run ld -lsample --verbose, it fails to find the library. In the verbose output, it details the directories that it searches and the one I added with ldconfig isn't there. As a workaround, I tested adding a symlink to the library in /usr/lib and ld was able to find it.
Are there other ways to add the library to the default linker path? Ideally I'm looking for a config file that I can modify similar to the one for loading.
If it matters, the node is a Centos7 node.
No, it is not possible. The paths that ld uses during the linking phase are configured via scripts which are pulled into ld during its build process. There isn't a way to update these after ld is built. There are other questions and answers related to accomplishing this for GCC specifically which seem to involve the LIBRARY_PATH environment variable. That solution, however, is gcc specific.

ldconfig loading only .so files

I'm trying run a program(Snort) that uses libdnet but it fails to find it and outputs:
snort: error while loading shared libraries: libdnet.1: cannot open
shared object file: No such file or directory
Now I know that I should add the library by running ldconfig and putting path to the library in /etc/ld.so.conf. libdnet is located in /usr/local/lib so I don't have to modify ld.so.conf since it already covers that dirctory. So I ran the following commands and tracing the output, I noticed my library is not being loaded.
ldconfig -v
Apparently ldconfig only loads files that have .so somewhere in their names and libdnet.1 doesn't match the pattern.
I've built libdnet from source and installed it using ./configure; make; make install commands. I'd rather not install it using the package manager unless I have to. What should I do?
EDIT:
It says here that libraries should match the patter lib*.so* but I can't rename the library. I neither made it nor am I using it in my own app: if I rename it it will be loaded but I think Snort is looking for libdnet.1 not libdnet.so.1.
Found the answer here. The Solution was simple: make a copy that matches the pattern.
cp /usr/local/lib/libdnet.1.0.1 /usr/local/lib/libdnet.so.1.0.1
A less preferred alternative:
$ LD_LIBRARY_PATH=/usr/local/lib
$ export LD_LIBRARY_PATH

Unable to link shared libraries not under the system library directories on Ubuntu 12.04

I created a shared library, libsslab_core.so.1.0.0 using gcc with proper options. I am pretty sure that the shared library works because I already linked it to another source code (I explicitly tells a compiler, gcc, the location of the library using -l option of the compiler).
After testing the library works, I tried to integrate the library into my Linux machine. I went to the /etc/ld.so.conf.d/ and added a file, sslab.conf. In the file I just typed the absolute path of the library, /opt/lib/sslab. Next, I executed ldconfig as a root to update the cache file of ldconfig. And I checked if the system finds the newly added library by typing ldconfig -p | grep libsslab. My Linux machine found the library, so I thought everything is finished.
However, when I try to compile a source code using the library, it gives me the following error:
/usr/bin/ld: cannot find -lsslab_core
When I move the library to /usr/local/lib, update the content of sslab.conf, and execute ldconfig as a root. I can use the shared library without any problems.
Do you have any ideas about the problem that I've come across on Ubuntu 12.04?
For your information, I refer to a document in TLDP to generate my own shared library. Here is the link: http://www.tldp.org/HOWTO/Program-Library-HOWTO/

dlopen failed: cannot open shared object file: No such file or directory

The problem is I use dlopen to load a library (the .so is written by me, it's not a system library), but I got the error shown in the title.
I have included dlfcn.h
in compiler, I used the -ldl command
What I want to load is just the source code folder, I tried to add -L., but it did not work.
The most brutal and effective way to find out where your code goes wrong is the following command which will activate the debugging mode for shared libraries and is documented here:
export LD_DEBUG=libs
Then, you will be surprised that so much information pops up. Don't worry, these information tells you which shared libraries the command you just typed needs and where to locate these needed libraries. For example, if you type reset, the screen will be reseted and then information about the shared libraries reset command needs will be printed.
Then, execute your "problematic" executable to see what's going wrong.
PS.1 : According to your accepted mythagal's solution :
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
It seemed that even though you use absolute or relative path in the dlopen function, the directory not found error will still show up. I am using CentOS, and my Debian is also having this problem. So I think the first solution mythagal provide is wrong. You can verify that in the "debugging" mode I mentioned above.
PS.2: If you "install" or "compile" a shared library rather than install it through package manager, you MUST run sudo ldconfig /path/where/not/found/shared/library/reside to notify the system of the newly added shared library. For example :
cp /etc/ld.so.cache ~/ld.so.cache.backup
#cp -r /etc/ld.so.conf.d ~/ld.so.conf.d.backup #sometimes this backup is unnecessary.
#cp /etc/ld.so.conf ~/ld.so.conf.backup #sometimes this backup is unnecessary.
sudo ldconfig /PATH/WHERE/NOT/FOUND/SHARED/LIBRARY/RESIDE
###I am omitting the cp commands to roll back.
###For example, sudo cp -f ld.so.cache /etc/ld.so.cache
To understand what's going on here, please carefully read all the contents in the link above.
PS.3 : You can always use the command export LD_DEBUG=help,export LD_DEBUG=libs to figure out how -rpath or LD_LIBRARY_PATH solve your problem. You will love this debugging mode.
PS.4: A less brutal way to figure out what's going wrong:
ldd ./YOURproblematicEXECUTABLE
This command can tell you whether your shared library to be opened is located or not. Besides, there are so many ways to fix your problem and each way has its limitation and application. So I strongly suggested you read the link I provide you above and understand how to choose the way to solve your problem. After reading that, if you actually feel like being very "OK", you can also read this Better understanding Linux secondary dependencies solving with examples for deeper understanding.
If the library you want to dlopen is not in the standard search path you have a number of options:
Specify the full path to the file in dlopen
dlopen("/full/path/to/libfile.so");
Add the path to the library via LD_LIBRARY_PATH
LD_LIBRARY_PATH=/path/to/library/ ./executable
use the ld -rpath option to add a library path to the application.
g++ -link stuff- -Wl,-rpath=/path/to/library/
Note that options 1 & 3 hardcode the library path into your application. -rpath does have an option to specify a relative path, i.e.
-Wl,-rpath=$ORIGIN/../lib/
Will embed a relative path into the application.
the dlopen's declaration look like,
void *dlopen(const char *filename, int flag);
if you set the para 'filename' as shared library's name , you should add you current path into the 'LD_LIBRARY_PATH'.for instance,
1, dlopen("libtest.so" , RTLD_LAZY)
2, in shell , export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
For my case, the solution was very simple:
The path is expected to be absolute unless clearly specified as relative
So I replaced
dlopen("mylib.so", RTLD_NOW)
with
dlopen("./mylib.so", RTLD_NOW)
And the problem solved.
I would recommed dlerror to get the reason
void* handle = dlopen(SO_FILE, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if(handle == NULL)
{
printf(LOG_ERROR, "Error: %s\n", dlerror());
assert(0);
}
this will report detailed reason for the error

shared library problems on linux

I'm trying to compile/link a very old piece of software on a linux system and I can't for some reason link with a shared library that's installed on my system.
I get the following error from the linker:
/usr/bin/ld: cannot find -lXaw
However, the lib itself is installed. If I run
ldconfig -v | grep libXaw
I get (among other things) this hit:
libXaw.so.7 -> libXaw7.so.7.0.0
The library and the links to it are in /usr/lib btw. So nothing special.
So the library is there and ldconfig finds it. What could ld cause ld from not finding the library during link-time? As you may have already guessed I'm quite new to the shared library stuff.
Any ideas?
The linker may be looking, literally, for "libXaw.so". Is that in /usr/lib? If not, you could try adding it as another soft link from libXaw7.so.7.0.0.
The reason for the symlink btw is to select the default version to link against in the case of multiple versions, keep in mind the name of the library is integrated into the binary. (which you can see with ldd).
Are the -L library directories being overridden, and it's not looking in /usr/lib?
To link it, you need the .a file, NOT the .so file, which is the runtime library. The shared object is only useful to a program already linked against the non-shared parts of a library. This is typically distributed in a ".a" file.

Resources