How to specify preference of library path?

Heinrich Schmetterling picture Heinrich Schmetterling · Apr 28, 2010 · Viewed 229.5k times · Source

I'm compiling a c++ program using g++ and ld. I have a .so library I want to be used during linking. However, a library of the same name exists in /usr/local/lib, and ld is choosing that library over the one I'm directly specifying. How can I fix this?

For the examples below, my library file is /my/dir/libfoo.so.0. Things I've tried that don't work:

  • my g++ command is g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp
  • adding /my/dir to the beginning or end of my $PATH en` variable
  • adding /my/dir/libfoo.so.0 as an argument to g++

Answer

stefanB picture stefanB · Apr 28, 2010

Add the path to where your new library is to LD_LIBRARY_PATH (it has slightly different name on Mac ...)

Your solution should work with using the -L/my/dir -lfoo options, at runtime use LD_LIBRARY_PATH to point to the location of your library.

Careful with using LD_LIBRARY_PATH - in short (from link):

..implications..:
Security: Remember that the directories specified in LD_LIBRARY_PATH get searched before(!) the standard locations? In that way, a nasty person could get your application to load a version of a shared library that contains malicious code! That’s one reason why setuid/setgid executables do neglect that variable!
Performance: The link loader has to search all the directories specified, until it finds the directory where the shared library resides – for ALL shared libraries the application is linked against! This means a lot of system calls to open(), that will fail with “ENOENT (No such file or directory)”! If the path contains many directories, the number of failed calls will increase linearly, and you can tell that from the start-up time of the application. If some (or all) of the directories are in an NFS environment, the start-up time of your applications can really get long – and it can slow down the whole system!
Inconsistency: This is the most common problem. LD_LIBRARY_PATH forces an application to load a shared library it wasn’t linked against, and that is quite likely not compatible with the original version. This can either be very obvious, i.e. the application crashes, or it can lead to wrong results, if the picked up library not quite does what the original version would have done. Especially the latter is sometimes hard to debug.

OR

Use the rpath option via gcc to linker - runtime library search path, will be used instead of looking in standard dir (gcc option):

-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

This is good for a temporary solution. Linker first searches the LD_LIBRARY_PATH for libraries before looking into standard directories.

If you don't want to permanently update LD_LIBRARY_PATH you can do it on the fly on command line:

LD_LIBRARY_PATH=/some/custom/dir ./fooo

You can check what libraries linker knows about using (example):

/sbin/ldconfig -p | grep libpthread
        libpthread.so.0 (libc6, OS ABI: Linux 2.6.4) => /lib/libpthread.so.0

And you can check which library your application is using:

ldd foo
        linux-gate.so.1 =>  (0xffffe000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xb7f9e000)
        libxml2.so.2 => /usr/lib/libxml2.so.2 (0xb7e6e000)
        librt.so.1 => /lib/librt.so.1 (0xb7e65000)
        libm.so.6 => /lib/libm.so.6 (0xb7d5b000)
        libc.so.6 => /lib/libc.so.6 (0xb7c2e000)
        /lib/ld-linux.so.2 (0xb7fc7000)
        libdl.so.2 => /lib/libdl.so.2 (0xb7c2a000)
        libz.so.1 => /lib/libz.so.1 (0xb7c18000)