Add /usr/local/lib to g++ library search path permanently - c++

I want to make g++ linker(ld) search for libraries starting in the directory /usr/local/lib. How do I permanently add /usr/local/lib to the search path for the linker?
The problem is that I am trying to link the library libboost_program_options.a to my source. There are two copies of the library, one in /usr/lib/x86_64-linux-gnu/ and the other in /usr/local/lib. How do I make the linker first look in /usr/local/lib and pick that instead of the other one?
The output of ldconfig -v 2>/dev/null | grep -v ^$'\t' on my system:
/usr/lib/x86_64-linux-gnu/libfakeroot:
/lib/i386-linux-gnu:
/usr/lib/i386-linux-gnu:
/usr/local/lib:
/lib/x86_64-linux-gnu:
/usr/lib/x86_64-linux-gnu:
/usr/lib/x86_64-linux-gnu/mesa-egl:
/usr/lib/nvidia-304:
/usr/lib32/nvidia-304:
/lib32:
/usr/lib32:
/lib:
/usr/lib:
/usr/lib/nvidia-304/tls: (hwcap: 0x8000000000000000)
/usr/lib32/nvidia-304/tls: (hwcap: 0x8000000000000000)
The output of ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib64")
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/local/lib64")
SEARCH_DIR("=/lib/x86_64-linux-gnu")
SEARCH_DIR("=/lib64")
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/lib64")
SEARCH_DIR("=/usr/x86_64-linux-gnu/lib")
SEARCH_DIR("=/usr/local/lib")
SEARCH_DIR("=/lib")
SEARCH_DIR("=/usr/lib")

The search path is specified in the linker scripts used during compilation. Run gcc -v foo.c to perform a link and see which linker script is used. In my case, it is /usr/lib/ldscripts/elf_x86_64.x. In that linker script, you will find SEARCH_DIR directives. Update it to include /usr/local/lib.
Note that ldconfig and ld.so.conf.d are only used at runtime.

Related

What does "-I" and "-L" mean when prepended to a path?

When installing openssl using brew, a part of the response is outputted:
For compilers to find openssl you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
and the following could be used to compile a C++ file.
g++ file.cpp -I/usr/local/opt/openssl/include
What is the -I and the -L for?
-L means the path is a dir which contains Libraries for linking (adds the path to the set of dirs the linker will search)
-I means there are header files to Include in the given dir.

shared object library not found when running program, but it's linked during compiling

