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?
问题:
回答1:
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.
回答2:
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 ?
回答3:
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
回答4:
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
回答5:
I just use otool command
otool -l <my executable>
It prints out the rpath field. No need for any long scripts.