部署不同版本程序时比较有用的一个东西。mark一下。
chrpath 这个工具可以将写死的依赖去掉.
Usage: chrpath [-v|-d|-c|-r <path>] <program> [<program> ...] -v|--version Display program version number -d|--delete Delete current rpath/runpath setting -c|--convert Convert rpath to runpath -r <path>|--replace <path> Replace current rpath/runpath setting with the path given -l|--list List the current rpath/runpath (default) -h|--help Show this usage information.
=============================================
2017-03-16 更新
=============================================
################################# # Linux ################################# # 删除写死的rpath chrpath -d lib*.so* # 指定查找路径 LD_LIBRARY_PAT
######################## # MAC OS X ######################## install_name_tool old new dylib # old 是某依赖库的旧的绝对路径 # new 是某依赖库新的的绝对或相对路径. # 可以用(@executable_path, @loader_path 和 @rpath)
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/dyld.1.html 写道
@executable_path/
This variable is replaced with the path to the directory containing the main executable for
the process. This is useful for loading dylibs/frameworks embedded in a .app directory. If
the main executable file is at /some/path/My.app/Contents/MacOS/My and a framework dylib file
is at /some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo, then the framework
load path could be encoded as @executable_path/../Frameworks/Foo.framework/Versions/A/Foo and
the .app directory could be moved around in the file system and dyld will still be able to
load the embedded framework.
@loader_path/
This variable is replaced with the path to the directory containing the mach-o binary which
contains the load command using @loader_path. Thus, in every binary, @loader_path resolves to
a different path, whereas @executable_path always resolves to the same path. @loader_path is
useful as the load path for a framework/dylib embedded in a plug-in, if the final file system
location of the plugin-in unknown (so absolute paths cannot be used) or if the plug-in is used
by multiple applications (so @executable_path cannot be used). If the plug-in mach-o file is
at /some/path/Myfilter.plugin/Contents/MacOS/Myfilter and a framework dylib file is at
/some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo, then the frame-work framework
work load path could be encoded as @loader_path/../Frameworks/Foo.framework/Versions/A/Foo and
the Myfilter.plugin directory could be moved around in the file system and dyld will still be
able to load the embedded framework.
@rpath/
Dyld maintains a current stack of paths called the run path list. When @rpath is encountered
it is substituted with each path in the run path list until a loadable dylib if found. The
run path stack is built from the LC_RPATH load commands in the depencency chain that lead to
the current dylib load. You can add an LC_RPATH load command to an image with the -rpath
option to ld(1). You can even add a LC_RPATH load command path that starts with
@loader_path/, and it will push a path on the run path stack that relative to the image con-taining containing
taining the LC_RPATH. The use of @rpath is most useful when you have a complex directory
structure of programs and dylibs which can be installed anywhere, but keep their relative
positions. This scenario could be implemented using @loader_path, but every client of a dylib
could need a different load path because its relative position in the file system is differ-ent. different.
ent. The use of @rpath introduces a level of indirection that simplies things. You pick a
location in your directory structure as an anchor point. Each dylib then gets an install path
that starts with @rpath and is the path to the dylib relative to the anchor point. Each main
executable is linked with -rpath @loader_path/zzz, where zzz is the path from the executable
to the anchor point. At runtime dyld sets it run path to be the anchor point, then each dylib
is found relative to the anchor point.
This variable is replaced with the path to the directory containing the main executable for
the process. This is useful for loading dylibs/frameworks embedded in a .app directory. If
the main executable file is at /some/path/My.app/Contents/MacOS/My and a framework dylib file
is at /some/path/My.app/Contents/Frameworks/Foo.framework/Versions/A/Foo, then the framework
load path could be encoded as @executable_path/../Frameworks/Foo.framework/Versions/A/Foo and
the .app directory could be moved around in the file system and dyld will still be able to
load the embedded framework.
@loader_path/
This variable is replaced with the path to the directory containing the mach-o binary which
contains the load command using @loader_path. Thus, in every binary, @loader_path resolves to
a different path, whereas @executable_path always resolves to the same path. @loader_path is
useful as the load path for a framework/dylib embedded in a plug-in, if the final file system
location of the plugin-in unknown (so absolute paths cannot be used) or if the plug-in is used
by multiple applications (so @executable_path cannot be used). If the plug-in mach-o file is
at /some/path/Myfilter.plugin/Contents/MacOS/Myfilter and a framework dylib file is at
/some/path/Myfilter.plugin/Contents/Frameworks/Foo.framework/Versions/A/Foo, then the frame-work framework
work load path could be encoded as @loader_path/../Frameworks/Foo.framework/Versions/A/Foo and
the Myfilter.plugin directory could be moved around in the file system and dyld will still be
able to load the embedded framework.
@rpath/
Dyld maintains a current stack of paths called the run path list. When @rpath is encountered
it is substituted with each path in the run path list until a loadable dylib if found. The
run path stack is built from the LC_RPATH load commands in the depencency chain that lead to
the current dylib load. You can add an LC_RPATH load command to an image with the -rpath
option to ld(1). You can even add a LC_RPATH load command path that starts with
@loader_path/, and it will push a path on the run path stack that relative to the image con-taining containing
taining the LC_RPATH. The use of @rpath is most useful when you have a complex directory
structure of programs and dylibs which can be installed anywhere, but keep their relative
positions. This scenario could be implemented using @loader_path, but every client of a dylib
could need a different load path because its relative position in the file system is differ-ent. different.
ent. The use of @rpath introduces a level of indirection that simplies things. You pick a
location in your directory structure as an anchor point. Each dylib then gets an install path
that starts with @rpath and is the path to the dylib relative to the anchor point. Each main
executable is linked with -rpath @loader_path/zzz, where zzz is the path from the executable
to the anchor point. At runtime dyld sets it run path to be the anchor point, then each dylib
is found relative to the anchor point.
#!/usr/bin/env bash LIBDIR="$(pwd)/x86_64-apple-darwin16.4.0" function copyLibraries() { cp -a lib*.dylib* ${LIBDIR}/ } function makeRelativeDyLibs() { local location=${1} local dylib="" local absPath="" if pushd ${location} > /dev/null; then absPath=$(pwd) for dylib in $(ls *.dylib*) do makeRelativeDyLib ${absPath}/${dylib} done popd > /dev/null fi } function makeRelativeDyLib() { local dylib=${1} local dependency echo "Make ${dylib} use relative dependencies" for dependency in $(otool -L ${dylib} | grep '^\s\+\/Users.*(compatibility version.*)' | sed -e 's/ (compatibility version.*)//g') do install_name_tool -change ${dependency} @loader_path/$(basename ${dependency}) ${dylib} done } function main() { copyLibraries makeRelativeDyLibs ${LIBDIR} } main