インストール - GCC

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

RHELおよびSUSEのパッケージ管理システムで提供されているGCCのバージョンは古い可能性がある。
最新のGCCでは、C++11からC++17を完全にサポートしており、また、C++20をサポートしている。

また、最新のGCCでは、C11およびC++14のサポートがデフォルトで有効になっている。(-std=c11または-std=c++14を追加する必要はない)


GCCのインストール : ソースコードからインストール

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

まず、システムが最新であることを確認する。

# RHEL
sudo dnf update

# SUSE
sudo zypper update


依存関係のライブラリを、以下に示す2種類のいずれかの方法でインストールする。

パッケージ管理システムの使用
# 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


スクリプトの使用

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

tar xf gcc-<バージョン>.tar.gz
cd gcc-<バージョン>


ビルドに必要なライブラリをソースコードからビルドする場合、解凍したGCCのディレクトリに移動して、ライブラリをダウンロードする。

./contrib/download_prerequisites


ダウンロードされた依存関係のライブラリを解凍する。

tar xf gmp-<バージョン>.tar.bz2
tar xf mpfr-<バージョン>.tar.bz2 
tar xf mpc-<バージョン>.tar.gz 
tar xf isl-<バージョン>.tar.bz2 


ビルドに必要なライブラリを、ビルドしてインストールする。

  • GMPのインストール
./gmp-<バージョン>/configure --prefix=<GCCのインストールディレクトリ> --enable-cxx
make -j $(nproc)
make check
make install


  • MPFRのインストール
./mpfr-<バージョン>/configure --prefix=<GCCのインストールディレクトリ> --with-gmp=<GCCのインストールディレクトリ>
make -s -j $(nproc)
make -s check -j $(nproc)
make install


  • MPCのインストール
./mpc-<バージョン>/configure --prefix=<GCCのインストールディレクトリ> --with-gmp=<GCCのインストールディレクトリ> --with-mpfr=<GCCのインストールディレクトリ>
make -s -j $(nproc)
make check -s -j $(nproc)
make install


  • ISLのインストール
./isl-<バージョン>/configure --prefix=<GCCのインストールディレクトリ> --with-gmp-prefix=<GCCのインストールディレクトリ>
make -j $(nproc)
make check
make install


GCCのインストール

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

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


sha512.sumファイルを使用して、ダウンロードしたファイルのチェックを行う。
sha512sum: gcc-<バージョン>.tar.gz: No such file or directoryというメッセージが表示されるが、
gcc-<バージョン>.tar.gzファイルをダウンロードしていないため表示されているだけなので、特に問題ない。

sha512sum --check sha512.sum


GCC 7.1をインストールする場合、/<GCC 7.1のソースディレクトリ>/libgcc/config/i386/linux-unwind.hファイルを、以下に示すように修正する必要がある。

 // /<GCC 7.1のソースディレクトリ>/libgcc/config/i386/linux-unwind.hファイルの61行目
 
 // 修正前
 struct ucontext *uc_ = context->cfa;
 
 // 修正後
 struct ucontext_t *uc_ = context->cfa;


GCCをビルドおよびインストールする。
オプションの説明を記載する。

  • enable-languages=c,c++,fortran
    C、C++、FORTRANのコンパイラをビルド対象とする。
  • disable-bootstrap
    ただし、クロスコンパイラ向けでは使用できないことに注意すること。
    3-stage bootstrap buildの無効化。
  • disable-multilib
    64bit専用コンパイラとする。(ただし、-m32オプションが使用できなくなる)
cd gcc-<バージョン>
mkdir build && cd build


# GCC 7.5以降かつパッケージ管理システムで依存関係のライブラリをインストールしている場合
../configure -v --build=x86_64-linux-gnu  \
                --host=x86_64-linux-gnu   \
                --target=x86_64-linux-gnu \
                --prefix=<GCCのインストールディレクトリ> \
                --program-suffix="_X_X"          \  # gcc, g++ のファイル名を一意に指定する場合
                --enable-languages=c,c++,fortran \  # C, C++, Fortranをインストールする場合
                --disable-bootstrap                 # 3-stage bootstrap buildを無効化する場合
make -j $(nproc)
make install-strip

