Gcc 搜索和链接库目录的顺序

Gcc 搜索和链接库目录的顺序,gcc,linker,centos,ld,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.conf和gcc-4.9.2.conf,其中包含指向4.7.2和4.9.2库的路径 我创建了一个简单的C++程序,Meal.CPP #include <cstdio> #include <iostream> using nam

我很难理解在目录中搜索链接到库的顺序。我有一个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.conf
gcc-4.9.2.conf
,其中包含指向4.7.2和4.9.2库的路径

我创建了一个简单的C++程序,Meal.CPP

#include <cstdio>
#include <iostream>

using namespace std;


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

    return 0;
}
查看
manld
,它指出(在
-rpath link=dir
下):

链接器使用以下搜索路径查找所需的共享路径 图书馆:

  • 由-rpath链接选项指定的任何目录

  • 由-rpath选项指定的任何目录。-rpath和 -rpath链接是指由-rpath选项指定的目录包含在 可执行并在运行时使用,而-rpath链接选项仅在运行时有效 链接时间。以这种方式搜索-rpath仅受本机链接器和 已使用--with sysroot选项配置的交叉链接器

  • 在ELF系统上,对于本机链接器,如果未指定-rpath和-rpath链接选项 使用时,搜索环境变量“LD_RUN_PATH”的内容

  • 在SunOS上,如果未使用-rpath选项,请搜索使用指定的任何目录 -L选项

  • 对于本机链接器,搜索将搜索环境变量的内容 “LD_库_路径”

  • 对于本机ELF链接器,共享链接的“DT_RUNPATH”或“DT_RPATH”中的目录 在库中搜索它所需的共享库。“DT_RPATH”条目为 如果存在“DT_运行路径”条目,则忽略

  • 默认目录,通常为/lib和/usr/lib

  • 对于ELF系统上的本机链接器,如果文件/etc/ld.so.conf存在,则列表 在该文件中找到的目录

    如果未找到所需的共享库,链接器将发出警告并 继续链接

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

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

    说明了LD的顺序:

    在解析共享对象依赖项时,动态链接器首先 检查每个依赖项字符串是否包含斜杠(此 如果创建了包含斜杠的共享对象路径名,则可能发生此情况 在链接时间指定)

    如果找到斜杠,则依赖项 字符串被解释为(相对或绝对)路径名,而 使用该路径名加载共享对象

    如果共享对象依赖项不包含斜杠,则将按以下顺序搜索它:

    • 使用二进制文件(如果存在)的DT_RPATH动态部分属性中指定的目录,并且DT_运行路径属性不存在。不推荐使用DT_RPATH

    • 使用环境变量LD_LIBRARY_PATH(除非可执行文件正在安全执行模式下运行;请参见下文)。在这种情况下,它被忽略

    • 使用二进制文件(如果存在)的DT_运行路径动态部分属性中指定的目录。搜索这些目录只是为了找到DT_NEEDED(直接依赖项)条目所需的对象,而不适用于这些对象的子对象,这些子对象本身必须有自己的DT_运行路径条目。这与DT_RPATH不同,DT_RPATH用于搜索依赖关系树中的所有子级

    • 来自缓存文件/etc/ld.so.cache,其中包含以前在扩展库路径中找到的候选共享对象的编译列表。但是,如果二进制文件与-z nodeflib链接器选项链接,则跳过默认路径中的共享对象。安装在硬件功能目录(见下文)中的共享对象优先于其他共享对象

    • 在默认路径/lib中,然后是/usr/lib。(在某些64位体系结构上,64位共享对象的默认路径是/lib64,然后是/usr/lib64。)如果二进制文件与-z nodeflib链接器选项链接,则跳过此步骤

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

    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)