1. 概要

このチュートリアルでは、Linuxマシンで複数のglibcライブラリを使用する方法について説明します。 まず、複数のライブラリが存在する可能性と、ライブラリで発生する可能性のある問題について説明します。 次に、同じマシンでglibcの複数のバージョンを使用するいくつかの方法を見ていきます。

2. Linux上の共有ライブラリのさまざまなバージョン

Linuxマシンに同じ共有ライブラリの複数のバージョンをインストールすることができます。 リンカは、プログラムのコンパイル中に、ライブラリの特定のバージョンにリンクするソフトリンクを探します。 たとえば、 glibc の場合、 / usr/libディレクトリの下のlibglib-2.0.soリンクは特定のバージョンのglibcを指します。

Linuxでは、共有ライブラリに名前を付けるための規則はlibです。 。それで。 規則の変数には、さまざまな意味があります。

  • name は共有オブジェクト(共有ライブラリ)のファイル名です
  • major はライブラリのAPIバージョンです—メジャーアップグレードは後方互換性を導入する可能性があります
  • minor は、APIバージョンのマイナーバージョンであり、新機能を示します
  • patch は、バグのパッチを示します

したがって、ある意味で、マシン上に glibc の複数のバージョンを持ち、特定のバージョンへのlibglib-2.0.soリンクを持つことができます。 リンカは、共有オブジェクトでsonameフィールドを探し、結果のバイナリに埋め込みます。 sonameフィールドは、ターゲット共有ライブラリのファイル名を指定します。 したがって、実行時に、ダイナミックリンカはで指定された共有ライブラリを探します。 soname 分野。

そのため、プログラムではさまざまなglibcバージョンを使用できます。 このアプローチの1つの注意点は、プログラムで同じライブラリの複数のバージョンを同時に使用できないことです。それでも、同じライブラリの異なるバージョンが絶対に必要な場合は、静的リンクを使用できます。 。

3. 別のglibcg++に指定する

glibc は、プログラムでリンクできるスタンドアロンファイルではありません。 それは他の多くのモジュールに依存します。 その1つがld-linuxです。 ldツールまたはリンケージエディタは、複数のオブジェクトファイルとその他のリソースを1つの出力ファイルに結合するヘルパーユーティリティです。したがって、ld-linuxの正しいバージョンを指定する必要があります。 ]からg++ 、およびglibc。

これで、異なるバージョンのglibcと適切なバージョンのld -linux がある場合、ターゲットのglibcを使用してソースコードをコンパイルできます。 ライブラリ:

$ g++ <main-file> -o <output-name> -Wl,--rpath=/path/glibc -Wl,--dynamic-linker=/path/glibc/ld-linux.so.2

それを分解しましょう:

  • g ++ を使用してファイルを作成し、-oオプションを使用して出力名を指定しました
  • -Wl は、glibcライブラリをリンクするための長い警告をオンにします
  • –rpath オプションは、ランタイムローダーに / path /glibcディレクトリで必要なライブラリを探すように指示します。
  • –dynamic-linker オプションは、結果のバイナリでld-linux.so.2への正しいパスを提供します

または、LD_LIBRARY_PATHをエクスポートして、アプリケーションを実行する前にglibcディレクトリへのパスを含めることもできます。 ただし、プログラムによって起動される新しい子プロセスも、この変数で指定されている新しいglibを使用する必要があります。 それ以外の場合、それらが新しいものでコンパイルされていない場合 glibc または、子プロセス環境が親の環境を継承しない場合。 したがって、 –rpath オプションを使用し、環境変数の使用を避ける必要があります。

4. patchelfを使用する

このアプローチは、プログラムのソースコードがある場合にうまく機能します。 一方、 chroot 環境の作成など、多くの手動作業を行う必要があるため、バイナリを再リンクするのは少し複雑になります。 そのため、 patchelf を使用して、時間と頭痛の種を節約できます。

patchelfは、ELF実行可能ファイルのrpathとダイナミックリンカを簡単に変更するために使用できるユーティリティです。 ELFは、Executable andLinkableFormatの略です。 これは、Linuxのバイナリおよびライブラリの標準ファイル形式です。 これらには、。 so .o 、および特定の拡張子を持たない実行可能ファイルが含まれます。

4.1. patchelfをインストールしています

一部のディストリビューションには、patchelfがプリインストールされています。 ただし、インストールされていない場合は、パッケージマネージャーを使用して、ディストリビューションの公式リポジトリからインストールできます。

UbuntuとDebianの派生物:

# apt install patchelf

RHELおよびFedoraの場合:

# yum install patchelf

Archベース:

# pacman -S patchelf

patchelf がインストールされたら、それを確認しましょう。

$ patchelf --version
patchelf 0.14.3

4.2. 使用法

patchelfの使用は非常に簡単です。 patch elfコマンドの基本的な構文は次のとおりです。

$ patchelf [OPERATION] [OPTIONS] <ELF File>

rpathのさまざまなCRUD操作について説明します。

まず、優先するglibcのバイナリ実行可能ファイルにrpathを追加します。

$ patchelf --add-rpath /path/glibc-older my_prog

同様に、rpaththe–set-rpathオプションで更新できます。 これによりプログラムが破損する可能性があるため、注意して使用してください。

$ patchelf --set-rpath "/path/glibc-older:/path/libsdl:/path/libgl" my_prog

既存のrpathを削除するには:

$ patchelf --remove-rpath /path/glibc-older my_prog

ダイナミックリンカー set-interpreterで更新することもできます。

$ patchelf --set-interpreter /path/glibc-older/ld-linux/ld-linux.so.2

ここで、/ usr/libディレクトリにある最新の既存のglibcライブラリを使用するとします。 ELFファイルのsonameを更新するだけです

$ patchelf --set-soname libglib-2.0.so.0.7000.2

5. 結論

この記事では、1つのホストに同じライブラリの複数のバージョンを配置する方法を説明しました。 g++およびpatchelfを使用して、マシン上で複数のglibcを使用するいくつかの方法を実行しました。