gcc8.2.0をソースからビルドした

環境構築がうまくいかないとつらいものです。うまくいったという情報がweb上にあるだけで助かったりします。

うまくいったので記録に残しておきます。

gcc8.2.0, x86向け

制約

  • 管理者ではないので/bin/とかそういうところにはインストールできません。/home/lpha/gcc82/以下にインストールすることにします。
  • もともとインストールされているgcc(というよりはデフォルトで指定されているアセンブラのas 2.25.1)のバージョンが低く*1-march=nativeコンパイルすると知らない命令だとエラーを出します*2。この部分を改善したいです。

方法

  • configureスクリプトのオプションとして、--prefix=/home/lpha/gcc82(最後にスラッシュがあってもなくても同じ)とつけることで、インストールパスを指定できます。
  • GNU binutilsも新しいものをインストールすることで、-march=nativeをつけてもアセンブラがエラーを出さないようにすることができます。

おおざっぱな手順

  1. GNU binutilsをインストールします。これにより、Haswell向けの命令をアセンブルすることができるアセンブラが手に入ります。
  2. もとからあるgccでgcc8.2.0を、Haswell向けの最適化なしでコンパイルし、gcc8.2.0(Haswell特有の命令を使わずに動作するプログラムになっている。Haswell特有の命令を出力できるコンパイラになっている*3)を手に入れます。
  3. 先ほどの成果物でもう一度gcc8.2.0をコンパイルすることでHaswell向けに最適化されたgcc8.2.0を得ることができます。
  4. さらにその成果物でもう一度gcc8.2.0をコンパイルしたとき、同じものが得られることをもって、サニティチェック(念のための確認)とします。

3.の手順は省略可能ですが、コンパイル速度は速い方がいいので最適化されたgccを手に入れることは意義があります。4.の手順も省略可能ですが、3ステージビルドの手順に従う方が楽です。一度のmakeコマンドで2.3.4.の手順が一気に行われます。代わりに三倍の時間がかかることは覚悟しなければなりません。

コマンド

wget https://ftp.gnu.org/gnu/binutils/binutils-2.31.tar.gz
wget http://ftp.gnu.org/gnu/gcc/gcc-8.2.0/gcc-8.2.0.tar.gz
tar xf binutils-2.31.tar.gz 
tar xf gcc-8.2.0.tar.gz & # 時間かかるから先に仕掛けておく、binutilsをmakeしている辺りで終わるはず
cd binutils-2.31
mkdir build
cd build
../configure --prefix=/home/lpha/gcc82/
make -j # 12スレッドで100秒くらい
make install -j
cd ..
cd ..
cd gcc-8.2.0
contrib/download_prerequisites
mkdir build
cd build
../configure --enable-languages=c,c++ --prefix=/home/lpha/gcc82/ --disable-multilib
make -j STAGE1_CFLAGS='-march=corei7-avx -O3' BOOT_CFLAGS='-march=native -O3'" # かかる時間は、ほとんどIO性能で決まる
make install

注意点

  • 二つの./configureで指定する--prefixは同じにすること
  • ./configureなどと、configureスクリプトをtarball(.tar.gzファイル)を展開したディレクトリ直下でやらない(buildディレクトリを作るなどする)こと
  • 逆に、contrib/download_prerequisitesはtarballを展開したディレクトリ直下で行うこと(contribディレクトリに入ってはいけない)

オプションについて

多くの「gccをソースからビルドしてみた」記事では、ブートストラップ(3回ビルドするやつ)をやっておらず、どのようにオプションを設定するべきかが分かりません。

以下の記事は3ステージビルドのオプションについても詳しく解説されており、有用でした。

CentOS6.xでGCC5.2をOS標準の4.4.7と共存できるようにソースビルドした - Qiita

gcc8.2.0, RV64GC

要するに、クロスコンパイラの作成です。

RV64GCとは、RISC-Vという命令セットアーキテクチャの64bit版で、使える命令セットがGeneral Instructions(整数系命令(I)・乗除算命令(M)・アトミック命令(A)・単精度浮動小数点数演算命令(F)・倍精度浮動小数点演算命令(D)の全部が使える)+Compressed Instructions(命令の長さが32bitではなく16bitの命令群)だということを示しています。

制約

  • Linux subsystem for Windowsを使って行ったので、sudo apt-get install ...などが使えます。
  • インストール先は、/home/lpha/rv64gc/以下にします。

コマンド

git clone --recursive https://github.com/riscv/riscv-gnu-toolchain # 30分くらいかかる
cd riscv-gnu-toolchain
sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev

texinfoが、バージョンの依存関係の制約を満たせないと怒られましたが、aptitudeコマンドに促されるまま、一部の依存ライブラリのバージョンをダウングレードして通しました。もっとうまい方法はあったのでしょうか……?

./configure --prefix=/home/lpha/rv64gc
make linux -j # 8スレッドで45分

依存関係の問題を解決するのに多少手間取りましたが、それ以外には難しいところはありませんでした。

*1:as 2.25.1が出たのは2014年、Haswellが発売されたのは2013年6月なのになぜ対応していないのでしょう?

*2:しかし一部のAVX2命令には対応している

*3:これはgcc8.2.0をコンパイルしたのとはあまり関係なく、デフォルトで使用するアセンブラが先ほどインストールした新しいasになっていることが重要です