Dynamic library file dependency modification tool chrpath, install_name_tool

    A useful thing when deploying different versions of the program. mark it.

    chrpath is a tool that removes dead-write dependencies.

 

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 Update

=============================================

#################################
#   Linux
#################################
# delete hard-coded rpath
chrpath -d lib*.so*
# Specify the search path
LD_LIBRARY_PAT

 

########################
# MAC OS X
########################

install_name_tool old new dylib

# old is the old absolute path of a dependent library
# new is the new absolute or relative path of a dependency library.
# available (@executable_path, @loader_path and @rpath)
 
https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/dyld.1.html writes
@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
    be
}

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
 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327082411&siteId=291194637