web-dev-qa-db-ja.com

macOS上の実行可能ファイルのrpathを出力します

install_name_toolを使用して実行可能ファイルのrpathを変更したいのですが、現在rpathが何であるかわかりません。 install_name_toolでは、コマンドラインで古いものと新しいものの両方をrpathで指定する必要があります。 macOSで実行可能ファイルのrpathを出力するには、どのコマンドを使用できますか?

66
staticfloat

まず、実行可能ファイルには単一のrpathエントリが含まれず、1つ以上のエントリの配列が含まれることを理解してください。

次に、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エントリの下のパスに注意してください。

86
NSGod

MacOSで共有ライブラリのインストール名を印刷できることがわかりました

otool -D mylib

さらに、-idフラグをinstall_name_toolに渡すことで、古いインストール名を参照せずにインストール名を直接設定できます。

install_name_tool -id @rpath/my/path mylib
3
Amos Joshua

現在、DYLDを処理するためのいくつかのBash-3スクリプトを書いていますが、これが質問に答えているので、参考のために投稿します。

#! /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のトリックを知っている人はいますか?

2
Fravadona

otool -l myexecutableを使用できますが、rpath sのリストのみに関心がある場合、これは多くの不要な情報を出力します。

otool -lの出力を、関連するrpathエントリにフィルターすることができます。

otool -l myexecutable | grep RPATH -A2
2
plasmacel