忽略 rpath 条目的可执行文件

Posted

技术标签:

【中文标题】忽略 rpath 条目的可执行文件【英文标题】:Executable ignoring rpath entry 【发布时间】:2015-04-03 17:33:46 【问题描述】:

我正在尝试创建一个使用一组本地安装的动态库的可执行文件,但是当我尝试运行该程序时出现以下错误:

dyld: Library not loaded: libSDL2-2.0.1.dylib
  Referenced from: /Volumes/OSXData/Users/danielrs/Development/Projects/Test/build/./ClearScreen
  Reason: image not found
Trace/BPT trap: 5

执行命令otool -L ClearScreen 给出:

ClearScreen:
    /Volumes/OSXData/Users/danielrs/Development/Projects/Test/build/DwarfEngine/libDwarf.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
    /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
    libSDL2-2.0.1.dylib (compatibility version 1.0.0, current version 0.2.1)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 21.0.0)
    /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/dependencies/../3rdParty/Darwin/lib/libglfw.3.dylib (compatibility version 3.0.0, current version 3.1.0)
    /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
    /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (compatibility version 1.2.0, current version 1.8.0)
    /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/dependencies/../3rdParty/Darwin//libassimp.3.dylib (compatibility version 3.0.0, current version 3.1.1)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

除 SDL 和 Assimp 之外的所有这些库都是预期的。由于我使用 CMake 的 ExternalProject_Add 构建和安装它们,因此在安装阶段会更改 .dylib 的 install_name。在阅读了很多之后,我发现可执行文件在尝试安装名称指定的位置之前,会在 DYLD_LIBRARY_PATH 中指定的路径中查找其库。因此,我将其设置为指向安装了我的库的文件夹:

export DYLD_LIBRARY_PATH=/Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/3rdParty/Darwin/lib

一切正常!但是,该项目将创建很多可执行文件,我希望他们知道要查找库而不是手动导出 DYLD_LIBRARY_PATH,最好的解决方案是在可执行文件中设置 rpath。我做了以下事情:

# Unset this so they don't override the rpath
unset DYLD_LIBRARY_PATH
unset LD_LIBRARY_PATH
install_name_tool -add_rpath /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/3rdParty/Darwin/lib ClearScreen

但它不起作用。我认为 dyld 在尝试在 .dylib 中安装名称之前查看了 rpath?这是otool -l ClearScreen添加rpath后的输出(LC_RPATH位于末尾):

ClearScreen:
Load command 0
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __PAGEZERO
   vmaddr 0x0000000000000000
   vmsize 0x0000000100000000
  fileoff 0
 filesize 0
  maxprot 0x00000000
 initprot 0x00000000
   nsects 0
    flags 0x0
Load command 1
      cmd LC_SEGMENT_64
  cmdsize 712
  segname __TEXT
   vmaddr 0x0000000100000000
   vmsize 0x0000000000004000
  fileoff 0
 filesize 16384
  maxprot 0x00000007
 initprot 0x00000005
   nsects 8
    flags 0x0
Section
  sectname __text
   segname __TEXT
      addr 0x0000000100003ab0
      size 0x0000000000000369
    offset 15024
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __stubs
   segname __TEXT
      addr 0x0000000100003e1a
      size 0x000000000000005a
    offset 15898
     align 2^1 (2)
    reloff 0
    nreloc 0
     flags 0x80000408
 reserved1 0 (index into indirect symbol table)
 reserved2 6 (size of stubs)
Section
  sectname __stub_helper
   segname __TEXT
      addr 0x0000000100003e74
      size 0x0000000000000092
    offset 15988
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x80000400
 reserved1 0
 reserved2 0
Section
  sectname __const
   segname __TEXT
      addr 0x0000000100003f08
      size 0x000000000000000d
    offset 16136
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __gcc_except_tab
   segname __TEXT
      addr 0x0000000100003f18
      size 0x000000000000002c
    offset 16152
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __cstring
   segname __TEXT
      addr 0x0000000100003f44
      size 0x0000000000000019
    offset 16196
     align 2^0 (1)
    reloff 0
    nreloc 0
     flags 0x00000002
 reserved1 0
 reserved2 0
Section
  sectname __unwind_info
   segname __TEXT
      addr 0x0000000100003f60
      size 0x0000000000000060
    offset 16224
     align 2^2 (4)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Section
  sectname __eh_frame
   segname __TEXT
      addr 0x0000000100003fc0
      size 0x0000000000000038
    offset 16320
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 2
      cmd LC_SEGMENT_64
  cmdsize 392
  segname __DATA
   vmaddr 0x0000000100004000
   vmsize 0x0000000000001000
  fileoff 16384
 filesize 4096
  maxprot 0x00000007
 initprot 0x00000003
   nsects 4
    flags 0x0
Section
  sectname __nl_symbol_ptr
   segname __DATA
      addr 0x0000000100004000
      size 0x0000000000000010
    offset 16384
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 15 (index into indirect symbol table)
 reserved2 0
Section
  sectname __got
   segname __DATA
      addr 0x0000000100004010
      size 0x0000000000000008
    offset 16400
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000006
 reserved1 17 (index into indirect symbol table)
 reserved2 0
Section
  sectname __la_symbol_ptr
   segname __DATA
      addr 0x0000000100004018
      size 0x0000000000000078
    offset 16408
     align 2^3 (8)
    reloff 0
    nreloc 0
     flags 0x00000007
 reserved1 18 (index into indirect symbol table)
 reserved2 0
Section
  sectname __const
   segname __DATA
      addr 0x0000000100004090
      size 0x0000000000000058
    offset 16528
     align 2^4 (16)
    reloff 0
    nreloc 0
     flags 0x00000000
 reserved1 0
 reserved2 0
