1. ホーム
  2. macos

[解決済み] macOSで実行ファイルのrpathを表示する

2023-07-24 04:48:46

質問

私は rpath を使って実行ファイルの install_name_tool を使用しているのですが、その rpath が今現在 install_name_tool は、古いものと新しいものの両方が必要です。 rpath をコマンドラインで指定する必要があります。どのようなコマンドを使用すれば rpath を表示するには、どのようなコマンドを使用すればよいですか?

どのように解決するのですか?

まず第一に、実行ファイルには単一の 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 のエントリの下にあるパスを記録してください。

EDIT: 何に関して @loader_path は何かというと、フレームワークのロードを行いたいMach-Oオブジェクトを参照するための一般的かつ動的な方法です。

これはかなり作為的な例ですが、私はそれがポイントを理解するべきだと思います。例えば、あるアプリ MyApp.app があり、フレームワーク MyFramework.framework . また、正しく機能するために、私のアプリは/Applicationsにインストールされ、他のどこにもインストールされないことを要求するとします。したがって、当該アプリとフレームワークの構造は、次のようになります。

/Applications/MyApp.app/Contents/MacOS/MyApp (実行ファイル) /Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/MyFramework (Mach-O dylib)

もし、私たちが otool -L (大文字のLに注意)を実行すると、MyFrameworkに関して次のように表示されるでしょう。

@rpath/MyFramework.framework/Versions/A/MyFramework
/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
/usr/lib/libobjc.A.dylib
/usr/lib/libSystem.B.dylib
....

MyFramework.frameworkでは、"MyFramework.framework "という名前の下に @rpath インストール名/パスを使うので、ランタイムサーチパスのエントリが必要で、それは @rpath の代わりに使われる実行時検索パスが必要です。今なら、1つのrpathのエントリを持つことができます。

/Applications/MyApp.app/Contents/Frameworks

これでうまくいき、実行時に2つのパーツが一緒になります。

/Applications/MyApp.app/Contents/Frameworks + /MyFramework.framework/Versions/A/MyFramework ==

/Applications/MyApp.app/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework

アプリを別のフォルダーに移動したり、アプリ自体の名前を変更したりするだけで、リンクに失敗してしまうからです。

@loader_path は、ファイル システム上のどこにでも存在するアプリの実行ファイルを参照するための動的な方法です。このケースでは、実行時に実行ファイルへのパスが入力されます。 /Applications/MyApp.app/Contents/MacOS/MyApp . それから、MyFramework.frameworkを見つけるために、単にディレクトリに移動し、そして Frameworks .