実行可能ファイルの動的ローダを設定できますか?

実行可能ファイルの動的ローダを設定できますか?

実行可能ファイルが共有ライブラリを見つけることを許可する方法を探していますが、同じ共有ライブラリの異なるバージョンを使用できるパッケージとの競合を避けるために、これらのライブラリを「プライベートパス」の代わりに保持することをお勧めします。 /usr/lib)。

可能な方法は次のとおりです。

  • 実行可能ファイルにrpathを含める
  • 実行ファイルの起動時にLD_LIBRARY_PATHを設定します。
  • ld.so.conf.d ファイルの ldconfig 構成にライブラリー・パスを追加します。

rpath はターゲット構造をビルドに接続し、ld.so.conf.d はシステムパスを構成し、LD_LIBRARY_PATH は呼び出し側プロセスがそれを知る必要があります。

その場合は、実行可能ファイルにのみ適用されるld.so.conf.d(または同様のローダー構成)を使用できるかどうか疑問に思います。

答え1

簡単なことではありません。ld.so.confファイル形式は非常に簡単です。ただパスのリストです。

さまざまな方法で実行可能ファイルを構築すると、いくつかのことができます。通訳;一般的な値は/lib64/ld-linux-x86-64.so.21に等しく、実際に動的接続を実行します。したがって、カスタムダイナミックリンカーは異なるように見えたり、ld.so.conf何でもすることができます。しかし、これはrpathよりはるかに悪いようです!

より簡単な解決策はラッパーです。バイナリをでインストールするprogram.realか、他の場所にインストールする方が良いです/usr/local/lib/(例ではありません$PATH)。次に、単純なシェルスクリプトを入力します/usr/local/bin/program

#!/bin/sh
export LD_LIBRARY_PATH=/path/to/libs
exec /usr/local/lib/program/program.real

ライブラリの場所はビルドとは関係ありませんが、呼び出し側はこれについて知る必要はありません。




1:システムで一般的に見つかる項目を見つけるためのクイック方法:readelf /bin/bash -p .interp。いくつかの異なる実行可能ファイルを試してみると、少なくとも32ビットプログラムと64ビットプログラムが異なるプログラムを使用していることがわかります。

答え2

相対rpathを使用できます$ORIGIN

-Wl,-rpath,'$ORIGIN/../lib'実行可能ファイルがインストールを検索できるようにするライブラリに実行可能ファイルをリンクします。

  • 実行可能ファイルは次の場所にあります。<base>/bin/
  • 共有図書館の場所は次のとおりです。<base>/lib/

これにより、実行可能ファイルに対してのみこのリンクを構成でき、ディレクトリ<base>はどこにでも配置できます。

答え3

filename引数はdlopen絶対パス(/""で始まる)です。

したがって、「プライベートパス」は設定ファイルに保存され、ライブラリのフルネームはこのファイルから構築されます。または、プライベートライブラリが実行可能ファイルと同じディレクトリにあることがわかっている場合は、実行可能ファイルパスで単純な文字列操作を実行して検索します。

#include <dlfcn.h>
#include <unistd.h>
#include <string.h>

static int (*foo)();

/* ... */
char buf[BUFSIZ];
char *lastslash;
void *handle;

realpath(argv[0],buf);
lastslash = strrchr(buf,'/');
strcpy(lastslash,"foo." VERSION_BUILD ".so");
dlopen(buf,RTLD_LOCAL | RTLD_LAZY);
*(void **)(&foo) = dlsym(handle, "foo");

/* ... */
printf("%d\n",foo());

関連情報