在macOS上打印可执行文件的rpath


75

我想使用来更改可执行文件的rpathinstall_name_tool,但我现在无法弄清rpath是什么。install_name_tool要求在命令行上同时提供旧的rpath和新的rpath。在macOS下可以使用什么命令来打印可执行文件的rpath

Answers:


99

首先,了解可执行文件不包含单个rpath条目,而是包含一个或多个条目的数组。

其次,您可以otool用来列出图像的rpath条目。使用otool -l,您将获得类似以下的输出,最后是rpath条目:

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)

查找LC_RPATH命令并记下path条目下的路径。


8
什么@loader_path
nn0p

3
@ nn0p我发现本文有助于理解loader_path。
凯文·奥尔瑞

1
我在otool -l输出中看不到LC_RPATH,但是在LC_ID_DYLIB cmd条目后面的名称字段下确实看到了安装名称
Amos Joshua

10

您可以使用otool -l myexecutable,但是如果您只对rpath列表感兴趣,则会打印出许多不必要的信息。

您可以通过以下方式过滤输出otool -l到相关的rpath条目:

otool -l myexecutable | grep RPATH -A2

5

我发现我可以使用以下命令在macOS上打印共享库的安装名称

otool -D mylib

此外,我可以通过将-id标志传递给来直接设置安装名称,而无需参考旧的安装名称install_name_tool

install_name_tool -id @rpath/my/path mylib

2

我目前正在编写一些Bash-3脚本来处理DYLD,这个脚本回答了这个问题,因此我将其发布以供参考:

#! /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

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

'希望能帮助到你 ;-)

注意:有谁知道一些Bash-3技巧可用于此脚本?


这不是Bash-3特有的技巧,但我建议在每个脚本的顶部写一个注释,说明其功能。必须阅读代码来找出存在工具的原因并不理想。
巴里·琼斯

-1

我只是用otool命令

otool -l <my executable>

它打印出rpath字段。不需要任何长脚本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.