忽略 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_path
和new_path
。 old_path
必须正是您从 otool -L
获得的内容。
您会在cmake wiki 中找到一些有用的信息。
【讨论】:
它有效,谢谢!可悲的是,没有简单的方法可以自动进行此更改,对吗?使用 CMake,我尝试在添加 SDL 时将参数-DCMAKE_INSTALL_RPATH='@rpath/lib'
传递给 ExternalProject_Add 中的 CMAKE_ARGS
您可以提出有关如何使用 cmake 正确设置 rpath 的新问题。当路径像现在这样被破坏时,您只能编写一个脚本来自动修复它。 This script 可能会给你带来灵感。
那个脚本很完美!继续加油!以上是关于忽略 rpath 条目的可执行文件的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Mac OSX 下使用 gcc 设置可执行文件的运行时路径(-rpath)?