gcc: linked libraries in /usr/local/lib are not found, but /etc/ld/so.conf.d/libc.conf lists it? - linux

I've got a problem with shared libraries and gcc. At first I couldn't run my compiled program because I was getting the following error: gcc error while loading shared libraries.
I did some searching and found that this is because the shared library cannot be found. However I had already identified that the shared library is in /usr/local/lib, which AFAICT is a commonly used directory for shared libraries and should work from the get go.
I read that you can set LD_LIBRARY_PATH, which worked for me. However I do not wish to set this each time I want to run my program.
Further searching suggested editing ld.so.conf. When I looked in this it had the following:
include /etc/ld.so.conf.d/*.conf
Looking in the ld.so.conf.d directory shows me a range of files, including libc.conf. Inside this file is the following:
/usr/local/lib
So my question is, why do I need to manually set LD_LIBRARY_PATH when the ld.so.conf appears to use the libc.conf which includes /usr/local/lib?
Is there something that I'm missing here that must be configured first? Is there an option at compile time that I'm missing?
I should note that to compile, I had to specify the path to the library, I don't know if this is a symptom of my problem or normal behaviour.
I should also note that this is a concern for me for when I deploy my software on other systems. I would have thought that I should be able to put the .so in the appropriate place and install my program without messing with ld.so.conf.
I hope this is the proper forum for this question, I read the FAQ and I think it's ok.
Cheers.

You should run ldconfig (as root) after every change of the directories configured via /etc/ld.so.conf or under /etc/ld.so.conf.d/, in particular in your case after every update inside /usr/local/lib (e.g. after every addition or update of some shared libraries there).

Related

is it possible to suppress user libraries from system libraies in linux

I'm creating a application that is using a pre-compiled third party shared library files.To use these I'm required to set the LD_LIBRARY_PATH or create a conf file under /etc/ld.so.conf.d/application.conf, My problem is There is a system libcurl.so.4 already available under /usr/lib/.The third party Library also has a libcurl.so.4 . If I create /etc/ld.so.conf.d/application.conf file, I'm not able to use "YUM installer" .
I'm getting the error
Pycurl error occured ,
Compile time Version is higher than the Linking version
I'm worried to remove the application libcurl.so.4 as it may break the features in that third party library that I'm making use of(making my application meaning less) and I can't neglect the system library either .
Is it possible to use these two libraries without any conflict as I mentioned above.
PS : Setting LD_LIBRARY_PATH too causes the same problem
Create a script that sets and exports $LD_LIBRARY_PATH before invoking the executable. The variable will disappear once the script exits.
If you have 2 conflicting libs and one is system, another one is a user app, don't put application.conf into /etc/ld.so.conf.d/. Instead use something like ~your_user_name/custom_conf , put your application.conf file there (eventually you may need to edit it adding the path to the proper version of libcurl.so.4). libcurl.so.4 should be not in system dirs as well rather in ~your_user_name/lib. You can make a wrapper for your app where you set $LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~your_user_name/lib as Ignacio Vazquez-Abrams suggested or compile your app explicitly pointing out which library to link (use linker flags -L /full/path/to/your/libcurl.so.4)

Looking for missing shared library

On a Linux system, I am trying to run a Fortran program that makes use of some shared libraries (netCDF libs, if that makes a difference). Before I run, I set LD_LIBRARY_PATH so that it points to the location of my libraries. Then I run the executable and I quickly get the error
../my_program: error while loading shared libraries: libnetcdff.so.5: cannot open shared object file: No such file or directory
Now, I double check the value of LD_LIBRARY_PATH, and then cd to it and find plain as day
$ ls *ff*
$ libnetcdff.a libnetcdff.la libnetcdff.so libnetcdff.so.0 libnetcdff.so.0.0.0
So the libnetcdff is absolutely present.
Could anyone point me to the problem?
The one thing that has occurred to me is that the executable seems to want to find libnetcdff.so.5, while the library that is present is actually libnetcdff.so.0. Is that the problem? If so, is there a way to convince the executable to not insist on "5"? Alternatively, would a link from libnetcdff.so.0 to libnetcdff.so.5 solve the problem? (I don't have permissions in the directory, BTW, which is why I haven't tried that yet.)
Environment info: CentOS machine, code compiled with gfortran. And yes, when I compiled, my -L flags were pointing to the same directory that LD_LIBRARY_PATH points to.
Thanks.
A library link should work. Since you mention that you do not have root/sudo access, what you can do is link in a file you do have access in:
ln -s /path/to/libnetcdff.so.0 /path/you/have/access/to/libnetcdff.so.5
And then add in the /path/you/have/access/to/ in your LD_LIBRARY_PATH.

How to manage development and installed versions of a shared library?

In short: This question is basically about telling Linux to load the development version of the .so file for executables in the dev directory and the installed .so file for others.
In long: Imagine a shared library, let's call it libasdf.so. And imagine the following directories:
/home/user/asdf/lib: libasdf.so
/home/user/asdf/test: ... perform_test
/opt/asdf/lib: libasdf.so
/home/user/jkl: ... use_asdf
In other words, you have a development directory for your library (/home/user/asdf) and you have an installed copy of its previous stable version (/opt/asdf) and some other programs using it (/home/user/jkl).
My question is, how can I tell Linux, to load /home/user/asdf/lib/libasdf.so when executing /home/user/asdf/test/perform_test and to load /opt/asdf/lib/libasdf.so when executing /home/user/jkl/use_asdf? Note that, even though I specify the directory by -L during link, Linux uses other methods (for example /ect/ld.so.conf and $LD_LIBRARY_PATH) to find the .so file.
The reason I need such a thing is that, of course the executables in the development directory need to link with the latest version of the library, while the other programs, would want to use the stable version.
Putting ../lib in the library path doesn't seem like a secure idea, not to mention not completely correct since you can't run the test from a different directory.
One solution I thought about is to have perform_test link with libasdf-dev.so and upon install, copy libasdf-dev.so as libasdf.so and have others link with that. This solution has one problem though. Imagine the following additional directory:
/home/user/asdf/tool: ... use_asdf_too
Which gets installed to:
/opt/asdf/bin: use_asdf_too
In my solution, it is unknown what use_asdf_too should be linked against. If linked against libasdf.so, it wouldn't work properly if invoked from the dev directory and if linked against libasdf-dev.so, it wouldn't work properly if invoked from the installed location.
What can I do? How is this managed by other people?
Installed shared objects usually don't just end with ".so". Usually they also include their soname, such as libadsf.so.42.1. The .so file for development is typically a symlink to a fully-versioned filename. The linker will look for the .so file and resolve it to the full filename, and the loader will then load the fully-versioned library instead.

How to build libcurl.so with a different target name?

I am using libcurl for my utility and its working very well till now for all Linux platforms. I downloaded, unzipped and simply followed the instructions given without any changes. My product uses the libcurl.so file and is linked dynamically. The .so file is bundled along with our product. Recently there were issues in Suse wherein we found that Libcurl is bundled by default and there was a conflict in installation.
To avoid this issue we tried renaming the libcurl.so into libother_curl.so but it did not work and my binaries still show libcurl.so as a dependency through ldd. I had since learnt that the ELF format of linux shared objects specifies the file name hardcoded as SO file name in the headers.(I could verify the same with objdump -p).
Now my question is what is the simplest way to go? How do I build a libcurl with a different name? My original process involves running configure with the following switches
./configure --without-ssl --disable-ldap --disable-telnet --disable-POP3 --disable-IMAP --disable-RTSP --disable-SMTP --disable-TFTP --disable-dict --disable-gopher --disable-debug --enable-nonblocking --enable-thread --disable-cookies --disable-crypto-auth --disable-ipv6 --disable-proxy --enable-hidden-symbols --without-libidn --without-zlib
Make
Then pick the generated files from /lib/.libs
Are there any Configure Switches available wherein I can specify the target file name? Any specific Makefile I could change?
I tried changing in what I thought could be obvious locations but either could not generate the libs or were generated with the same name.
Any help is much appreciated.
I got the answer from the curl forums(Thanks Dan). Basically we have to use the makefile.am as a starting point to go through a list of files and change the library name "libxxx_curl".
$find . -name Makefile.am |xargs sed -i 's/libcurl(.la)/libxxx_curl\1/g'
$buildconf
$configure
$make
I lot of commercial applications bundle their particular library versions in a non standard path and then tweak environment variable LD_LIBRARY_PATH in a launch script so to avoid conflict. IMHO it is better than trying to change the target name.

How to link shared libraries in local directory, OSX vs Linux

I have some shared/dynamic libraries installed in a sandbox directory. I'm building some applications which link agains the libraries. I'm running into what appears to be a difference between OSX and Linux in this regard and I'm not sure what the (best) solution is.
On OSX the location of library itself is recorded into the library, so that if your applications links against it, the executable knows where to look for the library at runtime. This works like expected with my sandbox, because the executable looks there instead of system wide install paths.
On Linux I can't get this to work. Apparently the library location is not present in the library itself. As I understand it you have to add the folders which contain libraries to /etc/ld.so.conf and regenerate the ld cache by running ldconfig.
This doesn't seem to do the trick for me because my libraries are located inside a users home directory. It looks like ldconfig doesn't like that, which makes sense actually.
How can I solve this? I don't want to move the libraries out of my sandbox.
On Linux, run your program with the environment variable LD_LIBRARY_PATH set to your sandbox dir.
(I remember having used a flag -R to include library paths in the binary, but either it has been removed from gcc or it was only available on BSD systems.)
On Linux you should set LD_RUN_PATH to your sandbox dir. This is better than setting LD_LIBRARY_PATH because you're telling the linker where the library is at link time, rather than telling the shared library loader at run time.
See: Link

Resources