Home » C++ » How to specify preference of library path?

How to specify preference of library path?

Posted by: admin November 29, 2017 Leave a comment

Questions:

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++
Answers:

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.

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)

Questions:
Answers:

Specifying the absolute path to the library should work fine:

g++ /my/dir/libfoo.so.0  ...

Did you remember to remove the -lfoo once you added the absolute path?

Questions:
Answers:

This is an old question, but no one seems to have mentioned this.

You were getting lucky that the thing was linking at all.

You needed to change

g++ -g -Wall -o my_binary -L/my/dir -lfoo bar.cpp

to this:

g++ -g -Wall -o my_binary -L/my/dir bar.cpp -lfoo

Your linker keeps track of symbols it needs to resolve. If it reads the library first,
it doesn’t have any needed symbols, so it ignores the symbols in it. Specify the libraries after the things that need
to link to them so that your linker has symbols to find in them.

Also, -lfoo makes it search specifically for a file named libfoo.a or libfoo.so as needed. Not libfoo.so.0. So either ln the name or rename the library as appopriate.

To quote the gcc man page:

-l library
   ...
   It makes a difference where in the command you 
   write this option; the linker searches and processes 
   libraries and object files in the order they are 
   specified.  Thus, foo.o -lz bar.o searches library z 
   after file foo.o but before bar.o.  If bar.o refers 
   to functions in z, those functions may not be loaded.

Adding the file directly to g++‘s command line should have worked,
unless of course, you put it prior to bar.cpp, causing the linker
to ignore it for lacking any needed symbols, because no symbols were needed yet.

Questions:
Answers:

As an alternative, you can use the environment variables LIBRARY_PATH and CPLUS_INCLUDE_PATH, which respectively indicate where to look for libraries and where to look for headers (CPATH will also do the job), without specifying the -L and -I options.

Edit:
CPATH includes header with -I and CPLUS_INCLUDE_PATH with -isystem.

Questions:
Answers:

If one is used to work with DLL in Windows and would like to skip .so version numbers in linux/QT, adding “CONFIG += plugin” will take version numbers out. To use absolute path to .so, giving it to linker works fine, as Mr. Klatchko mentioned.