web-dev-qa-db-ja.com

実行パス、検索パス、およびインストール名を適切に設定するにはどうすればよいですか?

ダイナミックライブラリとしてコンパイルしているプロジェクトのコレクションがあります。これらの各.dylibは、他のさまざまなディレクトリに配置したい他のさまざまな.dylibに依存しています(つまり、実行可能パス、ローダーパス、固定パスにあります)。

コンパイルされたライブラリでotool -Lを実行すると、それらの依存関係へのパスのリストが表示されますが、これらのパスがどのように設定/決定されているかはわかっています。それらはほとんど疑似ランダムに見えます。 Xcodeの「ビルド設定」をいじってこれらのパス(@ rpath、@ executeable_path、@ loader_pathなど)を変更しようと何時間も費やしましたが、何も変更できないようです(otool -Lを実行して確認しました)。 )。私はこれらのフラグをどこに追加するかさえ完全にはわかりませんし、以下の違いやそれらを適切に使用する方法を本当に理解していません:

リンク-「ダイナミックライブラリインストール名」
リンク-「RunpathSearchPaths」
リンク-「その他のリンクフラグ」
検索パス-「ライブラリ検索パス」

さまざまなライブラリでinstall_name_tool -changeを実行すると、実行パスの検索パスを正常に変更できます(これも、otool -Lを実行して確認することで確認できます)。

私はXcode4.2を実行していますが、諦めかけ、install_tool_nameを実行して変更を加えるビルド後のスクリプトを使用しています。しかし、それはクラッジハックの修正であり、私はそれをしたくないです。

Dylib依存関係の検索/実行パスがどのように設定されているかはどこで確認できますか?
私が間違っているかもしれないことについて誰かが何か考えを持っていますか?

13
BigMacAttack

通常、dylibのターゲットでは、_INSTALL_PATH_別名「インストールディレクトリ」を必要なプレフィックスに設定します(例:_@executable_path/../Frameworks_)。

_LD_DYLIB_INSTALL_NAME_別名「ダイナミックライブラリインストール名」をデフォルト値である$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)に設定したままにします。

Xcodeはターゲットの名前に基づいてそれを拡張するため、たとえば_@executable_path/../Frameworks/MyFramework.framework/Versions/A/MyFramework_になる可能性があります。

理解しておくべき重要なことは、ビルドプロセスの一部として、インストールパスが組み込み dylibであることです。後で、A.dylibを参照するB.dylibをリンクすると、A.dylibのインストールパスはコピー先 B.dylibになります。 (これがotoolが示しているものです。コピーされたインストールパスです。)したがって、最初に正しいインストールパスをdylibに組み込むのが最善です。

すべてのdylibを一緒に機能させる前に、それぞれを個別に確認してください。それをビルドしてから、ビルドされたdylibで_otool -L_。各アーキテクチャの最初の行は、_LD_DYLIB_INSTALL_NAME_が示していたものである必要があります。

それを整理したら、dylibを相互にリンクさせてみてください。それははるかに簡単なはずです。

12
Kurt Revis

install_name_toolは、名前とパスを設定するのに非常に便利です。プログラムがビルドディレクトリでセルフテストを実行し、make installの間に状況が変化する場合に特に便利です。この場合、個別のビルドを必要とせずにinstall_name_toolを使用できます。

install_name_toolは、AppleのLDがLinux/GCCのようにrpathリンカーオプションを尊重しないため、便利です。つまり、次のコマンドの異なるセットを使用する必要があります。それらを設定します。

これがそのマニュアルページです。 -headerpad_max_install_namesなどの他のオプションについて説明しているため、全体に含まれています。

INSTALL_NAME_TOOL(1)                                      INSTALL_NAME_TOOL(1)

NAME
       install_name_tool - change dynamic shared library install names

SYNOPSIS
       install_name_tool  [-change  old  new  ]  ...  [-rpath  old  new  ] ...
       [-add_rpath new ] ... [-delete_rpath new ] ... [-id name] file

DESCRIPTION
       Install_name_tool changes the dynamic shared library install names  and
       or  adds,  changes  or  deletes the rpaths recorded in a Mach-O binary.
       For this tool to work when the install names or rpaths are  larger  the
       binary  should  be  built  with  the ld(1) -headerpad_max_install_names
       option.

       -change old new
              Changes the dependent shared library install name old to new  in
              the specified Mach-O binary.  More than one of these options can
              be specified.  If the Mach-O binary does  not  contain  the  old
              install  name  in  a  specified  -change  option  the  option is
              ignored.

       -id name
              Changes the shared library  identification  name  of  a  dynamic
              shared  library  to name.  If the Mach-O binary is not a dynamic
              shared library and the -id option is specified it is ignored.

       -rpath old new
              Changes the rpath path name old to new in the  specified  Mach-O
              binary.   More  than  one of these options can be specified.  If
              the Mach-O binary does not contain the old rpath path name in  a
              specified -rpath it is an error.

       -add_rpath new
              Adds  the  rpath  path  name new in the specified Mach-O binary.
              More than one of these options can be specified.  If the  Mach-O
              binary  already  contains  the  new rpath path name specified in
              -add_rpath it is an error.

       -delete_rpath old
              deletes the rpath path name old in the specified Mach-O  binary.
              More  than one of these options can be specified.  If the Mach-O
              binary does not contains the old rpath path  name  specified  in
              -delete_rpath it is an error.

SEE ALSO
       ld(1)
2
jww