Print rpath of an executable on macOS

2019-01-10 16:20发布

I want to change the rpath of an executable using install_name_tool, but I can't figure out what the rpath is right now. install_name_tool requires both the old and the new rpath's to be given on the commandline. What command can I use to print the rpath of an executable under macOS?

5条回答
我命由我不由天
2楼-- · 2019-01-10 16:51

I found that I can print the install name of a shared library on macOS using

otool -D mylib

Moreover, I can set the install name directly without reference to the old install name by passing the -id flag to install_name_tool:

install_name_tool -id @rpath/my/path mylib
查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-01-10 17:00

I just use otool command

otool -l <my executable>

It prints out the rpath field. No need for any long scripts.

查看更多
Explosion°爆炸
4楼-- · 2019-01-10 17:07

I'm currently writing several Bash-3 scripts for processing DYLD and this one answers the question, so I post it for reference :

#! /bin/bash

# ######################################################################### #

if [ ${#} -eq 0 ]
then
    echo "
Usage: ${0##*/} FILE...

List rpaths in FILEs
"    
    exit 0
fi

# ######################################################################### #

shopt -s extglob

# ######################################################################### #

for file in "${@}"
do
    if [ ! -r "${file}" ]
    then
        echo "${file}: no such file" 1>&2
        continue
    fi

    if ! [[ "$(/usr/bin/file "${file}")" =~ ^${file}:\ *Mach-O\ .*$ ]]
    then
        echo "${file}: is not an object file" 1>&2
        continue
    fi

    if [ ${#} -gt 1 ]
     then
         echo "${file}:"
    fi

    IFS_save="${IFS}"
    IFS=$'\n'

    _next_path_is_rpath=

    while read line
    do
        case "${line}" in
            *(\ )cmd\ LC_RPATH)
                _next_path_is_rpath=yes
                ;;
            *(\ )path\ *\ \(offset\ +([0-9])\))
                if [ -z "${_next_path_is_rpath}" ]
                then
                    continue
                fi
                line="${line#* path }"
                line="${line% (offset *}"
                if [ ${#} -gt 1 ]
                then
                    line=$'\t'"${line}"
                fi
                echo "${line}"
                _next_path_is_rpath=
                ;;
        esac
    done < <(/usr/bin/otool -l "${file}")

    IFS="${IFS_save}"
done

# ######################################################################### #

'hope it helps ;-)

NB: Does anyone know some Bash-3 tricks that can be useful for this script ?

查看更多
叼着烟拽天下
5楼-- · 2019-01-10 17:12

You can use otool -l myexecutable, but this prints a lot of unnecessary information if you are interested only in the list of rpaths.

You can filter the output of otool -l to the relevant rpath entries by

otool -l myexecutable | grep RPATH -A2
查看更多
做自己的国王
6楼-- · 2019-01-10 17:16

First of all, understand that an executable doesn't contain a single rpath entry, but an array of one or more entries.

Second, you can use otool to list an image's rpath entries. Using otool -l, you'll get output like the following, at the very end of which are the rpath entries:

Load command 34
          cmd LC_LOAD_DYLIB
      cmdsize 88
         name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24)
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 1038.32.0
compatibility version 45.0.0

Load command 35
          cmd LC_RPATH
      cmdsize 40
         path @loader_path/../Frameworks (offset 12)

Look for the LC_RPATH commands and note the path under the path entry.

查看更多
登录 后发表回答