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

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
25行目: 25行目:
#: <code>make install</code>
#: <code>make install</code>
#: または
#: または
#: <code>../configure --prefix=/home/<ユーザ名>/InstallSoftware/Coreutils \</code>
#: <code>../configure --prefix=<Coreutilsのインストールディレクトリ> \</code>
#: <code>CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \</code>
#: <code>CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \</code>
#: <code>CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \</code>
#: <code>CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \</code>

2024年6月21日 (金) 23:51時点における版

概要

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のビルドに必要なライブラリをインストールする。
    sudo zypper install make gcc libcap-devel libattr-devel libacl-devel
  2. Coreutilsの公式Webサイトにアクセスして、最新のCoreutilsをダウンロードする。
    wget https://ftp.gnu.org/gnu/coreutils/coreutils-<バージョン>.tar.xz
  3. ダウンロードしたCoreutilsを解凍して、Coreutilsディレクトリに移動する。
    tar xf coreutils-<バージョン>.tar.xz
    cd coreutils-<バージョン>
  4. ビルドディレクトリを作成する。
    mkdir build && cd build
  5. Coreutilsをビルドおよびインストールする。
    ../configure --prefix=<Coreutilsのインストールディレクトリ>
    make -j $(nproc)
    make install
    または
    ../configure --prefix=<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 $(nproc)
    make install


Binutilsのインストール

  1. ビルドに必要な依存関係のライブラリをインストールする。
    sudo zypper install \
    gmp-devel mpfr-devel mpc-devel isl-devel expect-devel gcc-fortran gcc7-fortran libgfortran4 libquadmath0 gcc-go gcc7-go libgo11
  2. Binutilsの公式Webサイトにアクセスして、最新のBinutilsをダウンロードする。
  3. ダウンロードしたBinutilsを解凍して、Binutilsディレクトリに移動する。
    tar xf Binutils-x.xx.tar.xz
  4. ビルドディレクトリを作成する。
    mkdir build && cd build
  5. Binutilsをビルドおよびインストールするために、以下のコマンドを実行する。
    ../configure --prefix=<Binutilsのインストールディレクトリ>
    make -j $(nproc)
    make install
    または
    ../configure --prefix=<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 $(nproc)
    make install



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

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

ls -l /lib/libc-*


まず、GLIBCのインストールディレクトリおよびビルドディレクトリを作成する。

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


GLIBCの公式Webサイトにアクセスして、GLIBCをダウンロードして解凍する。
または、wgetコマンドやgit cloneコマンドを実行してダウンロードする。

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


次に、ビルドに関連する環境変数PATHLD_LIBRARY_PATHPKG_CONFIG_PATH等を初期状態にする。

export PATH="/usr/local/bin:/usr/bin:/bin"; \
export LD_LIBRARY_PATH=""; \
export PKG_CONFIG_PATH="$(pkg-config --variable pc_path pkg-config)"; \
export CFLAGS=""; \
export CPPFLAGS="";


ビルドディレクトリに移動して、GLIBCをビルドおよびインストールする。

cd build

../glibc-x.xx/configure --prefix=<GLIBCのインストールディレクトリ> \
CC=/<GCCのインストールディレクトリ>/bin/gcc  \
CXX=/<GCCのインストールディレクトリ>/bin/g++ \
--host=x86_64-linux-gnu --enable-add-ons=libidn, --without-selinux \
--enable-stack-protector=strong \
--enable-multi-arch             \
--with-binutils=<Binutilsのインストールディレクトリ>  # 必要な場合

make -j $(nproc)
make install

# 各国語対応ファイルのインストール
make localedata/install-others


次に、Linuxの公式Webサイトにアクセスして、Linuxカーネルをダウンロードする。
ダウンロードしたファイルを解凍する。

tar xf linux-<バージョン>.tar.xz
cd linux-<バージョン>


または、git cloneコマンドを実行して、Linuxカーネルをダウンロードする。

git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux


Linuxのヘッダファイルをインストールする。

make -j $(nproc) headers_install INSTALL_HDR_PATH=<GLIBCのインストールディレクトリ>


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

# パッケージ管理システムによりインストールしたGCCを使用する場合
cp -r /lib64/libgcc* /<GLIBCのインストールディレクトリ>/lib64

# ホームディレクトリにインストールしたGCCを使用する場合
cp -r /<GCCのインストールディレクトリ>/lib64/libgcc* /<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:/usr/lib64:/usr/lib:/lib64:/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に指定されているパスを復元できないため)

patchelfのGithubから、patchelfをダウンロードする。

git clone https://github.com/NixOS/patchelf.git


実行ファイルに対して、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"と表示される場合、新しいインタプリタを設定することで解決する。