Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

My project tree looks something like that:

src/
include/
Makefile
lib/
   lib/3rdparylib/

I didn't code 3rdpartylib, but decided to embed its source code in my project packaging. I compile the software by doing the following steps:

$ cd lib/3rdpartylib/
$ make
$ ln -s 3rdpartylib.so.0 3rdpartylib.so

Then I compile each of my source files like this:

$ gcc -c src/file.c -I include -o file.o -l 3rdparylib -L lib/3rdpartylib -I lib/3rdpartylib/include

Then I link:

$ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp

When I am on my main machine, it works perfectly. Today I tried to launch it on another machine. It compiled and linked without any problem. However when I tried to launch the application I got the following error message.

./myapp: error while loading shared libraries: 3rdpartylib.so.0: cannot open shared object file: No such file or directory

I tried doing the following:

export LD_LIBRARY_PATH=/path/to/3rdpartylib.so

It seems to work. But I understand that using LD_LIBRARY_PATH is a bad practice. It bothers me to have this variable set up every time I want to run my app.

What am I missing? Why does it work on my main machine (where LD_LIBRARY_PATH is not set to anything) and not on the other machine? Does it matter that the other machine is a virtual one?

If it is of any help, my main machine is a Debian box, and my "new" machine is a Sabayon (Gentoo), running in Virtualbox.

share|improve this question
    
I don't see what's going on at the moment, but this may provide useful background. –  Gilles Nov 23 '11 at 23:54

4 Answers 4

What matters is what Linux distribution each machine uses, because they handle library paths differently. On the Gentoo (Sabayon) machine, if you want a third party library to be usable system-wide, you should:

  • Create a file under /etc/env.d/ that will contain the additional environment setup. The files are named using the scheme [0-9][0-9]somename - the two initial digits decide on the order in which they are used. A good practice requires that your custom settings are added (near) last, so 99 is a proper beginning, as long as it works. Getting to the point: Create a file named like

    /etc/env.d/99mythirdpartylib
    

    containing

    LDPATH=/path/to/your/library
    
  • To make the changes active without reboot, run as root:

    env-update && source /etc/profile
    

    (which will update the environment as well as run ldconfig).

Reference, if you'd like one.

share|improve this answer

If you don't want to set a global library search path for your whole system with the /etc/env.d approach, you can either:

Just set the LD_LIBRARY_PATH to the PATH of your library (you did set it to the library itself, that won't work), the same which you set with the -L parameter to gcc e.g.

export LD_LIBRARY_PATH="$PROJ/lib/3rdpartylib/:$LD_LIBRARY_PATH"

(the last part is for preserving the variable if it was already set, which it shouldn't be normally). This will only work in you current shell and you will have to set it again everytime.

Or you link using a 'static' library search paths like this:

gcc file1.o file2.o -L./lib/3rdpartylib -Wl,-rpath=./lib/3rdpartylib  -l3rdpartylib  -o myapp

-Wl specifies commmand line arguments that will not be processed by gcc but instead be passed to the linker. Since the library search path will be written into the binary, this will work even on different machines (provided the library exists)

PS: Since you're just talking about the case where you're developing a project, I think this temporary way is more appropriate than putting it in system-wide configuration files.

share|improve this answer

The line:

$ gcc file1.o file2.o -l3rdpartylib -L lib/3rdpartylib -o myapp

searches for a file called lib3rdpartylib.so in your library path, which doesn't even include lib/3rdpartylib! If you look at the gcc man page, it states that when specifying a library path with -L it must come before the -l flags, or it will not be searched. Really, the simplest solution is to just link to the library itself:

$ gcc file1.o file2.o lib/3rdpartylib/3rdpartylib.so -o myapp

That way, the library will be searched for in the library paths and dynamically loaded when myapp runs.

If you want to check it, just do an strace -eopen ./myapp once it's installed and look at where it tries to load the library from.

share|improve this answer
    
If that were the issue, wouldn't ld complain during building? The app is said to get built fine. –  rozcietrzewiacz Nov 24 '11 at 19:25

You have to tell your system where to look for libraries. This job is done by /etc/ld.so.cache. You can add libraries or whole directories in /etc/ld.so.conf.

You can rebuild the cache by doing:

# /sbin/ldconfig -v
share|improve this answer
    
On Gentoo this is not the way to do it: the top line of /etc/ld.so.conf proves it vividly, saying "ld.so.conf autogenerated by env-update; make all changes to contents of /etc/env.d directory" –  rozcietrzewiacz Nov 24 '11 at 19:02
    
...And /etc/env.d is sourced on each boot, so you'd loose all your changes. –  rozcietrzewiacz Nov 24 '11 at 19:04
    
Ok I don't know Gentoo, env-update will do exactly what I say : env-update will also extract the information from the LDPATH variable and use that to create /etc/ld.so.conf. After this, it will run ldconfig to recreate the /etc/ld.so.cache. So your answer is better ;-) –  fab Nov 24 '11 at 20:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.