Update: issue is solved. The library was Made for Armv7a CPUs but it was "soft float" Not "hard float". It seems like my machine is HF and Not SF compatible
My program depends on an externally build .so library called libMyLib.so. When I compile the program like this:
$ g++ -std=c++11 main.cpp -o run -pthread
it reports that there are a lot of undefined references, obviously because i didn't include libMyLib.so when compiling. So the compiler knows what he needs to compile the program. When i compile the program like this:
$ g++ -std=c++11 main.cpp -o run -pthread -lMyLib
it doesn't report any errors and creates the file "run". Notice that libMyLib.so is already in /usr/local/lib and it looks like it is linked when compiling since the references are defined now and the "run" file is created. But as i run the file, this happens:
$ ./run
./run: error while loading shared libraries: libMyLib.so: cannot open shared object file: No such file or directory
I've checked with ldd and it shows me this:
$ ldd run
...
libMyLib.so => not found
...
So ldd doesn't find the library on execution, but it finds it while compiling. I'm quite new to Linux and linking libraries so i don't know what to do.
Also, running ldd on the .so file returns this:
$ ldd /usr/local/lib/libMyLib.so
not a dynamic executable
I've already checked an this message may occur when running a .so file on the wrong platform. But i've checked, the library is compiled for arm (I'm running on a raspberry pi -> arm):
$ objdump -f /usr/local/lib/libMyLib.so | grep ^architecture
architecture: arm, flags 0x00000150:
I also update the linker:
$ sudo ldconfig -v
...
/usr/local/lib:
libwiringPi.so -> libwiringPi.so.2.44
libwiringPiDev.so -> libwiringPiDev.so.2.44
libMyLib.so -> libMyLib.so.1
...
I really have no clue why this might still happen. Can anyone help me?
/usr/local/lib is one of the directories that the linker searches by default
for libraries specified with the -l option, so your linkage succeeds.
At runtime however, the program loader by default searches for the linked
libraries in:-
/lib, /usr/lib and among the libraries whose names and locations have been cached in the ldconfig cache, /etc/ld.so.cache.
The directories listed in the value of the environment variable LD_LIBRARY_PATH,
in the current shell.
The ldconfig cache is only updated when ldconfig is run. See man ldconfig.
The loader fails to find libMyLib.so at runtime because you have not
run ldconfig since you placed that library in /usr/local/lib and
neither have you correctly added /usr/local/lib to the LD_LIBRARY_PATH
in the same shell in which you try to run the program.
It is inconvenient and otherwise undesirable to require a special setting of
LD_LIBRARY_PATH to enable a program to run.
To enable the loader to find your library, run ldconfig as root. This
will succeed provided that /usr/local/lib is listed in /etc/ld.so.conf,
or in one of the files included by /etc/ld.so.conf. If it's not, then
you can explicitly cache the shared libraries from /usr/local/lib by running
ldconfig /usr/local/lib, as root.
First check LD_LIBRARY_PATH variable is having the path to your library directory
$ echo $LD_LIBRARY_PATH
If not there then update the library path.
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library
Use strace to debug.
strace -f ./run

gcc or g++ path search order on default directories when linking libraries

I've seen this article and learned that:
Directories specified on the command line with -L option are searched before the default directories.
The directories specified in -L are searched in the order in which they are specified on the command line.
The question is: Is there an search order for the default directories?
For example, if I run this command:
$ gcc -Xlinker --verbose 2>/dev/null | grep SEARCH | sed 's/SEARCH_DIR("=\?\([^"]\+\)"); */\1\n/g' | grep -vE '^$'
(command copied from this article)
it prints out /usr/local/lib before /usr/lib in my machine (Ubuntu 16.04, 64-bit, gcc 5.4.0). In this case, will /usr/local/lib be searched before /usr/lib?
From the binutils ld manual section 3.4.2 Commands Dealing with Files:
SEARCH_DIR(path)
The SEARCH_DIR command adds path to the list of paths where ld looks for archive libraries. Using SEARCH_DIR(path) is exactly like using `-L path' on the command line (see Command Line Options). If both are used, then the linker will search both paths. Paths specified using the command line option are searched first.
So, yes, as the default directories are given in the default linker script using this SEARCH_DIR() command, they will be searched in the order the SEARCH_DIR() commands appear.
E.g., in my mingw installation, the default linker script starts like this:
/* Default linker script, for normal executables */
/* Copyright (C) 2014-2017 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT(pei-i386)
SEARCH_DIR("=/mingw32/i686-w64-mingw32/lib");
SEARCH_DIR("=/mingw32/lib");
SEARCH_DIR("=/usr/local/lib");
SEARCH_DIR("=/lib");
SEARCH_DIR("=/usr/lib");
--> A library in /usr/local/lib can override libraries in /lib and /usr/lib, but not libraries provided by mingw itself.

shared library not in ld cache

I'm attempting to use the JAUS++-2.110519 library. Following the included instructions, I have managed to install the library. I have verified the following:
Shared libraries:
libcxutils.so
libjauscore.so
libjausextras.so
libjausmobility.so
libtinyxml.so
are located in
/usr/local/lib/active
Header files
are located in
/usr/local/include/active
Source code
is located in
/usr/local/src/
Following the installation, it was mentioned in the instructions that the library path would need to be added to ld.so.conf. Since /etc/ld.so.conf.d/libc.conf already contained /usr/local/lib, running sudo ldconfig should have linked the newly installed library, however, I am not seeing said libraries in ld cache.
Running the following:
/sbin/ldconfig -p | grep libcxutils.so
/sbin/ldconfig -p | grep libjauscore.so
/sbin/ldconfig -p | grep libjausextras.so
/sbin/ldconfig -p | grep libjausmobility.so
/sbin/ldconfig -p | grep libtinyxml.so
returns nothing.
I have also created /etc/ld.so.conf.d/jaus.conf that contains the following:
/usr/local/lib/active
and ran sudo ldconfig afterwords. The results were the same, however.
Running nm -Ca on each of the *.so files appears to return valid input.
Why can't I get ldconfig to link this library properly? I am running Ubuntu 12.04.

Why shared library is linked by absolute path?

I create an application by linking the libociei.so and libcustome.so
CC -o main main.cpp ../lib/libociei.so ../lib/libcustome.so
and copy libociei.so libcustome.so to /usr/lib
then I use ldd to check library, it shows:
main .....
libcustome.so ===> /usr/lib/libcustome.so
../lib/libociei.so
why libociei.so is not relocated to /usr/lib/libociei.so ?
ps : ld library path is /lib:/usr/lib and I do not add ../lib to ld library path
If you are on linux (say Ubuntu) then it is probably because you did not run:
sudo ldconfig
On other systems I am not so sure.
When you use readelf -d main does the NEEDED entries have the full path?
My guess is that ldd is seeking the libraries in the default path.