コンパイル済みのバイナリで「rpath」を変更できますか?


92

スクラップヒープ用にスケジュールされている古い実行可能ファイルがありますが、まだありません。それは私の環境から削除されたいくつかのライブラリに依存していますが、私はそれがうまく機能する場所にいくつかのスタブライブラリを持っています。この実行可能ファイルがこれらのスタブライブラリを指すようにしたいと思います。はい、LD_LIBRARY_PATHを設定できますが、この実行可能ファイルは多くのスクリプトから呼び出されます。多くのユーザーがいるため、1つの場所で修正したいと思います。

私にはこれのソースがなく、入手するのは難しいでしょう。私は考えていました-ELF対応エディターを使用してこのファイルを編集し、rpathに単純なPATHを追加して、新しいライブラリにヒットさせることができますか?これは可能ですか、またはELFバイナリを作成すると、場所に固定して移動できなくなりますか?


3
LD_LIBRARY_PATHを設定してバイナリを呼び出すシェルスクリプトにラップします。呼び出し元のPATHにある場所にシェルスクリプトを配置します。
wildplasser

LD_LIBRARY_PATHは子プロセスに継承されます。あなたはそれを望まないかもしれません。
ウィル

1
@そうそう、私はすでにそれをしたくないと言った。:)
Rich Homolka 2016

回答:


78

chrpathこれを行うことができると呼ばれるツールがあります-それはおそらくあなたのディストリビューションのパッケージで利用可能です。


9
Macユーザー向けのメモです。フラグをinstall_name_tool使用してこれを実行できます-rpath
Kevin Tonon

10
あなたがエラーを取得する場合:<binary>: no rpath or runpath tag found.、あなたが使用することはできませんchrpath、それを置き換えるために、しかし、あなたが使用することができpatchelf、この場合には:patchelf --set-rpath /path/to/libaries <binary>
phyatt

もっと一般的ですが、patchelfにはライブラリ/実行可能ファイルのサイズを劇的に増大させる長年のバグがあるため、できればchrpathを選択します。
taranaki 2019年

157

chrpath呼ばれるよりもより普遍的なツールがありpatchelfます。もともとはNixとNixOS(パッケージングシステムとGNU / Linuxディストリビューション)のパッケージを作成するために作成されました。

バイナリ(ここではrdsampと呼ばれます)にrpathがない場合、chrpath失敗します。

chrpath -r '$ORIGIN/../lib64' rdsamp 
rdsamp: no rpath or runpath tag found.

一方、

patchelf --set-rpath '$ORIGIN/../lib64' rdsamp

うまくいきます。


9
特に、patchelfrpathを含まないバイナリにrpathを追加することはできchrpathますが、すでに存在するエントリを変更することしかできないようです。
maxschlepzig 2014

4
一般的な注意として、との微妙な違いを理解することは価値がrpathありrunpathます。基本的に、1つはオーバーライドでき、もう1つはオーバーライドLD_LIBRARY_PATHできません。詳細については、を参照してくださいblog.tremily.us/posts/rpath
スチュアート・ベルク

6
迷惑な事は、両方のことですchrpathし、patchelfその用語にずさんです。たとえば、上記のpatchelfコマンドは変更されますrunpathrpath--force-rpathオプションも指定しない限り変更されません。
スチュアートバーグ

10
@superbatfishはい。ただし、通常、違いは問題ではありません。のCHANGELOGからのこのエントリは、patchelfそれを説明します: " --set-rpath--shrink-rpathそして--print-rpath今では廃止されたを優先 DT_RUNPATHDT_RPATHます。更新時に両方が存在する場合は、両方が更新されます。DT_RPATHのみが存在するDT_RUNPATH場合--force-rpathは、指定されない限り変換されます。どちらも存在しない場合、a DT_RUNPATH--force-rpath指定されていない限り、a が追加DT_RPATHされます。互換性の理由から、オプションの名前はおそらく変更されていません。
user7610 14

2
これまでのところ最良の答えは、これが代わりに受け入れられる答えであるはずです!
Kenneth Hoste 2016年

12

@ user7610が言ったように、正しい方法はpatchelfツールです。

しかし、私はそれを実行するために必要なすべてのコマンドをカバーして、より包括的な答えを出すことができると感じています。

このテーマに関する包括的な記事については、ここをクリックしてください

まず第一に、多くの開発者が話しますRPATHが、実際にはを意味しRUNPATHます。これらは2つの異なるオプションの動的セクションであり、ローダーはそれらを非常に異なる方法で処理します。これらの違いの詳細については、前述のリンクを参照してください。

とりあえず、覚えておいてください。

  • RUNPATH設定されている場合、RPATH無視されます
  • RPATH 非推奨であり、回避する必要があります
  • RUNPATH によって上書きできるため、 LD_LIBRARY_PATH

現在のR [UN] PATHを確認する

readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"

R [UN] PATHをクリアする

patchelf --remove-rpath <path-to-elf>

ノート:

  • 両方RPATHを削除し、RUNPATH

R [UN] PATHに値を追加します

patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>

ノート:

  • <desired-path> カンマ区切りのディレクトリリストです。例: /my/libs:/my/other/libs
  • を指定した場合は--force-rpath、を設定しますRPATH。それ以外の場合は、RUNPATH

1
-Wl,-R,<desired-rpath> -Wl,--enable-new-dtagssets DT_RUNPATH、そしてそれはほとんどの人が使うべきものです。RUNPATHによってオーバーライドされる可能性があるLD_LIBRARY_PATHため、ユーザーはを使用しないでください--force-rpath
jww

@jww RPATHの廃止に関するコメントを追加しなかったので、今すぐ追加しました。ありがとう!
Daniel Trugman

この例で<desired-path>はコロンを使用していることに注意してください。それはコンマでなければなりません(つまり:)/my/libs,/my/other/libs
Alan De Smet

@AlanDeSmet、私はコンマについて知りませんが、コロンは私のために働きます。
Daniel Trugman

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.