# GCC 7.5以降かつ手動で依存関係のライブラリをインストールしている場合
../configure -v --build=x86_64-linux-gnu  \
                --host=x86_64-linux-gnu   \
                --target=x86_64-linux-gnu \
                --prefix=<GCCのインストールディレクトリ> \
                --program-suffix="_X_X"          \  # gcc, g++ のファイル名を一意に指定する場合
                --enable-checking=release        \
                --enable-languages=c,c++,fortran \  # C, C++, Fortranをインストールする場合
                --disable-bootstrap              \  # 3-stage bootstrap buildを無効化する場合
                --with-gmp=<GMP, MPC MPFR, ISLのインストールディレクトリ>  \
                --with-mpc=<GMP, MPC MPFR, ISLのインストールディレクトリ>  \
                --with-mpfr=<GMP, MPC MPFR, ISLのインストールディレクトリ> \
                --with-isl=<GMP, MPC MPFR, ISLのインストールディレクトリ>

unset LIBRARY_PATH CPATH C_INCLUDE_PATH PKG_CONFIG_PATH CPLUS_INCLUDE_PATH INCLUDE
export LD_LIBRARY_PATH=/<GMP, MPC MPFR, ISLのインストールディレクトリ>/lib64

make -j $(nproc)
make install

# GCC 6.5以前かつパッケージ管理システムで依存関係のライブラリをインストールしている場合
../configure -v --build=x86_64-linux-gnu  \ 
                --host=x86_64-linux-gnu   \
                --target=x86_64-linux-gnu \
                --prefix=<GCCのインストールディレクトリ> \
                --program-suffix="_X_X"          \  # gcc, g++ のファイル名を一意に指定する場合
                --enable-checking=release        \
                --enable-languages=c,c++,fortran \  # C, C++, Fortranをインストールする場合
                --disable-bootstrap              \  # 3-stage bootstrap buildを無効化する場合
                --disable-libsanitizer           \
                --disable-libcilkrts
make -j $(nproc)
make install-strip


インストールしたGCCへ環境変数のパスを通す。

vi ~/.profile

# .profileファイル
export export PATH="/<GCCのインストールディレクトリ>/bin:$PATH"
export LD_LIBRARY_PATH="/<GCCのインストールディレクトリ>/lib64:$LD_LIBRARY_PATH"


最後に、PCを再起動する。

GCCの設定

GCCをソースコードからインストールした場合、共有ライブラリが/<GCCのインストールディレクトリ>/lib64に作成されるが、環境変数のパスが設定されていない。
そのため、以下に示すいずれかの方法で環境変数のパスを通す必要がある。

  • システム全体に設定する場合
    /etc/ld.so.confファイル
  • ユーザごとに設定する場合
    ~/.profileファイル等
    環境変数LD_LIBRARY_PATHを設定する。


システム全体に設定する場合

/etc/ld.so.confファイルに/<GCCのインストールディレクトリ/lib64を追記することで、システム全体がライブラリを認識する。

sudo vi /etc/ld.so.conf


# /etc/ld.so.confファイル

/<GCCのインストールディレクトリ/lib64


設定を反映させる。

ldconfig -v


ldconfigコマンドを実行した時に表示される情報から、
以下に示すように、/<GCCのインストールディレクトリ/lib64ディレクトリが読み込まれていることを確認する。

/<GCCのインストールディレクトリ>/lib64:
ldconfig: /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py is not an ELF file - it has the wrong magic bytes at the start.

       libatomic.so.1 -> libatomic.so.1.2.0
       libitm.so.1 -> libitm.so.1.0.0
       libgomp.so.1 -> libgomp.so.1.0.0
       libquadmath.so.0 -> libquadmath.so.0.0.0
       libssp.so.0 -> libssp.so.0.0.0
       libmpxwrappers.so.2 -> libmpxwrappers.so.2.0.1


ldconfigコマンドを実行した結果、以下に示すようなメッセージが表示される場合がある。

ldconfig: /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py is not an ELF file - it has the wrong magic bytes at the start.


これは、libstdc++.so.6.0.25-gdb.pyは、pythonのスクリプトであるが、これを共有ライブラリとして認識していることが原因である。

file /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py

/<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py: Python script, ASCII text executable


対処方法としては、該当ファイルの名前を変更して、共有ライブラリと認識されないようする。

mv /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py  /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.25-gdb.py_org


再度、ldconfigコマンドを実行する。

ldconfig -v


