Linux 什么';动态库搜索ld的规则是什么?

Linux 什么';动态库搜索ld的规则是什么?,linux,gcc,linker,ld,Linux,Gcc,Linker,Ld,Linux将链接器时搜索路径和运行时搜索路径分开 对于运行时搜索路径,我在其 DT_RPATH 环境LD_库_路径 DT_运行路径 ld.so.cache /lib,/usr/lib 但是对于链接器时间搜索路径,ld:( 除了-L选项外,还表示: 搜索的默认路径集(未使用-L指定)取决于ld使用的仿真模式,在某些情况下还取决于其配置方式 还可以使用“SEARCH\u DIR”命令在链接脚本中指定路径。以这种方式指定的目录将在链接器脚本出现在命令行中的位置进行搜索 取决于仿真模式的“默认路径集”是

Linux将链接器时搜索路径和运行时搜索路径分开

对于运行时搜索路径,我在其

  • DT_RPATH
  • 环境LD_库_路径
  • DT_运行路径
  • ld.so.cache
  • /lib,/usr/lib
  • 但是对于链接器时间搜索路径,
    ld
    :(

    除了
    -L
    选项外,还表示:

    搜索的默认路径集(未使用
    -L
    指定)取决于ld使用的仿真模式,在某些情况下还取决于其配置方式

    还可以使用“
    SEARCH\u DIR
    ”命令在链接脚本中指定路径。以这种方式指定的目录将在链接器脚本出现在命令行中的位置进行搜索


    取决于仿真模式的“默认路径集”是否意味着“
    SEARCH\u DIR
    ”?

    说到
    ld
    本身,库路径搜索顺序如下:

  • 通过
    -L
    命令行标志指定的目录
  • 库路径中的目录
    环境变量
  • SEARCH\u DIR
    链接器脚本中的变量
  • 通过运行
    ld--verbose | grep SEARCH_DIR
    可以查看默认链接器脚本中指定的目录。请注意,
    SEARCH_DIR
    中的
    =
    值将被指定的
    --sysroot
    选项的值替换


    通常不会直接调用
    ld
    ,而是通过编译器驱动程序将多个
    -L
    选项传递给链接器。在
    gcc
    clang
    的情况下,您可以通过调用
    -print search dirs
    选项来打印编译器添加的附加库搜索目录。还请注意,如果指定一些特定于机器的编译器标志(如前面提到的-m32)然后,链接器可以根据所选的ELF仿真使用不同的链接器脚本。在
    gcc
    的情况下,您可以使用
    -dumpspecs
    选项查看不同的编译器标志如何影响链接器调用。但是,查找链接器命令行的最简单方法是编译一个简单的程序并将其链接到
    -v,要查找特定ELF仿真的链接器搜索路径,只需运行
    ld-m--verbose | grep search_DIR

    misssprite,在binutils的ld链接器中不搜索
    ld.so
    ld linux.so

    当使用gcc构建动态程序时,它使用ld(collect2)程序的选项
    -dynamic linker

    -Ifile
    -动态链接器=文件

      Set the name of the dynamic linker.  This is only meaningful when
           generating dynamically linked ELF executables.  The default
           dynamic linker is normally correct; don't use this unless you
           know what you are doing.")
    
    通常用作ELF的运行时加载程序,“ld linux.so”在动态ELF文件中注册为解释器,程序头
    INTERP
    .INTERP
    ),检查输出
    readelf-l./dynamic_应用程序
    。据我所知,此字段用于完整路径

    当没有gcc(直接称为'ld'程序)或没有提供此选项时,
    ld
    使用
    ld的完整路径的硬编码字符串。因此
    ;此默认值对于大多数操作系统(包括Linux)是不正确的:

    模板
    常量目标::目标\u信息目标\u x86\u 64::x86\u 64\u信息=
    ...
    “/lib/ld64.so.1”,//程序解释器
    常量目标::目标\u信息目标\u x86\u 64::x86\u 64\u信息=
    ...
    “/libx32/ldx32.so.1”,//程序解释器
    

    正确的动态链接器/加载程序路径是在gcc机器中硬编码的,
    gcc-dumpspecs
    ld-linux命令的grep输出用于
    -dynamic linker
    选项值。

    LIBRARY\u路径对我不起作用。我编辑了这个问题来澄清这个问题。你能更新对这两个问题的响应吗?顺便说一下,我没有提到
    -m32
    。似乎另一个伙伴删除了他的答案。@misssprite,您试图用LIBRARY\u PATH修改的确切命令是什么?我在binutils中的ld sources中没有看到LIBRARY\u PATH的读取:
    ldfile\u add\u LIBRARY\u PATH
    中填充了链接器脚本()的SEARCH\u DIR选项和ld
    -L options
    @osgx,该命令应该是OK的,
    导出库路径=:$LIBRARY\u路径
    。因此src代码还指示库路径不生效。@osgx,我运行
    ld hello.o-ltest-L.
    ld hello.o-ltest
    ,并设置了LIRARY\u路径。前者在pwd中找到了
    libtest.So
    ,而后者没有。@osgx,是的,它是ubuntu gnu ld。正如你之前所说,
    LIBRARY\u PATH
    没有出现在ld源代码中,它不应该生效。这是有意义的。misssprite,什么是“ld”?是“ld.so”,还是“ld linux.so”或“libdl.so”?(ELF动态链接器/加载程序)在动态ELF文件的第…节中注册为解释器,请检查
    readelf-l./dynamic_应用程序
    .PS您使用了哪个手册页,是它还是其他?我指的是GCC中的
    链接器
    ,而不是加载程序。我会编辑它。@OSGxmissprite,您对手册页1 ld的理解不正确,DT_RPATH和其他用于搜索ng动态库(它们被命名为
    libSOMETHING.so
    like
    libc.so
    ),是应用程序所需的,带有动态部分所需的条目(检查
    readelf-d./dynamic\u程序的输出
    )。没有名为
    ld.so
    的动态库。我知道
    ld.so
    是加载程序,而不是.so库。也许您可以帮助我编辑问题以修复任何令人困惑的地方。@osgxdynamic库由动态加载程序ld-linux搜索(在运行时)。如您在问题中所述。以及ld-linux.so路径(在编译+链接过程结束时)在binutils链接器
    ld
    (错误)和gcc(正确,请检查
    gcc-dumpspecs | grep动态链接器
    )中进行硬编码,并从gcc传递到ld(检查我的答案)。规范和ld.so路径在gcc源代码中进行硬编码:&在gcc/confi中
    /* The name of the dynamic interpreter.  This is put in the .interp
       section.  */
    
    #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
    #define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
    
    template<>
    const Target::Target_info Target_x86_64<64>::x86_64_info =
     ...
      "/lib/ld64.so.1",     // program interpreter
    const Target::Target_info Target_x86_64<32>::x86_64_info =
     ...
      "/libx32/ldx32.so.1", // program interpreter