「インストール - GLIBC」の版間の差分

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
112行目: 112行目:
しかし、GLIBCは多くのモジュールから(200以上の共有ライブラリ)から構成されており、それらが全て一致する必要がある。<br>
しかし、GLIBCは多くのモジュールから(200以上の共有ライブラリ)から構成されており、それらが全て一致する必要がある。<br>
<br>
<br>
その1つが、ld-linux.so.2ライブラリであり、libc.so.6ライブラリと一致しなければ、エラーが発生する。<br>
例えば、ld-linux-x86-64.so.2ライブラリはlibc.so.6ライブラリと一致しなければ、エラーが発生する。<br>
ld-linux.so.2ライブラリへの絶対パスは、リンク時に実行ファイルにハードコードされており、リンク後は簡単に変更できない。
ld-linux-x86-64.so.2ライブラリへの絶対パスは、リンク時に実行ファイルにハードコードされており、リンク後は簡単に変更できない。
([http://nixos.org/patchelf.html patchelf]を使用することで可能である)<br>
([http://nixos.org/patchelf.html patchelf]を使用することで可能である)<br>
<br>
<br>
ソフトウェアを再リンクする場合、以下の方法がある。<br>
ソフトウェアを再リンクする場合、以下の方法がある。<br>
* [http://nixos.org/patchelf.html patchelf]を使用する。<br>既にビルドされたELFのパスとインタプリタを変更することができる。
* [http://nixos.org/patchelf.html patchelf]を使用する。<br>既にビルドされたELFのパスとインタプリタを変更することができる。
* ユーザがインストールしたGLIBCのld-linux.so.2を直接実行して、パラメータとしてソフトウェアのパスを渡す。<br>ソフトウェアを再ビルドすることなく、ld.-linux.so.2を置き換えることができる。
* 個別にインストールしたGLIBCのld-linux-x86-64.so.2ライブラリを直接実行して、パラメータとしてソフトウェアのパスを渡す。<br>ソフトウェアを再ビルドすることなく、ld-linux-x86-64.so.2ライブラリを置き換えることができる。
*: <code>/<GLIBCのインストールディレクトリ>/lib64/ld-linux.so.2 \</code>
*: <code>/<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \</code>
*: <code>--library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/usr/lib64 \</code>
*: <code>--library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib \</code>
*: <code><ソフトウェアの実行ファイルのパス></code>
*: <code><ソフトウェアの実行ファイルのパス></code>
* 適切なchroot環境を設定する。
* 適切なchroot環境を設定する。
128行目: 128行目:
リンカオプションの<code>rpath</code>オプションを指定して、ランタイムローダがGLIBCのインストールディレクトリにあるライブラリを検索する。<br>
リンカオプションの<code>rpath</code>オプションを指定して、ランタイムローダがGLIBCのインストールディレクトリにあるライブラリを検索する。<br>
  ./configure --prefix=<インストールするソフトウェアのディレクトリ> \
  ./configure --prefix=<インストールするソフトウェアのディレクトリ> \
  LDFLAGS="-Wl,-rpath <GLIBCのインストールディレクトリ>/lib64 -Wl,--dynamic-linker=<GLIBCのインストールディレクトリ>/lib64/ld-linux.so.2"
  LDFLAGS="-Wl,-rpath <GLIBCのインストールディレクトリ>/lib -Wl,--dynamic-linker=<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2"
<br>
<br>
<code>dynamic-linker</code>オプションは、ld-linux.so.2へのパスをソフトウェアに焼き付ける設定である。<br>
<code>dynamic-linker</code>オプションは、ld-linux-x86-64.so.2ライブラリへのパスをソフトウェアの実行ファイルに焼き付ける設定である。<br>
(<code>dynamic-linker</code>オプションは、ELF実行ファイル用にコンパイルする場合にのみ動作する)<br>
(<code>dynamic-linker</code>オプションは、ELF実行ファイル用にコンパイルする場合にのみ動作する)<br>
<br>
<br>
141行目: 141行目:
<br>
<br>
実行ファイルに対して、patchelfを実行する。<br>
実行ファイルに対して、patchelfを実行する。<br>
  ./patchelf -set-interpreter /<GLIBCのインストールディレクトリ>/ld-linux.so.2 -set-rpath \
  ./patchelf -set-interpreter /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
/<GLIBCのインストールディレクトリ>/ <ソフトウェアの実行ファイルのパス>
-set-rpath /<GLIBCのインストールディレクトリ>/ <ソフトウェアの実行ファイルのパス>
<br>
<br>
新しく生成された実行ファイルを実行する。<br>
新しく生成された実行ファイルを実行する。<br>
  ./<ソフトウェアの実行ファイル>
  ./<ソフトウェアの実行ファイル>
<br>
<br>
Linuxにおいて、ソフトウェアを実行する場合、バイナリはリンカ、ライブラリの順に読み込む。<br>
Linux上でソフトウェアを実行する場合、実行ファイルは①リンカ、②ライブラリの順に読み込む。<br>
もし、リンカに問題があり、実行ファイルがどのパスを探しているのかを知りたい場合、以下のコマンドで確認することができる。<br>
もし、リンカに問題がある時、実行ファイルがどのパスを探しているのかを知りたい場合、以下のコマンドで確認することができる。<br>
  readelf -l <ソフトウェアの実行ファイルのパス> | grep interpreter
  readelf -l <ソフトウェアの実行ファイルのパス> | grep interpreter
<br>
<br>
157行目: 157行目:
patchelfは、上記2つの問題に関連して、ソフトウェアを実行する時に遭遇する様々な問題に対して動作する。<br>
patchelfは、上記2つの問題に関連して、ソフトウェアを実行する時に遭遇する様々な問題に対して動作する。<br>
例えば、"ELF file OS ABI invalid"と表示される場合、新しいローダを設定する(コマンドの-set-interpreter部分)ことで解決する場合がある。<br>
例えば、"ELF file OS ABI invalid"と表示される場合、新しいローダを設定する(コマンドの-set-interpreter部分)ことで解決する場合がある。<br>
別の例では、ソフトウェアの実行時に"No such file or directory"と表示される場合、新しいインタプリタを設定することで解決する。<br>
また、ソフトウェアの実行時に"No such file or directory"と表示される場合、新しいインタプリタを設定することで解決する。<br>
<br><br>
<br><br>


__FORCETOC__
__FORCETOC__
[[カテゴリ:CentOS]][[カテゴリ:SUSE]][[カテゴリ:Raspberry_Pi]]
[[カテゴリ:CentOS]][[カテゴリ:SUSE]][[カテゴリ:Raspberry_Pi]]

2021年4月5日 (月) 02:13時点における版

概要

GNU Cライブラリは、GNUシステムとGNU/Linuxシステム、そしてLinuxをカーネルとして使うシステムのためのコアライブラリである。

これらのライブラリは、ISO C11、POSIX.1-2008、BSD、OS固有のAPIなどを含む重要なAPIを提供しており、
APIには、open、read、write、malloc、printf、getaddrinfo、dlopen、pthread_create、crypt、login、exit等の基本的な機能が含まれている。

GNU Cライブラリは、下位互換性や移植性があり、高性能なISO Cライブラリになるように設計されている。
ISO C11、POSIX.1-2008、IEEE 754-2008を含むすべての関連規格に従うことを目指している。


依存関係のライブラリのインストール

Coreutilsのインストール

  1. Coreutilsの公式Webサイトにアクセスして、最新のCoreutilsをダウンロードする。
  2. ダウンロードしたCoreutilsを解凍して、Coreutilsディレクトリに移動する。
    tar xf coreutils-x.xx.tar.xz
  3. ビルド用ディレクトリを作成して移動する。
    mkdir build && cd build
  4. Coreutilsをビルドおよびインストールするために、以下のコマンドを実行する。
    export CFLAGS="-static -O2 -g"

    ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Coreutils
    または
    ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Coreutils \
    CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \
    CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \
    CPP="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -E" CXXCPP="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -E"

    make -j 8

    make install


Binutilsのインストール

  1. Binutilsの公式Webサイトにアクセスして、最新のBinutilsをダウンロードする。
  2. ダウンロードしたBinutilsを解凍して、Binutilsディレクトリに移動する。
    tar xf Binutils-x.xx.tar.xz
  3. ビルド用ディレクトリを作成して移動する。
    mkdir build && cd build
  4. Binutilsをビルドおよびインストールするために、以下のコマンドを実行する。
    export CFLAGS="-static -O2 -g"

    ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Binutils
    または
    ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Binutils \
    CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \
    CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \
    CPP="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -E" CXXCPP="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -E"

    make -j 8

    make install



glibc(GNU C Library)のインストール

現在使用しているglibcのバージョンを確認する。

ls -l /lib/libc-*


まず、glibcをコンパイルするディレクトリを作成する。

mkdir -p ~/InstallSoftware/GLIBC/build
cd ~/InstallSoftware/GLIBC


glibcをダウンロードして解凍する。(glibc-x.xxディレクトリが作成される)

wget http://ftp.gnu.org/gnu/glibc/glibc-x.xx.tar.xz
または
git clone git://sourceware.org/git/glibc.git

tar xf glibc-x.xx.tar.gz


環境変数LD_LIBRARY_PATHを空にする。

LD_LIBRARY_PATH=""


ビルド用ディレクトリに移動して、ビルドおよびインストールを行う。
これで、インストールしたGLIBCにより、実行するアプリケーションをビルドすることができる。

cd build

../glibc-x.xx/configure --prefix=/home/<ユーザ名>/InstallSoftware/GLIBC \
CC=/home/<ユーザ名>/InstallSoftware/GCC/gcc-<バージョン名>/bin/gcc-<バージョン名> \
CXX=/home/<ユーザ名>/InstallSoftware/GCC/g++-<バージョン名>/bin/gcc-<バージョン名> \
--host=x86_64-linux-gnu --enable-add-ons=libidn, --without-selinux \
--enable-stack-protector=strong --enable-multi-arch --with-binutils=/home/<ユーザ名>/InstallSoftware/Binutils

make -j 8

make install


次に、Linuxカーネルのヘッダファイル群が必要になるので、ダウンロードしてインストールする。

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
make headers_install INSTALL_HDR_PATH=/home/ユーザ名/InstallSoftware/GLIBC


最後に、GCCのヘルパーライブラリが必要になるので、/lib64ディレクトリからコピーする。
これにより、/home/ユーザ名/InstallSoftware/GLIBCディレクトリにおいて、システムファイルを使用する準備が整う。

# パッケージ管理システムによりインストールしたGCCを使用する場合
cp -r /lib64/libgcc* /home/<ユーザ名>/InstallSoftware/GLIBC/lib64

# ホームディレクトリにインストールしたGCCを使用する場合
cp -r /<GCCのインストールディレクトリ>/libgcc* /home/<ユーザ名>/InstallSoftware/GLIBC/lib64


Linux x86やUbuntuにおいて、lib64ディレクトリではなく、libディレクトリを使用する必要がある。


glibcの確認

まず、インストールしたGLIBCのバージョンを確認する。

strings /<GLIBCのインストールディレクトリ>/lib/libc.so.6 | grep GLIBC_


次に、ビルドしたGLIBCを使用して、ソフトウェアを実行する。
ビルドディレクトリにあるtestrun.shファイルを使用して、以下のようにコマンドを実行する。

/<GLIBCのビルドディレクトリ>/build/testrun.sh <実行するソフトウェアのパス>



GLIBCを使用したソフトウェアのビルド

同じシステム上で複数のバージョンのGLIBCを使用することは可能である。
しかし、GLIBCは多くのモジュールから(200以上の共有ライブラリ)から構成されており、それらが全て一致する必要がある。

例えば、ld-linux-x86-64.so.2ライブラリはlibc.so.6ライブラリと一致しなければ、エラーが発生する。
ld-linux-x86-64.so.2ライブラリへの絶対パスは、リンク時に実行ファイルにハードコードされており、リンク後は簡単に変更できない。 (patchelfを使用することで可能である)

ソフトウェアを再リンクする場合、以下の方法がある。

  • patchelfを使用する。
    既にビルドされたELFのパスとインタプリタを変更することができる。
  • 個別にインストールしたGLIBCのld-linux-x86-64.so.2ライブラリを直接実行して、パラメータとしてソフトウェアのパスを渡す。
    ソフトウェアを再ビルドすることなく、ld-linux-x86-64.so.2ライブラリを置き換えることができる。
    /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
    --library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib \
    <ソフトウェアの実行ファイルのパス>
  • 適切なchroot環境を設定する。
  • rtldiとバイナリエディタを使用する。


インストールしたGLIBCを使用してソフトウェアをビルドする場合

リンカオプションのrpathオプションを指定して、ランタイムローダがGLIBCのインストールディレクトリにあるライブラリを検索する。

./configure --prefix=<インストールするソフトウェアのディレクトリ> \
LDFLAGS="-Wl,-rpath <GLIBCのインストールディレクトリ>/lib -Wl,--dynamic-linker=<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2"


dynamic-linkerオプションは、ld-linux-x86-64.so.2ライブラリへのパスをソフトウェアの実行ファイルに焼き付ける設定である。
(dynamic-linkerオプションは、ELF実行ファイル用にコンパイルする場合にのみ動作する)

patchelfを使用してソフトウェアを実行する場合

まず、ソフトウェアの実行ファイルをバックアップする。
(patchelfの実行後は、rpathに指定されているパスを復元できないため)

以下に示すWebサイトから、patchelfをダウンロードする。
http://nixos.org/patchelf.html

実行ファイルに対して、patchelfを実行する。

./patchelf -set-interpreter /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
-set-rpath /<GLIBCのインストールディレクトリ>/ <ソフトウェアの実行ファイルのパス>


新しく生成された実行ファイルを実行する。

./<ソフトウェアの実行ファイル>


Linux上でソフトウェアを実行する場合、実行ファイルは①リンカ、②ライブラリの順に読み込む。
もし、リンカに問題がある時、実行ファイルがどのパスを探しているのかを知りたい場合、以下のコマンドで確認することができる。

readelf -l <ソフトウェアの実行ファイルのパス> | grep interpreter


もし、ライブラリファイルに問題がある場合、実行ファイルが必要とするライブラリファイル群を確認する。

readelf -d <ソフトウェアの実行ファイルのパス> | grep Shared
ldd <ソフトウェアの実行ファイルのパス>


patchelfは、上記2つの問題に関連して、ソフトウェアを実行する時に遭遇する様々な問題に対して動作する。
例えば、"ELF file OS ABI invalid"と表示される場合、新しいローダを設定する(コマンドの-set-interpreter部分)ことで解決する場合がある。
また、ソフトウェアの実行時に"No such file or directory"と表示される場合、新しいインタプリタを設定することで解決する。