また、RHELおよびSUSEの場合、/etc/ld.so.confファイルにinclude ld.so.conf.d/*.confと設定されている。
これは、ld.so.conf.dディレクトリ内のconf拡張子をもつファイルの内容を読み込むという意味である。

システム全体に共有ライブラリのパスを設定するには、/etc/ld.so.conf.dディレクトリ内に該当するライブラリが存在するパスを記述した設定ファイルを作成する。

以下の例では、/etc/ld.so.conf.d/00-libstdc++.confファイルを作成している。

sudo vi /etc/ld.so.conf.d/00-libstdc++.conf


# 00-libstdc++.confファイル

/<GCCのインストールディレクトリ>/lib64


設定を反映させる。

ldconfig -v


各ユーザごとに設定する場合

この方法は、ユーザごとに設定する必要がある。

~/.profileファイル等に環境変数LD_LIBRARY_PATHを設定することにより、ユーザがログインする際に設定が読み込まれる。

vi ~/.profile


 # ~/.profileファイル
 
 export LD_LIBRARY_PATH="/<GCCのインストールディレクトリ>/lib64:$LD_LIBRARY_PATH"


上記の設定を反映させるため、PCを再起動または再ログインする。

libstdc++を入れ替える場合

この手順を行う場合、システムが不安定になる可能性があることに注意する。

現在のlibstdc++の対応関係を確認する。

strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX


インストールしたGCCのlibstdc++.so.<バージョン名>をコピーする。

sudo cp /<GCCのインストールディレクトリ>/lib64/libstdc++.so.6.0.28 /usr/lib64


/usr/lib64ディレクトリにあるlibstdc++.so.6ファイルのバージョンを確認する。

ls -ahlF /usr/lib64/libstd*


libstdc++.so.6ファイルを入れ替える。

sudo mv /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6_org
sudo ln -s /usr/lib64/libstdc++.so.<バージョン名> /usr/lib64/libstdc++.so.6


正常にコピーできたか確認する。

ls -ahlF /usr/lib64/libstd*


入れ替えたlibstdc++の対応関係を確認する。

strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX



クロスコンパイラ向けGCCツールチェーンのインストール

クロスコンパイラ向けGCCツールチェーンとは

クロスコンパイラ向けGCCツールチェインは、C/C++、アセンブリ言語のためのオープンソースのツール群である。
これは、各アーキテクチャのプロセッサを対象として実装している。

共通 (ホスト側)

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

sudo zypper install expect-devel gmp-devel mpc-devel mpfr-devel


PinePhone (AArch64) (システムルートあり)

まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


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

mkdir build && cd build


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

../configure CFLAGS="-g0 -O3 -fstack-protector-strong"       \  # バッファオーバーフロー攻撃に対する中程度の保護を有効化
             CXXFLAGS="-g0 -O3 -fstack-protector-strong"     \  # バッファオーバーフロー攻撃に対する中程度の保護を有効化
             --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu \
             --host=x86_64-pc-linux-gnu  \
             --target=aarch64-linux-gnu  \
             --disable-gdb               \  # GDBサポートを無効化
             --disable-nls               \  # 国際化サポートを無効化
             --disable-multilib          \  # マルチライブラリサポートを無効化
             --disable-werror            \  # 警告をエラーとして扱わない
             --enable-gold               \  # GOLDリンカを有効化 (高速な代替リンカ)
             --enable-lto                \  # リンク時最適化を有効化
             --enable-plugins            \  # プラグインサポートを有効化
             --enable-relro              \  # RELROセキュリティ機能を有効化 (リロケーションの読み取り専用化)
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install


次に、GCCの公式Webサイトにアクセスして、GCCのソースコードをダウンロードして解凍する。
または、以下のコマンドを実行してダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-<バージョン>/gcc-<バージョン>.tar.xz
tar xf gcc-<バージョン>.tar.xz
cd gcc-<バージョン>


クロスコンパイラ向けGCCをビルドおよびインストールする。
クロスコンパイラ向けGCCをビルドする場合、ネイティブ向けGCCとバージョンを合わせた方がよい。

export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH" && \
CC=<ネイティブ向けGCCのパス> CXX=<ネイティブ向けG++のパス>             \
../configure -v                                             \
             CFLAGS="-g0 -O3 -fstack-protector-strong"      \
             CXXFLAGS="-g0 -O3 -fstack-protector-strong"    \
             --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu \
             --host=x86_64-pc-linux-gnu  \
             --target=aarch64-linux-gnu  \
             --enable-languages=c,c++    \
             --disable-bootstrap         \
             --disable-multilib          \
             --disable-nls               \
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install-strip


Rsdpberry Pi 32bit (システムルートあり)

まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


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

mkdir build && cd build


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

# Raspberry Pi Zero / 1 の場合
export ARCH=armv6
export FPU=vfp

# Raspberry Pi 2
export ARCH=armv7-a
export FPU=neon-vfpv4

# Raspberry Pi 3B の場合
export ARCH=armv8-a
export FPU=vfp

# Raspberry Pi 3B+ / 4B の場合
export ARCH=armv8-a
export FPU=vfp  または  export FPU=neon-fp-armv8

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>
             --build=x86_64-pc-linux-gnu  \
             --host=x86_64-pc-linux-gnu   \
             --target=arm-linux-gnueabihf \
             --disable-nls                \
             --disable-werror             \
             --disable-multilib           \
             --with-arch=$ARCH            \
             --with-fpu=$FPU              \
             --with-float=hard            \
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install


次に、GCCの公式Webサイトにアクセスして、GCCのソースコードをダウンロードして解凍する。
または、以下のコマンドを実行してダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-<バージョン>/gcc-<バージョン>.tar.xz
tar xf gcc-<バージョン>.tar.xz
cd gcc-<バージョン>


クロスコンパイラ向けGCCをビルドおよびインストールする。

# Raspberry Pi Zero / 1 の場合
export ARCH=armv6
export FPU=vfp

# Raspberry Pi 2
export ARCH=armv7-a
export FPU=neon-vfpv4

# Raspberry Pi 3B の場合
export ARCH=armv8-a
export FPU=vfp

# Raspberry Pi 3B+ / 4B の場合
export ARCH=armv8-a
export FPU=vfp  または  export FPU=neon-fp-armv8

export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH"

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu  \
             --host=x86_64-pc-linux-gnu   \
             --target=arm-linux-gnueabihf \
             --enable-languages=c,c++ \
             --disable-multilib       \
             --with-arch=$ARCH        \
             --with-fpu=$FPU          \
             --with-float=hard        \
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install-strip


Rsdpberry Pi 64bit (システムルートあり)

まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


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

mkdir build && cd build


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

# Raspberry Pi 3B /3B+
export ARCH=armv8-a
export CPU=cortex-a53  # 最適化のためにオプションを調整することができる

# Raspberry Pi 4B
export ARCH=armv8-a
export CPU=cortex-a72  # 最適化のためにオプションを調整することができる

# Raspberry Pi 5の場合
export ARCH=armv8-a+crc+simd
export CPU=cortex-a76  # 最適化のためにオプションを調整することができる

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>
             --build=x86_64-pc-linux-gnu \
             --host=x86_64-pc-linux-gnu  \
             --target=aarch64-linux-gnu  \
             --disable-multilib          \
             --with-arch=$ARCH           \
             --with-cpu=$CPU             \  # 省略可能
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install


次に、GCCの公式Webサイトにアクセスして、GCCのソースコードをダウンロードして解凍する。
または、以下のコマンドを実行してダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-<バージョン>/gcc-<バージョン>.tar.xz
tar xf gcc-<バージョン>.tar.xz
cd gcc-<バージョン>


クロスコンパイラ向けGCCをビルドおよびインストールする。

# Raspberry Pi 3B /3B+
export ARCH=armv8-a
export CPU=cortex-a53  # 最適化のためにオプションを調整することができる

# Raspberry Pi 4B
export ARCH=armv8-a
export CPU=cortex-a72  # 最適化のためにオプションを調整することができる

# Raspberry Pi 5の場合
export ARCH=armv8-a+crc+simd
export CPU=cortex-a76  # 最適化のためにオプションを調整することができる

export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH"

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu \
             --host=x86_64-pc-linux-gnu  \
             --target=aarch64-linux-gnu  \
             --enable-languages=c,c++    \
             --disable-multilib          \
             --with-arch=$ARCH           \
             --with-cpu=$CPU             \  # 省略可能
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install-strip


RISC-V 64bit (システムルートあり)

まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


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

mkdir build && cd build


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>
             --build=x86_64-pc-linux-gnu        \
             --host=x86_64-pc-linux-gnu         \
             --target=riscv64-unknown-linux-gnu \
             --disable-nls                      \
             --disable-werror                   \
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install


次に、GCCの公式Webサイトにアクセスして、GCCのソースコードをダウンロードして解凍する。
または、以下のコマンドを実行してダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-<バージョン>/gcc-<バージョン>.tar.xz
tar xf gcc-<バージョン>.tar.xz
cd gcc-<バージョン>


export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH"

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu        \
             --host=x86_64-pc-linux-gnu         \
             --target=riscv64-unknown-linux-gnu \
             --enable-languages=c,c++           \
             --disable-multilib                 \
             --disable-nls                      \
             --with-sysroot=<ターゲットのシステムルートディレクトリ>

make -j $(nproc)
make install-strip


RISC-V 64bit (Newlibを使用する場合)

まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


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

mkdir build && cd build


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>
             --build=x86_64-pc-linux-gnu  \
             --host=x86_64-pc-linux-gnu   \
             --target=riscv64-unknown-elf \
             --disable-nls                \
             --disable-werror

make -j $(nproc)
make install


次に、GCCの初期ビルドを行う。
GCCの公式Webサイトにアクセスして、GCCのソースコードをダウンロードして解凍する。
または、以下のコマンドを実行してダウンロードする。

wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-<バージョン>/gcc-<バージョン>.tar.xz
tar xf gcc-<バージョン>.tar.xz
cd gcc-<バージョン>


export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH"

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu  \
             --host=x86_64-pc-linux-gnu   \
             --target=riscv64-unknown-elf \
             --enable-languages=c         \  # まず、最小限のGCCコンパイラを生成する
                                             # このコンパイラはC言語のみをサポートし、標準ライブラリなしで動作可能
             --disable-multilib           \
             --disable-nls                \
             --without-headers            \  # ターゲットのシステムヘッダを使用せずにビルド
             --with-newlib                   # 組み込みシステム向けのC標準ライブラリNewlibを使用

#  GCCの一部のみをビルドおよびインストール
make all-gcc -j $(nproc)
make install-gcc


Newlibを使用する場合、Newlibのソースコードが必要になる。
Newlibの公式Webサイト、または、NewlibのGithubにアクセスして、Newlibのソースコードをダウンロードする。
もし、Newlibの公式Webサイトからファイルをダウンロードできない場合は、wgetコマンド等を使用する、あるいは、Githubからダウンロードする。

wget ftp://sourceware.org/pub/newlib/newlib-<バージョン>.tar.gz


ダウンロードしたファイルを解凍する。

tar xf newlib-<バージョン>.tar.gz


Newlibとは、組み込みシステムやベアメタル環境向けの軽量なC標準ライブラリ実装である。
GCCと一緒に使用することにより、完全なクロスコンパイル環境を構築できる。

Newlibを使用する理由は以下の通りである。

  • 軽量
    組み込みシステムや制限のあるハードウェア向けに最適化されている。
  • 移植性
    多くのアーキテクチャをサポートしている。
  • カスタマイズ性
    特定のターゲット向けに容易にカスタマイズできる。


mkdir build && cd build

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --target=riscv64-unknown-elf

make -j $(nproc)
make install


GCCの最終ビルドを行う。

export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH"

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu  \
             --host=x86_64-pc-linux-gnu   \
             --target=riscv64-unknown-elf \
             --enable-languages=c,c++     \  # 完全な機能を持つGCC (最終ビルド) を生成
             --disable-multilib           \
             --disable-nls                \
             --without-headers            \  # ターゲットのシステムヘッダを使用せずにビルド
             --with-newlib                \  # 組み込みシステム向けのC標準ライブラリNewlibを使用
             --with-sysroot=/<Newlibのインストールディレクトリ>/riscv64-unknown-elf  # Newlibのヘッダファイルとライブラリの場所を指定

make all -j $(nproc)
make install


H8 (システムルート無し)

※注意 1
H8向けのGCCのターゲットには、h8300-hms(coffと同じ)とh8300-elfがあり,バイナリフォーマットが異なることに注意する。

※注意 2
GCC 9.1以降は、共有ライブラリとしてC++(libstdc++)をビルドすると失敗するため、C言語のみの対応となる。
スタティックライブラリとしてはビルド可能であるが、その場合、例えば、#inlcude <iostream>のインクルードができなくなる。

共有ライブラリとしてビルド不可の理由としては、ビット数を管理するソースコードファイルにおいて、
std::size_tの配列が、H8アーキテクチャ上ではstd::size_tのビット長が短いため、配列の要素が格納できないからである。
また、C++17のメモリ管理機構において、コンパイル時のstatic_assertに失敗する。

GCC 8.5では、GCCのMakefileに手を加えることにより、C言語およびC++言語を対応させることができる。
通常、ビルドを行う場合、basic_string.hファイルにおいて、internal compiler error: unrecognizable insnとしてエラーになる。
これは、C++向けライブラリをビルドするためのxgccにおいて、内部エラーが起きているからである。
しかし、ビルドディレクトリにあるh8300-elfディレクトリ内のMakefileファイルの526行目 CXXFLAGS_FOR_TARGET-g -O0に変更する(最適化を無効にする)ことにより、ビルド可能となる。

H8 GCCツールチェーンのビルドには32ビットGCCライブラリも必要であるため、以下に示すライブラリもインストールする。

sudo zypper install glibc-devel-32bit


まず、GNUの公式Webサイトから、Binutilsをダウンロードする。
ダウンロードしたファイルを解凍する。

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


クロスコンパイラ向けBinutilsのビルドおよびインストールする。
インストールディレクトリは、クロスコンパイラ向けGCCのインストールディレクトリと同じディレクトリであることに注意する。

mkdir build && cd build

../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ> \
             --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=h8300-elf \
             --disable-gdb --disable-nls --disable-multilib --disable-werror \
             --enable-lto
make -j $(nproc)
make install


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

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


さらに、Newlibの公式Webサイト、または、NewlibのGithubにアクセスして、Newlibのソースコードをダウンロードする。
もし、Newlibの公式Webサイトからファイルをダウンロードできない場合は、wgetコマンド等を使用してダウンロードする。

wget ftp://sourceware.org/pub/newlib/newlib-<バージョン>.tar.gz


ただし、現在(2022年11月現在)、Newlibの公式Webサイトからダウンロードしたファイルを使用するとビルドに失敗するため、Githubからダウンロードすること。

ダウンロードしたファイルを解凍する。

tar xf newlib-<バージョン>.tar.gz


クロスコンパイラ向けGCC(1度目は、gccファイルのみ)をビルドおよびインストールする。
クロスコンパイラ向けGCCをビルドする場合、ネイティブ向けGCCとバージョンを合わせた方がよい。

# GCC ビルド ステージ:1
cd <GCCのソースコードがあるディレクトリ>
mkdir build && cd build

# GCC 8.5以前
export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH" && \
CC=<ネイティブ向けGCCのパス> CXX=<ネイティブ向けG++のパス> \
../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>  \
             --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=h8300-elf \
             --enable-languages=c,c++ \
             --disable-bootstrap --disable-nls --disable-werror --enable-lto --enable-gold \
             --with-newlib \
             --with-headers=/<上記でダウンロードしたNewlibのディレクトリ>/newlib/libc/include
make -j $(nproc)
make install

# GCC 9.1以降
export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH" && \
CC=<ネイティブ向けGCCのパス> CXX=<ネイティブ向けG++のパス> \
../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>  \
             --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=h8300-elf \
             --enable-languages=c \
             --disable-bootstrap --disable-nls --disable-shared --enable-static --enable-lto --enable-gold \
             --with-newlib \
             --with-headers=/<上記でダウンロードしたNewlibのディレクトリ>/newlib/libc/include
make -j $(nproc)
make install


次に、Newlibをビルドおよびインストールする。

mkdir build && cd build

export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH" && \
CC=<ネイティブ向けGCCのパス> CXX=<ネイティブ向けG++のパス> \
../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>  \
             --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=h8300-elf
make -j $(nproc)
make install


最後に、クロスコンパイラ向けGCC(2度目は、g++ファイルのみ)をビルドおよびインストールする。

# GCC ビルド ステージ:2
cd <GCCのソースコードがあるディレクトリ>/build

# GCC 8.5以前は不要

# GCC 9.1以降
export PATH="/<上記でインストールしたBinutilsのインストールディレクトリ>/bin:$PATH" && \
CC=<ネイティブ向けGCCのパス> CXX=<ネイティブ向けG++のパス> \
../configure --prefix=<クロスコンパイラ向けGCCのインストールディレクトリ>  \
             --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=h8300-elf \
             --enable-languages=c,c++ \
             --disable-bootstrap --disable-nls --disable-shared --enable-static --disable-libstdc__-v3 --enable-lto --enable-gold \
             --with-newlib \
             --with-headers=/<上記でダウンロードしたNewlibのディレクトリ>/newlib/libc/include
make -j $(nproc)
make install



GCC ARMツールチェーンの使用方法

GCC ARMツールチェーンとは

Cortex-A向けGNUツールチェインは、C/C++、アセンブリ言語のためのオープンソースのツール群である。
これは、Cortex-Aファミリのプロセッサを対象としており、Arm Aプロファイルアーキテクチャを実装している。
このツールチェーンにはGCCが含まれており、WindowsおよびLinux向けに無償で提供されている。

GCC ARMツールチェーンのダウンロード

Cortex-Aファミリ

ARMの公式Webサイトから、ユーザの環境に合うバージョンをダウンロードする。
GCC ARMを解凍して、適切なディレクトリに配置する。

Raspberry Pi

Raspberry Pi向けにクロスコンパイルする場合は、下表を参考にして、ユーザの環境に合ったGCC ARMツールチェーンをダウンロードする。
https://sourceforge.net/projects/raspberry-pi-cross-compilers/files/Raspberry%20Pi%20GCC%20Cross-Compiler%20Toolchains/

表. Raspberry Pi専用GCC ARMツールチェーンのダウンロード
Raspberry Piの種類 Raspbian Stretch(32-bit) Raspbian Buster(32-bit) Raspbian Bullseye(32-bit)
Raspberry Pi Zero/W/WH
Raspberry Pi 1 Model A / B / A+ / B+
6.3.0
9.3.0
10.2.0
8.3.0
9.3.0
10.2.0
10.2.0
10.3.0
Raspberry Pi 2 Model A / B
Raspberry Pi 3 Model A / B
6.3.0
9.3.0
10.2.0
8.3.0
9.3.0
10.2.0
10.2.0
10.3.0
Raspberry Pi 3 Model A+ / B+
Raspberry Pi 4 Model A+ / B+
Raspberry Pi Compute 3 / 3lite / 3+
6.3.0
8.3.0
10.2.0
8.3.0
9.3.0
10.2.0
10.2.0
10.3.0


上表は、Raspbian OS 32bit向けのGCC ARMツールチェインであるが、Raspbian OS 64bit向けのGCC ARMツールチェインが必要な場合は、以下に示すURLにアクセスする。
https://sourceforge.net/projects/raspberry-pi-cross-compilers/files/Bonus%20Raspberry%20Pi%20GCC%2064-Bit%20Toolchains/Raspberry%20Pi%20GCC%2064-Bit%20Cross-Compiler%20Toolchains/

また、Raspberry Pi向けには、Linaro社が提供しているGCC ARMツールチェインを使用することもできる。


※注意
クロスコンパイラのlibstdc++.so.6ファイルにおいて、Raspberry Pi OSのlibstdc++.so.6ファイルのバージョンと同等または古いものを使用する必要がある。
例えば、Raspberry Pi OS Bullseyeのlibstdc++.so.6ファイルはGLIBCXX_3.4.28までであるため、GCC 10ツールチェーン、または、それ以前のものを使用する。
また、Raspberry Pi OS Bookwormのlibstdc++.so.6ファイルはGLIBCXX_3.4.30までであるため、GCC 12ツールチェーン、または、それ以前のものを使用する。

GCC ARMツールチェーンを使用したコンパイル

Cortex-Aファミリ

以下の例では、ARMの公式WebサイトからダウンロードしたGCC ARMツールチェーンを使用して、
任意のソフトウェアをCortex-Aファミリ向けにビルドしている。

もし、configureスクリプトを実行する時、undefined reference to 'rpl_malloc'というエラーが表示される場合は、
ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yesオプションを付加する。
これは、autotoolsの仕様で、GLIBC以外のシステム(例. uClibc等)を使用しているからである。

# 32bit Cortex-A (Hard Float) 向けにビルドする場合
ac_cv_func_malloc_0_nonnull=yes  \
ac_cv_func_realloc_0_nonnull=yes \
../configure --prefix=<ソフトウェアのインストールディレクトリ>                             \
             CC=/<GCC_ARMのインストールディレクトリ>/bin/arm-none-linux-gnueabihf-gcc  \
             CXX=/<GCC_ARMのインストールディレクトリ>/bin/arm-none-linux-gnueabihf-g++ \
             --build=x86_64-unknown-linux-gnu                                  \
             --host=arm-none-linux-gnueabihf                                   \
             --target=arm-none-linux-gnueabihf                                 \
             --with-sysroot=/<GCC_ARMのインストールディレクトリ>/arm-none-linux-gnueabihf/libc \
             --with-gnu-ld

make -j $(nproc) LDFLAGS="-L/<GCC_ARMのインストールディレクトリ>/arm-none-linux-gnueabihf/lib" \
                 CFLAGS="-I/<GCC_ARMのインストールディレクトリ>/arm-none-linux-gnueabihf/include"
make install


# 64bit Cortex-A向けにビルドする場合
ac_cv_func_malloc_0_nonnull=yes  \
ac_cv_func_realloc_0_nonnull=yes \
../configure --prefix=<ソフトウェアのインストールディレクトリ>                           \
             CC=/<GCC_ARMのインストールディレクトリ>/bin/aarch64-none-linux-gnu-gcc  \
             CXX=/<GCC_ARMのインストールディレクトリ>/bin/aarch64-none-linux-gnu-g++ \ 
             --build=x86_64-unknown-linux-gnu                                \
             --host=aarch64-none-linux-gnu                                   \
             --target=aarch64-none-linux-gnu                                 \
             --with-sysroot=/<GCC_ARMのインストールディレクトリ>/aarch64-none-linux-gnu/libc \
             --with-gnu-ld

make -j $(nproc) LDFLAGS="-L/<GCC_ARMのインストールディレクトリ>/aarch64-none-linux-gnu/lib64" \
                 CFLAGS="-I/<GCC_ARMのインストールディレクトリ>/aarch64-none-linux-gnu/include"
make install


Raspberry Pi

以下の例では、SourceForgeからダウンロードしたRaspberry Pi専用のGCC ARMツールチェーンを使用して、
任意のソフトウェアをRaspberry Pi向けにビルドしている。

# Raspberry Pi OS 32ビットの場合
ac_cv_func_malloc_0_nonnull=yes  \
ac_cv_func_realloc_0_nonnull=yes \
../configure --prefix=<ソフトウェアのインストールディレクトリ>                        \
             CC=/<GCC_ARMのインストールディレクトリ>/bin/arm-linux-gnueabihf-gcc  \
             CXX=/<GCC_ARMのインストールディレクトリ>/bin/arm-linux-gnueabihf-g++ \
             --build=x86_64-unknown-linux-gnu \
             --host=arm-linux-gnueabihf       \
             --target=arm-linux-gnueabihf

make -j $(nproc)
make install


# Raspberry Pi OS 64ビットの場合
../configure --prefix=<ソフトウェアのインストールディレクトリ>                      \
             CC=/<GCC_ARMのインストールディレクトリ>/bin/aarch64-linux-gnu-gcc  \
             CXX=/<GCC_ARMのインストールディレクトリ>/bin/aarch64-linux-gnu-g++ \
             --build=x86_64-unknown-linux-gnu \
             --host=aarch64-linux-gnu         \
             --target=aarch64-linux-gnu

make -j $(nproc)
make install



C++14 / C++17のサンプルコード

C++14では、ラムダ式のパラメータのタイプにautoが使用できる。

 // sample.cpp
 
 #include <iostream>
  
 int main()
 {
    std::cout << [](auto a, auto b) { return a + b; } (5, 6) << std::endl;
    std::cout << [](auto a, auto b) { return a + b; } (5.23, 6.45) << std::endl;
    return 0;
 }


# 実行
g++-10.1 -Wall -pedantic sample.cpp -o sample
./sample

# 出力
11
11.68


このページの冒頭で述べたように、GCC 10.1は、C++17を完全にサポートしている。
以下の例では、static_assertへのC++17変更の使用例をテストしている。

 // sample.cpp
 
 #include <type_traits>
 #include <iostream>
  
 struct A
 {
    int foo;
 };
 
 struct B
 {
    int foo = 0;
 };
  
 template <typename T>
 void print(const T& a)
 {
    static_assert(std::is_pod<T>::value);
    std::cout << a.foo << '\n';
 }
  
 int main()
 {
    A x{1};
    B y{2};
    B z;
 
    print<A>(x);
    print<B>(y);
    print<B>(z);
 
    return 0;
 }


コンパイルを行うには、-std=c++17オプションを付与する。
また、上記のコードの17行目と24行目でトリガーされたコンパイルエラーが表示される。

# 実行
g++-10.1 -std=c++17 -Wall -pedantic sample.cpp -o sample

# 出力
sample.cpp: In instantiation of ‘void print(const T&) [with T = B]’:
sample.cpp:24:13:   required from here
sample.cpp:14:33: error: static assertion failed
    17 |   static_assert(std::is_pod<T>::value);


もし、C++11の構文の詳細に興味がある場合は、Bjarne StroustrupによるC++プログラミング言語を読むことを推奨する。