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

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の36版が非表示)
10行目: 10行目:


== 依存関係のライブラリのインストール ==
== 依存関係のライブラリのインストール ==
==== Coreutilsのインストール ====
==== Coreutilsのインストール (不要) ====
# [http://ftp.gnu.org/gnu/coreutils Coreutilsの公式Webサイト]にアクセスして、最新のCoreutilsをダウンロードする。
Coreutilsのビルドに必要なライブラリをインストールする。<br>
# ダウンロードしたCoreutilsを解凍して、Coreutilsディレクトリに移動する。
sudo zypper install make gcc libcap-devel libattr-devel libacl-devel
#: tar xf coreutils-x.xx.tar.xz
<br>
# ビルド用ディレクトリを作成して移動する。
[http://ftp.gnu.org/gnu/coreutils Coreutilsの公式Webサイト]にアクセスして、最新のCoreutilsをダウンロードする。<br>
#: mkdir build && cd build
wget https://ftp.gnu.org/gnu/coreutils/coreutils-<バージョン>.tar.xz
# Coreutilsをビルドおよびインストールするために、以下のコマンドを実行する。
<br>
#: export CFLAGS="-static -O2 -g"
ダウンロードしたCoreutilsを解凍して、Coreutilsディレクトリに移動する。<br>
#: <br>
tar xf coreutils-<バージョン>.tar.xz
#: ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Coreutils
cd coreutils-<バージョン>
#: または
<br>
#: ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Coreutils \
ビルドディレクトリを作成する。<br>
#: CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \
mkdir build && cd build
#: CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \
<br>
#: CPP="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -E" CXXCPP="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -E"
Coreutilsをビルドおよびインストールする。<br>
#: <br>
../configure --prefix=<Coreutilsのインストールディレクトリ>
#: make -j 8
make -j $(nproc)
#: <br>
make install
#: 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
<br>
<br>
==== Binutilsのインストール ====
==== Binutilsのインストール ====
# [https://ftp.gnu.org/gnu/binutils Binutilsの公式Webサイト]にアクセスして、最新のBinutilsをダウンロードする。
Binutilsのビルドに必要な依存関係のライブラリをインストールする。<br>
# ダウンロードしたBinutilsを解凍して、Binutilsディレクトリに移動する。
# RHEL
#: tar xf Binutils-x.xx.tar.xz
sudo dnf install gmp-devel mpfr-devel libmpc-devel isl-devel
# ビルド用ディレクトリを作成して移動する。
#: mkdir build && cd build
# SUSE
# Binutilsをビルドおよびインストールするために、以下のコマンドを実行する。
sudo zypper install patterns-base-basesystem patterns-devel-base-devel_basis patterns-devel-C-C++-devel_C_C++ \
#: export CFLAGS="-static -O2 -g"
                    gcc gcc-c++ gawk ncurses-devel make tar pkg-config m4 gperf bison flex expect expect-devel \
#: <br>
                    gmp-devel mpfr-devel mpc-devel isl-devel
#: ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Binutils
<br>
#: または
[https://ftp.gnu.org/gnu/binutils Binutilsの公式Webサイト]にアクセスして、最新のBinutilsをダウンロードする。<br>
#: ./configure --prefix=/home/<ユーザ名>/InstallSoftware/Binutils \
ダウンロードしたBinutilsを解凍して、Binutilsディレクトリに移動する。<br>
#: CC="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -arch i386 -arch x86_64" \
tar xf Binutils-<バージョン>.tar.xz
#: CXX="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -arch i386 -arch x86_64" \
mkdir build && cd build
#: CPP="/<GCCのインストールディレクトリ>/bin/gcc-<バージョン名> -E" CXXCPP="/<GCCのインストールディレクトリ>/bin/g++-<バージョン名> -E"
<br>
#: <br>
Binutilsをビルドおよびインストールする。<br>
#: make -j 8
../configure --prefix=<Binutilsのインストールディレクトリ>
#: <br>
make -j $(nproc)
#: make install
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
<br><br>
<br><br>


== glibc(GNU C Library)のインストール ==
== GLIBC(GNU C Library)のインストール ==
現在使用しているglibcのバージョンを確認する。<br>
GLIBCのビルドに必要な依存関係のライブラリをインストールする。<br>
# SUSE
sudo zypper install patterns-base-basesystem patterns-devel-base-devel_basis patterns-devel-C-C++-devel_C_C++ \
                    gcc gcc-c++ gawk bison make m4 gperf bison flex    \
                    ncurses-devel ncurses5-devel expect expect-devel  \
                    gdbm-devel libbz2-devel zlib-devel libdb-4_8-devel \
                    libopenssl-devel libopenssl-1_1-devel                # OpenSSL 1を使用する場合
                    libopenssl-3-devel                                  # OpenSSL 3を使用する場合
<br>
現在使用しているGLIBCのバージョンを確認する。<br>
  ls -l /lib/libc-*
  ls -l /lib/libc-*
# 出力例
-rwxr-xr-x 1 root root 2205616  9月 13 00:35 /lib/libc-2.31.so*
<br>
<br>
まず、glibcをコンパイルするディレクトリを作成する。<br>
まず、GLIBCのインストールディレクトリおよびビルドディレクトリを作成する。<br>
  mkdir -p ~/InstallSoftware/GLIBC/build
  mkdir -p ~/InstallSoftware/GLIBC/build
  cd ~/InstallSoftware/GLIBC
  cd ~/InstallSoftware/GLIBC
<br>
<br>
glibcをダウンロードして解凍する。(glibc-x.xxディレクトリが作成される)<br>
[https://ftp.gnu.org/gnu/glibc/ GLIBCの公式Webサイト]にアクセスして、GLIBCをダウンロードして解凍する。<br>
または、<code>wget</code>コマンドや<code>git clone</code>コマンドを実行してダウンロードする。<br>
  wget http://ftp.gnu.org/gnu/glibc/glibc-x.xx.tar.xz
  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
  git clone git://sourceware.org/git/glibc.git
tar xf glibc-x.xx.tar.gz
<br>
<br>
環境変数<code>LD_LIBRARY_PATH</code>を空にする。<br>
<u>次に、ビルドに関連する環境変数<code>PATH</code>、<code>LD_LIBRARY_PATH</code>、<code>PKG_CONFIG_PATH</code>等を初期状態にする。</u><br>
  LD_LIBRARY_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="";
<br>
<br>
ビルド用ディレクトリに移動して、ビルドおよびインストールを行う。<br>
ビルドディレクトリに移動して、GLIBCをビルドおよびインストールする。<br>
これで、インストールしたGLIBCにより、実行するアプリケーションをビルドすることができる。<br>
  cd build
  cd build
   
   
  ../glibc-x.xx/configure --prefix=/home/<ユーザ名>/Installsoftware/GLIBC \
  ../glibc-x.xx/configure --prefix=<GLIBCのインストールディレクトリ>   \
CC=/home/<ユーザ名>/InstallSoftware/GCC/gcc-<バージョン名>/bin/gcc-<バージョン名> \
                        CC=/<GCCのインストールディレクトリ>/bin/gcc \ # GCCを指定する場合
CXX=/home/<ユーザ名>/InstallSoftware/GCC/g++-<バージョン名>/bin/gcc-<バージョン名> \
                        CXX=/<GCCのインストールディレクトリ>/bin/g++ \ # G++を指定する場合
--host=x86_64-linux-gnu --enable-add-ons=libidn, --without-selinux \
                        --host=x86_64-linux-gnu             \
--enable-stack-protector=strong --enable-multi-arch --with-binutils=/home/<ユーザ名>/InstallSoftware/Binutils
                        --enable-multi-arch                  \  # 32ビットを有効にする場合
                        --enable-stack-protector=strong      \
                        --enable-obsolete-rpc                \
                        --enable-obsolete-nsl                \
                        --enable-add-ons=libidn              \
                        --without-selinux                    \        # SELinuxが不要な場合
                        --with-binutils=<Binutilsのインストールディレクトリ> # 必要な場合
   
   
  make -j 8
  make -j $(nproc)
make install
   
   
  make install
# 各国語対応ファイルのインストール
  make localedata/install-others
<br>
configureスクリプトで使用可能なオプションを、以下に示す。<br>
* --enable-multi-archオプション
*: マルチアーキテクチャサポートを有効にする。
*: 異なるCPUアーキテクチャ (例:x86_64, i386, Aarch64等) 向けのライブラリを同一システム上で共存させることができる。
*: <br>
*: 動的リンカが実行時に最適なライブラリバージョンを選択できるようになる。
*: クロスコンパイルや異なるアーキテクチャのバイナリの実行をサポートする。
*: ロケールや文字セットのサポートを含む、アーキテクチャ固有の最適化を可能にする。
*: <br>
* --enable-stack-protector=strongオプション
*: 強力なスタック保護機能を有効にする。
*: <br>
*: バッファオーバーフロー攻撃からの保護を強化する。
*: 関数の開始時にカナリア値 (ランダムな値) をスタックに配置して、関数終了時にこの値を確認する。
*: カナリア値が変更されていた場合、スタックの破壊が検出され、プログラムは即座に終了する。
*: strong値は、より多くの関数に対してこの保護を適用する。(サイズの小さな配列を持つ関数も含む)
*: <br>
* --enable-obsolete-rpcオプション
*: 廃止予定のRPC(Remote Procedure Call)関連の機能を有効にする。
*: <br>
*: 古いRPC関連の関数やライブラリ (例: rpc/rpc.hのヘッダファイル等) を含める。
*: 後方互換性のために必要な場合がある。
*: 新しいプログラムではこれらの機能の使用は推奨されないが、レガシーシステムとの互換性維持のために重要である。
*: <br>
* --enable-obsolete-nslオプション
*: 廃止予定のNSL (Network Services Library) 関連の機能を有効にする。
*: <br>
*: 古いネットワークサービスライブラリ関連の関数 (例: gethostbyname関数等) を含める。
*: これらの関数は主にDNS解決に使用されていたが、現在では、getaddrinfo関数等の新しいAPIに置き換えられている。
*: レガシーソフトウェアとの互換性のために必要な場合がある。
<br>
<br>
次に、Linuxカーネルのヘッダファイル群が必要になるので、ダウンロードしてインストールする。<br>
マルチアーキテクチャサポートと強力なスタック保護は、現代のシステムにおいて重要な機能である。<br>
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
一方で、廃止予定のRPCとNSL機能の有効化は、主に古いソフトウェアとの互換性のために行われる。<br>
cd linux
make headers_install INSTALL_HDR_PATH=/home/ユーザ名/InstallSoftware/GLIBC
<br>
<br>
最後に、GCCのヘルパーライブラリが必要になるので、/lib64ディレクトリからコピーする。<br>
最後に、GCCのヘルパーライブラリが必要になるので、/lib64ディレクトリからコピーする。<br>
これにより、/home/ユーザ名/InstallSoftware/GLIBCディレクトリにおいて、システムファイルを使用する準備が整う。<br>
これにより、/home/ユーザ名/InstallSoftware/GLIBCディレクトリにおいて、システムファイルを使用する準備が整う。<br>
  # パッケージ管理システムによりインストールしたGCCを使用する場合
  # パッケージ管理システムによりインストールしたGCCを使用する場合
  cp -r /lib64/libgcc* /home/<ユーザ名>/InstallSoftware/GLIBC/lib64
  cp -r /lib64/libgcc* /<GLIBCのインストールディレクトリ>/lib64
   
   
  # ホームディレクトリにインストールしたGCCを使用する場合
  # ホームディレクトリにインストールしたGCCを使用する場合
  cp -r /<GCCのインストールディレクトリ>/libgcc* /home/<ユーザ名>/InstallSoftware/GLIBC/lib64
  cp -r /<GCCのインストールディレクトリ>/lib64/libgcc* /<GLIBCのインストールディレクトリ>/lib64
<br>
Linux x86やUbuntuの場合、lib64ディレクトリではなく、libディレクトリを使用する必要がある。<br>
<br><br>
 
== Linuxカーネルヘッダのインストール (不要) ==
次に、[https://www.kernel.org Linuxの公式Webサイト]にアクセスして、Linuxカーネルをダウンロードする。<br>
ダウンロードしたファイルを解凍する。<br>
tar xf linux-<バージョン>.tar.xz
cd linux-<バージョン>
<br>
または、<code>git clone</code>コマンドを実行して、Linuxカーネルをダウンロードする。<br>
git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux
<br>
Linuxのヘッダファイルをインストールする。<br>
make -j $(nproc) headers_install INSTALL_HDR_PATH=<GLIBCのインストールディレクトリ>
<br><br>
 
== ロケールデータ ==
まず、GLIBCのインストールディレクトリ内に、ロケールデータが正しく含まれているかどうかを確認する。<br>
<br>
/<GLIBCのインストールディレクトリ>/share/i18n/locales
/<GLIBCのインストールディレクトリ>/share/i18n/charmaps
<br>
次に、ロケールデータを生成する。<br>
# 日本語のロケールデータを生成する場合
mkdir /<GLIBCのインストールディレクトリ>/lib/locale
/<GLIBCのインストールディレクトリ>/bin/localedef -i ja_JP -f UTF-8 /<GLIBCのインストールディレクトリ>/lib/locale/ja_JP.UTF-8
<br>
<br>
Linux x86やUbuntuにおいて、lib64ディレクトリではなく、libディレクトリを使用する必要がある。<br>
必要ならば、ロケール環境変数を設定する。<br>
ローカルインストールしたGLIBCを使用して任意のソフトウェアを実行する場合、以下に示す環境変数の設定が必要になる可能性がある。<br>
export LOCPATH=/<GLIBCのインストールディレクトリ>/lib/locale
export LOCALE_ARCHIVE=/<GLIBCのインストールディレクトリ>/lib/locale/locale-archive
<br><br>
<br><br>


== glibcの確認 ==
== GLIBCの確認 ==
新しくインストールしたglibcを使用してソフトウェアを実行する。<br>
まず、インストールしたGLIBCのバージョンを確認する。<br>
インストールディレクトリにあるtestrun.shを使用して、以下のようにコマンドを実行する。<br>
strings /<GLIBCのインストールディレクトリ>/lib/libc.so.6 | grep GLIBC_
  /home/<ユーザ名>/InstallSoftware/GLIBC/build/testrun.sh <実行するソフトウェアのパス>
<br>
次に、ビルドしたGLIBCを使用して、ソフトウェアを実行する。<br>
ビルドディレクトリにあるtestrun.shファイルを使用して、以下のようにコマンドを実行する。<br>
  /<GLIBCのビルドディレクトリ>/build/testrun.sh <実行するソフトウェアのパス>
<br><br>
<br><br>


== 環境パスの設定 ==
== GLIBCを使用したソフトウェアの実行 ==
インストールしたglibcを使用するために、環境パスを設定する。<br>
GLIBCを使用してソフトウェアを実行する場合、再リンクする必要がある。<br>
sudo vi /etc/ld.so.conf
<br>
<br>
  # /etc/ld.so.confファイル
# まず、個別にインストールしたGLIBCのld-linux-x86-64.so.2ライブラリを直接実行して、パラメータとしてソフトウェアのパスを渡す。<br>これにより、ソフトウェアを再ビルドすることなく、ld-linux-x86-64.so.2ライブラリを置き換えることができる。
  /<glibcのインストールディレクトリ>/lib64
  /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
/<glibcのインストールディレクトリ>/lib
  --library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib:/usr/lib64:/usr/lib:/lib64:/lib \
<ソフトウェアの実行ファイルのパス>
<br>
<br>
設定を反映させるため、再起動する。<br>
<syntaxhighlight lang="sh">
# FileZillaを実行する場合
export PATH="/<FileZillaのインストールディレクトリ>/bin:$PATH"; \
export FZ_DATADIR="/<FileZillaのインストールディレクトリ>/share/filezilla"
/<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
--library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib:/usr/lib64:/usr/lib:/lib64:/lib \
/<FileZillaのインストールディレクトリ>/bin/filezilla
</syntaxhighlight>
<br><br>
<br><br>


120行目: 231行目:
しかし、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ライブラリへの絶対パスは、リンク時に実行ファイルにハードコードされており、<br>
ld-linux-x86-64.so.2ライブラリへの絶対パスは、リンク時に実行ファイルにハードコードされており、リンク後は簡単に変更できない。
リンク後に簡単に変更することはできない。(patchelfを使用することで可能である)<br>
([http://nixos.org/patchelf.html patchelf]を使用することで可能である)<br>
<br>
ソフトウェアを再リンクする場合、以下の方法がある。<br>
* [http://nixos.org/patchelf.html patchelf]を使用する。<br>既にビルドされたELFのパスとインタプリタを変更することができる。
* 個別にインストールしたGLIBCのld-linux-x86-64.so.2ライブラリを直接実行して、パラメータとしてソフトウェアのパスを渡す。<br>ソフトウェアを再ビルドすることなく、ld-linux-x86-64.so.2ライブラリを置き換えることができる。
*: <code>/<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \</code>
*: <code>--library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib:/usr/lib64:/usr/lib:/lib64:/lib \</code>
*: <code><ソフトウェアの実行ファイルのパス></code>
* 適切なchroot環境を設定する。
* [http://bitwagon.com/rtldi/rtldi.html rtldi]とバイナリエディタを使用する。
<br>
<br>
新しくインストールしたGLIBCで動作するソフトウェアを使用する場合、以下のようにビルドする。<br>
==== インストールしたGLIBCを使用してソフトウェアをビルドする場合 ====
リンカオプションの<code>rpath</code>オプションを指定して、ランタイムローダがGLIBCのインストールディレクトリにあるライブラリを検索する。<br>
  ./configure --prefix=<インストールするソフトウェアのディレクトリ> \
  ./configure --prefix=<インストールするソフトウェアのディレクトリ> \
  LDFLAGS="-Wl,-rpath <GLIBCのインストールディレクトリ> -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>
<code>dynamic-linker</code>オプションは、ld-linux-x86-64.so.2ライブラリへのパスをソフトウェアの実行ファイルに焼き付ける設定である。<br>
(<code>dynamic-linker</code>オプションは、ELF実行ファイル用にコンパイルする場合にのみ動作する)<br>
<br>
==== patchelfを使用してソフトウェアを実行する場合 ====
まず、ソフトウェアの実行ファイルをバックアップする。<br>
(patchelfの実行後は、rpathに指定されているパスを復元できないため)<br>
<br>
[http://nixos.org/patchelf.html patchelfのGithub]から、patchelfをダウンロードする。<br>
git clone https://github.com/NixOS/patchelf.git
<br>
実行ファイルに対して、patchelfを実行する。<br>
./patchelf -set-interpreter /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
-set-rpath <GLIBCのインストールディレクトリ> \
<ソフトウェアの実行ファイルのパス>
<br>
新しく生成された実行ファイルを実行する。<br>
./<ソフトウェアの実行ファイル>
<br>
Linux上でソフトウェアを実行する場合、実行ファイルは①リンカ、②ライブラリの順に読み込む。<br>
もし、リンカに問題がある時、実行ファイルがどのパスを探しているのかを知りたい場合、以下のコマンドで確認することができる。<br>
readelf -l <ソフトウェアの実行ファイルのパス> | grep interpreter
<br>
<br>
リンカオプションのrpathオプションは、ランタイムローダがGLIBCのインストールディレクトリにあるライブラリを検索する設定である。<br>
もし、ライブラリファイルに問題がある場合、実行ファイルが必要とするライブラリファイル群を確認する。<br>
-dynamic-linkerオプションは、ld-linux.so.2へのパスをソフトウェアに焼き付ける設定である。<br>
readelf -d <ソフトウェアの実行ファイルのパス> | grep Shared
ldd <ソフトウェアの実行ファイルのパス>
<br>
<br>
ソフトウェアを再リンクする場合、以下の方法がある。<br>
patchelfは、上記2つの問題に関連して、ソフトウェアを実行する時に遭遇する様々な問題に対して動作する。<br>
* 適切なchroot環境を設定する。
例えば、"ELF file OS ABI invalid"と表示される場合、新しいローダを設定する(コマンドの-set-interpreter部分)ことで解決する場合がある。<br>
* rtldiとバイナリエディタを使用する。
また、ソフトウェアの実行時に"No such file or directory"と表示される場合、新しいインタプリタを設定することで解決する。<br>
* patchelfを使用する。
<br><br>
<br><br>
{{#seo:
|keywords=Mochiuwiki,mochiuwiki,mochiu,wiki,mochiu wiki,electric circuit,electric,pcb,Mathematics,AVR,TI,ti,STMicro,avr,atmega,msp430,stm,Arduino,arduino,Xilinx,xilinx,fpga,verilog,HDL,hdl,pinephone,pine phone,raspberry,raspbberry pi,c,c++,c#,qt,qml,mfc,shell,bash,zsh,fish,suse,sle,suse enterprise,suse linux,opensuse,open suse,leap,linux,uclinux,電気回路,電子回路,基板,プリント基板
|description=This is a wiki with information on electronic circuits and SUSE Linux
|image=MochiuLogo.png
}}


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

2024年10月19日 (土) 14:38時点における最新版

概要

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のインストール (不要)

Coreutilsのビルドに必要なライブラリをインストールする。

sudo zypper install make gcc libcap-devel libattr-devel libacl-devel


Coreutilsの公式Webサイトにアクセスして、最新のCoreutilsをダウンロードする。

wget https://ftp.gnu.org/gnu/coreutils/coreutils-<バージョン>.tar.xz


ダウンロードしたCoreutilsを解凍して、Coreutilsディレクトリに移動する。

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


ビルドディレクトリを作成する。

mkdir build && cd build


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のインストール

Binutilsのビルドに必要な依存関係のライブラリをインストールする。

# RHEL
sudo dnf install gmp-devel mpfr-devel libmpc-devel isl-devel 

# SUSE
sudo zypper install patterns-base-basesystem patterns-devel-base-devel_basis patterns-devel-C-C++-devel_C_C++ \
                    gcc gcc-c++ gawk ncurses-devel make tar pkg-config m4 gperf bison flex expect expect-devel \
                    gmp-devel mpfr-devel mpc-devel isl-devel


Binutilsの公式Webサイトにアクセスして、最新のBinutilsをダウンロードする。
ダウンロードしたBinutilsを解凍して、Binutilsディレクトリに移動する。

tar xf Binutils-<バージョン>.tar.xz
mkdir build && cd build


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のビルドに必要な依存関係のライブラリをインストールする。

# SUSE
sudo zypper install patterns-base-basesystem patterns-devel-base-devel_basis patterns-devel-C-C++-devel_C_C++ \
                    gcc gcc-c++ gawk bison make m4 gperf bison flex    \
                    ncurses-devel ncurses5-devel expect expect-devel   \
                    gdbm-devel libbz2-devel zlib-devel libdb-4_8-devel \
                    libopenssl-devel libopenssl-1_1-devel                # OpenSSL 1を使用する場合
                    libopenssl-3-devel                                   # OpenSSL 3を使用する場合


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

ls -l /lib/libc-*

# 出力例
-rwxr-xr-x 1 root root 2205616  9月 13 00:35 /lib/libc-2.31.so*


まず、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  \  # GCCを指定する場合
                        CXX=/<GCCのインストールディレクトリ>/bin/g++ \  # G++を指定する場合
                        --host=x86_64-linux-gnu              \
                        --enable-multi-arch                  \  # 32ビットを有効にする場合
                        --enable-stack-protector=strong      \
                        --enable-obsolete-rpc                \
                        --enable-obsolete-nsl                \
                        --enable-add-ons=libidn              \
                        --without-selinux                    \        # SELinuxが不要な場合
                        --with-binutils=<Binutilsのインストールディレクトリ>  # 必要な場合

make -j $(nproc)
make install

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


configureスクリプトで使用可能なオプションを、以下に示す。

  • --enable-multi-archオプション
    マルチアーキテクチャサポートを有効にする。
    異なるCPUアーキテクチャ (例:x86_64, i386, Aarch64等) 向けのライブラリを同一システム上で共存させることができる。

    動的リンカが実行時に最適なライブラリバージョンを選択できるようになる。
    クロスコンパイルや異なるアーキテクチャのバイナリの実行をサポートする。
    ロケールや文字セットのサポートを含む、アーキテクチャ固有の最適化を可能にする。

  • --enable-stack-protector=strongオプション
    強力なスタック保護機能を有効にする。

    バッファオーバーフロー攻撃からの保護を強化する。
    関数の開始時にカナリア値 (ランダムな値) をスタックに配置して、関数終了時にこの値を確認する。
    カナリア値が変更されていた場合、スタックの破壊が検出され、プログラムは即座に終了する。
    strong値は、より多くの関数に対してこの保護を適用する。(サイズの小さな配列を持つ関数も含む)

  • --enable-obsolete-rpcオプション
    廃止予定のRPC(Remote Procedure Call)関連の機能を有効にする。

    古いRPC関連の関数やライブラリ (例: rpc/rpc.hのヘッダファイル等) を含める。
    後方互換性のために必要な場合がある。
    新しいプログラムではこれらの機能の使用は推奨されないが、レガシーシステムとの互換性維持のために重要である。

  • --enable-obsolete-nslオプション
    廃止予定のNSL (Network Services Library) 関連の機能を有効にする。

    古いネットワークサービスライブラリ関連の関数 (例: gethostbyname関数等) を含める。
    これらの関数は主にDNS解決に使用されていたが、現在では、getaddrinfo関数等の新しいAPIに置き換えられている。
    レガシーソフトウェアとの互換性のために必要な場合がある。


マルチアーキテクチャサポートと強力なスタック保護は、現代のシステムにおいて重要な機能である。
一方で、廃止予定のRPCとNSL機能の有効化は、主に古いソフトウェアとの互換性のために行われる。

最後に、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ディレクトリを使用する必要がある。


Linuxカーネルヘッダのインストール (不要)

次に、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のインストールディレクトリ>



ロケールデータ

まず、GLIBCのインストールディレクトリ内に、ロケールデータが正しく含まれているかどうかを確認する。

/<GLIBCのインストールディレクトリ>/share/i18n/locales
/<GLIBCのインストールディレクトリ>/share/i18n/charmaps


次に、ロケールデータを生成する。

# 日本語のロケールデータを生成する場合
mkdir /<GLIBCのインストールディレクトリ>/lib/locale
/<GLIBCのインストールディレクトリ>/bin/localedef -i ja_JP -f UTF-8 /<GLIBCのインストールディレクトリ>/lib/locale/ja_JP.UTF-8


必要ならば、ロケール環境変数を設定する。
ローカルインストールしたGLIBCを使用して任意のソフトウェアを実行する場合、以下に示す環境変数の設定が必要になる可能性がある。

export LOCPATH=/<GLIBCのインストールディレクトリ>/lib/locale
export LOCALE_ARCHIVE=/<GLIBCのインストールディレクトリ>/lib/locale/locale-archive



GLIBCの確認

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

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


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

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



GLIBCを使用したソフトウェアの実行

GLIBCを使用してソフトウェアを実行する場合、再リンクする必要がある。

  1. まず、個別にインストールした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 \
<ソフトウェアの実行ファイルのパス>


 # FileZillaを実行する場合
 export PATH="/<FileZillaのインストールディレクトリ>/bin:$PATH"; \
 export FZ_DATADIR="/<FileZillaのインストールディレクトリ>/share/filezilla"
 
 /<GLIBCのインストールディレクトリ>/lib/ld-linux-x86-64.so.2 \
 --library-path /<GLIBCのインストールディレクトリ>/lib64:/<GLIBCのインストールディレクトリ>/lib:/usr/lib64:/usr/lib:/lib64:/lib \
 /<FileZillaのインストールディレクトリ>/bin/filezilla



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