gcc - 搜索和链接库目录的顺序

标签 gcc linker centos ld

我很难理解搜索目录以链接到库的顺序。我有一个CentOS6系统和3个版本的gcc,4.4.7、4.7.2、4.9.2。系统版本为4.4.7,版本4.7.2、4.9.2为模块。在 /etc/ld.so.conf.d/ 中有两个文件,gcc-4.7.2.confgcc-4.9.2.conf 其中包含 4.7.2 和 4.9.2 库的路径。

我创建了一个简单的 C++ 程序,main.cpp

#include <cstdio>
#include <iostream>

using namespace std;


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

    return 0;
}

用 g++-4.4.7 编译它并运行 ldd a.out,我明白了

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)

查看 man ld,它指出(在 -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.

它没有说明搜索目录的顺序。从我上面的示例中,似乎在 /usr/lib/lib 之前搜索了 /etc/ld.so.conf.d/p>

问题:链接器搜索库(例如 LD_LIBRARY_PATH、ld.so.conf.d、-rpath、-L)的顺序是什么?

最佳答案

The online man page说明 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.

取自 2017-09-15 版本。我假设旧版本的 ld 是相似的。

关于gcc - 搜索和链接库目录的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36015224/

相关文章:

linux - 如何使用 Bash 中的 file 命令检查文件是否可执行?

c - 如何在 C 编程中执行 Shell 脚本,接收反馈和处理器 ID,并关闭进程

qt - 编译: undefined reference "clock_gettime and memcpy" for Qt project

gcc - C 预处理器宏 - 定义与值(value)可移植性和实践

c++ - qtCreator 错误 : can't map file, errno=22 架构 x86_64 文件?

ios - 使用 GCC 4.2 编译的 iOS 静态库与 Xcode 4.2 中的 LLVM 兼容吗?

Clang、Microsoft 链接器和标准库

c - C 动态分配如何与链接器一起定义堆位置

使用 GCC 编译 C 程序时找不到 -lgcc -s

c++ - "less than"ifstream 与 GCC 4 与 6 的比较