3
votes

I am having difficulty understanding the order in which directories are searched for linking to libraries. I have a CentOS6 system and 3 versions of gcc, 4.4.7, 4.7.2, 4.9.2. The system version is 4.4.7 and version 4.7.2 and 4.9.2 are modules. In /etc/ld.so.conf.d/ there two files, gcc-4.7.2.conf and gcc-4.9.2.conf which contain the paths to the 4.7.2 and 4.9.2 libraries.

I created a simple C++ program, main.cpp

#include <cstdio>
#include <iostream>

using namespace std;


int main(void)
{
    cout << "Hello You!" << endl;
    printf("Back at you!\n");

    return 0;
}

compiling it with g++-4.4.7 and running ldd a.out, I see

linux-vdso.so.1 =>  (0x00007fff5535b000)
libstdc++.so.6 => /nonstandardpath/gcc-4.7.2/lib64/libstdc++.so.6 (0x00002ac12de73000)
libm.so.6 => /lib64/libm.so.6 (0x00002ac12e17a000)
libgcc_s.so.1 => /nonstandardpath/gcc-4.7.2/lib64/libgcc_s.so.1 (0x00002ac12e3ff000)
libc.so.6 => /lib64/libc.so.6 (0x00002ac12e614000)
/lib64/ld-linux-x86-64.so.2 (0x00002ac12dc51000)

Looking at man ld, it states (under -rpath-link=dir) :

The linker uses the following search paths to locate required shared libraries:

  1. Any directories specified by -rpath-link options.

  2. Any directories specified by -rpath options. The difference between -rpath and -rpath-link is that directories specified by -rpath options are included in the executable and used at runtime, whereas the -rpath-link option is only effective at link time. Searching -rpath in this way is only supported by native linkers and cross linkers which have been configured with the --with-sysroot option.

  3. On an ELF system, for native linkers, if the -rpath and -rpath-link options were not used, search the contents of the environment variable "LD_RUN_PATH".

  4. On SunOS, if the -rpath option was not used, search any directories specified using -L options.

  5. For a native linker, the search the contents of the environment variable "LD_LIBRARY_PATH".

  6. For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared library are searched for shared libraries needed by it. The "DT_RPATH" entries are ignored if "DT_RUNPATH" entries exist.

  7. The default directories, normally /lib and /usr/lib.

  8. For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list of directories found in that file.

    If the required shared library is not found, the linker will issue a warning and continue with the link.

It does not state the order in which the directories are searched. From my example above, it appears that /etc/ld.so.conf.d is searched before /usr/lib or /lib

QUESTION : what is the order in which linker searches for libraries (e.g. LD_LIBRARY_PATH, ld.so.conf.d, -rpath, -L)?

1

1 Answers

1
votes

The online man page states the order for ld:

When resolving shared object dependencies, the dynamic linker first inspects each dependency string to see if it contains a slash (this can occur if a shared object pathname containing slashes was specified at link time).

If a slash is found, then the dependency string is interpreted as a (relative or absolute) pathname, and the shared object is loaded using that pathname.

If a shared object dependency does not contain a slash, then it is searched for in the following order:

  • Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated.

  • Using the environment variable LD_LIBRARY_PATH (unless the executable is being run in secure-execution mode; see below). in which case it is ignored.

  • Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present. Such directories are searched only to find those objects required by DT_NEEDED (direct dependencies) entries and do not apply to those objects' children, which must themselves have their own DT_RUNPATH entries. This is unlike DT_RPATH, which is applied to searches for all children in the dependency tree.

  • From the cache file /etc/ld.so.cache, which contains a compiled list of candidate shared objects previously found in the augmented library path. If, however, the binary was linked with the -z nodeflib linker option, shared objects in the default paths are skipped. Shared objects installed in hardware capability directories (see below) are preferred to other shared objects.

  • In the default path /lib, and then /usr/lib. (On some 64-bit architectures, the default paths for 64-bit shared objects are /lib64, and then /usr/lib64.) If the binary was linked with the -z nodeflib linker option, this step is skipped.

Taken from the 2017-09-15 version. I assume older versions of ld are similar.