Error while loading shared libraries

7,569

Solution 1

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.

Solution 2

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:
7,569
rahmu
Author by

rahmu

Updated on September 18, 2022

Comments

  • rahmu
    rahmu over 1 year

    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.

  • rozcietrzewiacz
    rozcietrzewiacz over 12 years
    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
    rozcietrzewiacz over 12 years
    ...And /etc/env.d is sourced on each boot, so you'd loose all your changes.
  • rozcietrzewiacz
    rozcietrzewiacz over 12 years
    If that were the issue, wouldn't ld complain during building? The app is said to get built fine.
  • fab
    fab over 12 years
    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 ;-)