Load command 3
      cmd LC_SEGMENT_64
  cmdsize 72
  segname __LINKEDIT
   vmaddr 0x0000000100005000
   vmsize 0x0000000000001000
  fileoff 20480
 filesize 2628
  maxprot 0x00000007
 initprot 0x00000001
   nsects 0
    flags 0x0
Load command 4
            cmd LC_DYLD_INFO_ONLY
        cmdsize 48
     rebase_off 20480
    rebase_size 16
       bind_off 20496
      bind_size 216
  weak_bind_off 20712
 weak_bind_size 56
  lazy_bind_off 20768
 lazy_bind_size 400
     export_off 21168
    export_size 208
Load command 5
     cmd LC_SYMTAB
 cmdsize 24
  symoff 21816
   nsyms 30
  stroff 22428
 strsize 680
Load command 6
            cmd LC_DYSYMTAB
        cmdsize 80
      ilocalsym 0
      nlocalsym 3
     iextdefsym 3
     nextdefsym 10
      iundefsym 13
      nundefsym 17
         tocoff 0
           ntoc 0
      modtaboff 0
        nmodtab 0
   extrefsymoff 0
    nextrefsyms 0
 indirectsymoff 22296
  nindirectsyms 33
      extreloff 0
        nextrel 0
      locreloff 0
        nlocrel 0
Load command 7
          cmd LC_LOAD_DYLINKER
      cmdsize 32
         name /usr/lib/dyld (offset 12)
Load command 8
     cmd LC_UUID
 cmdsize 24
    uuid 967CAC7D-945E-3767-89AD-7BF4D62D0903
Load command 9
      cmd LC_VERSION_MIN_MACOSX
  cmdsize 16
  version 10.10
      sdk 10.10
Load command 10
      cmd LC_SOURCE_VERSION
  cmdsize 16
  version 0.0
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 15392
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 120
         name /Volumes/OSXData/Users/danielrs/Development/Projects/Test/build/DwarfEngine/libDwarf.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 0.0.0
compatibility version 0.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 80
         name /System/Library/Frameworks/AGL.framework/Versions/A/AGL (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 1.0.0
compatibility version 1.0.0
Load command 14
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 1.0.0
compatibility version 1.0.0
Load command 15
          cmd LC_LOAD_DYLIB
      cmdsize 48
         name libSDL2-2.0.1.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 0.2.1
compatibility version 1.0.0
Load command 16
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 21.0.0
compatibility version 1.0.0
Load command 17
          cmd LC_LOAD_DYLIB
      cmdsize 152
         name /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/dependencies/../3rdParty/Darwin/lib/libglfw.3.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 3.1.0
compatibility version 3.0.0
Load command 18
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 275.0.0
compatibility version 1.0.0
Load command 19
          cmd LC_LOAD_DYLIB
      cmdsize 96
         name /System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 1.8.0
compatibility version 1.2.0
Load command 20
          cmd LC_LOAD_DYLIB
      cmdsize 152
         name /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/dependencies/../3rdParty/Darwin//libassimp.3.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 3.1.1
compatibility version 3.0.0
Load command 21
          cmd LC_LOAD_DYLIB
      cmdsize 48
         name /usr/lib/libc++.1.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 120.0.0
compatibility version 1.0.0
Load command 22
          cmd LC_LOAD_DYLIB
      cmdsize 56
         name /usr/lib/libSystem.B.dylib (offset 24)
   time stamp 2 Wed Dec 31 20:00:02 1969
      current version 1213.0.0
compatibility version 1.0.0
Load command 23
      cmd LC_FUNCTION_STARTS
  cmdsize 16
  dataoff 21376
 datasize 16
Load command 24
      cmd LC_DATA_IN_CODE
  cmdsize 16
  dataoff 21392
 datasize 0
Load command 25
      cmd LC_DYLIB_CODE_SIGN_DRS
  cmdsize 16
  dataoff 21392
 datasize 424
Load command 26
          cmd LC_RPATH
      cmdsize 104
         path /Volumes/OSXData/Users/danielrs/Development/Projects/Test/DwarfEngine/3rdParty/Darwin/lib (offset 12)

【问题讨论】:

【参考方案1】:

在使用-add-rpath 设置LC_RPATH 后,您仍必须将@rpath 变量添加到重定位的库路径中。该变量将替换为添加的 rpath 值。

install_name_tool -change libSDL2-2.0.1.dylib @rpath/libSDL2-2.0.1.dylib ClearScreen

对于-change 选项,您需要提供两个参数:old_pathnew_pathold_path 必须正是您从 otool -L 获得的内容。

您会在cmake wiki 中找到一些有用的信息。

【讨论】:

它有效,谢谢!可悲的是,没有简单的方法可以自动进行此更改,对吗?使用 CMake,我尝试在添加 SDL 时将参数 -DCMAKE_INSTALL_RPATH='@rpath/lib' 传递给 ExternalProject_Add 中的 CMAKE_ARGS 您可以提出有关如何使用 cmake 正确设置 rpath 的新问题。当路径像现在这样被破坏时,您只能编写一个脚本来自动修复它。 This script 可能会给你带来灵感。 那个脚本很完美!继续加油!

以上是关于忽略 rpath 条目的可执行文件的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用 .gitignore 忽略特定的可执行文件?

如何在 Mac OSX 下使用 gcc 设置可执行文件的运行时路径(-rpath)?

为啥 ld 在将可执行文件链接到 a 时需要 -rpath-link 以便需要另一个 so ?

使用rpath解决指定动态库链接目录问题

UBUNTU 8.04的可执行文件后缀是啥??

-Wl,-rpath=