`
chenqi210
  • 浏览: 76769 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

动态库文件依赖修改工具 chrpath, install_name_tool

 
阅读更多

    部署不同版本程序时比较有用的一个东西。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.
 
#!/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
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics