/* Ajith - Syntax Higlighter - End ----------------------------------------------- */

12.17.2009

Creating Shared Libraries in Linux - Part 2

Check the PART1 of this article.

4. Making the library available at run-time

Using LD_LIBRARY_PATH
We have to create or set the environment variable "LD_LIBRARY_PATH" to the directory containing the shared libraries.
export LD_LIBRARY_PATH=/home/cf/lib
If in current directory you can give the following command
export LD_LIBRARY_PATH=.
If we have to append a new directory to the existing paths then add the directories separated by colons to environment variable "LD_LIBRARY_PATH".
export LD_LIBRARY_PATH=/opt/lib:$LD_LIBRARY_PATH
Now recompile the main program
gcc -o test main.c -lcalc_mean -L/home/cf/slib
Now check the ldd command output
$ ldd test
 linux-gate.so.1 =>  (0x007ad000)
 libcalc_mean.so => ./libcalc_mean.so (0x0081e000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x005ff000)
 /lib/ld-linux.so.2 (0x00e19000)
It seems now linker is able to locate our shared library as we can see in above output. Now run the program
$./test
LD_LIBRARY_PATH is good for quick tests and for systems on which you don’t have admin privileges. As a downside, however, exporting the LD_LIBRARY_PATH environment variable  might screw up with other programs you run that also rely on LD_LIBRARY_PATH if you don’t reset it to its previous state when you’re done.

Using rpath
Rpath, or the run path or -R, is a way of embedding the location of shared libraries in the executable itself, instead of relying on default locations or environment variables. We do this during the linking stage. Before we compile the main.c with rpath option we will unset the LD_LIBRARY_PATH.
gcc -g -o test main.c -lcalc_mean -L/home/cf/slib -Wl,-R/home/cf/slib
or
gcc -g -o test main.c -lcalc_mean -L/home/cf/slib -Wl,-rpath=/home/cf/slib
  • -Wl portion sends comma-separated options to the linker, so we tell it to send the -rpath option to the linker with our working directory.
$ ldd test
 linux-gate.so.1 =>  (0x00a1b000)
 libcalc_mean.so => /home/cf/slib/libcalc_mean.so (0x00e84000)
 libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00359000)
 /lib/ld-linux.so.2 (0x007c3000)
The rpath method is great since each program gets to list its shared library locations independently, so there are no issues with different programs looking in the wrong paths like there were for LD_LIBRARY_PATH. But rpath has its downsides even.
  • First, it requires all shared libraries be installed in a fixed location so that all users of your program will have access to those libraries in those locations. That means less flexibility in system configuration. 
  • Second, if that library refers to a NFS mount or other network drive, you may experience undesirable delays–or worse–on program startup.

References
1. Yolinux
2. CProgramming

5 comments :

  1. I am trying to make an executable using a custom shared dynamic library in Linux. However when I run my Makefile I get this errors (where `mylib` is my library: `libmylib.so` and located in `/home/user/test/`):

    /usr/bin/ld: skipping incompatible home/user/test/libmylib.so when searching for -lmylib
    /usr/bin/ld: cannot find -lmylib

    This is the makefile I am using:

    build: main.xo
    gcc main.xo -o exec -lmylib -L/home/user/test -Wl,-R/home/user/test4
    main.xo: main.c uso.h
    gcc -c main.c -o main.xo
    Can someone tell me what am I doing wrong?

    ReplyDelete
  2. Thanks for your help!

    ReplyDelete
  3. Thank you very much. Now I figured out the difference between option -L and -rpath. -L tells the linker ld where to find the shared library that needs to be linked. And -rpath actually tells the compiler where to load the shared library, when building an executable which depends on the some certain shared libraries(.so files).

    ReplyDelete

Your comments are moderated