トップ > 最小システムの構築 > 新システムの作成(後半) >
GCC

  

GCCのビルド

GCCは、GNUプロジェクトによる各種プログラミング言語用のコンパイラ群です。 当初はC言語用のコンパイラでしたが、現在は、C++、Java、Fortranなど多くの言語に対応しています。

ビルド・インストール前リストの生成

最初に、ビルド・インストール前リストを生成します。


/sources/genprevlist.sh > /dev/null 2>&1

 

ソースファイルの展開

ソースファイルを展開します。


cd /sources
tar xvf gcc-4.9.2.tar.bz2
cd gcc-4.9.2

 

ビルド用ディレクトリの準備

ビルド用ディレクトリを準備します。


mkdir -vp ../gcc-build
cd ../gcc-build

 
  
GCCでは、ソースファイルが置かれているディレクトリでのビルドは推奨されていません。 別にビルド用のディレクトリを用意し、そこでビルドを行うことが推奨されています。

configure

configureを実行します。


../gcc-4.9.2/configure \
  --prefix=/usr \
  --enable-languages=c,c++ \
  --disable-multilib \
  --disable-bootstrap \
  --with-system-zlib > ../../logs/configurelog.gcc 2>&1

 

configureが終了したら、ログファイルに出力された内容を参照し、正常に終了したことを確認します。


cat ../../logs/configurelog.gcc

 

ビルド

ビルドを実行します。


make

 

ビルドが終了したら、画面に出力された内容を参照し、正常に終了したことを確認します。

テスト

テストを行います。


ulimit -s 65536
make -k check 2>&1 | tee ../../logs/checklog.gcc

 

テストが終了したら、ログファイルに出力された内容を参照し、正常に終了したことを確認します。


grep '^# of' ../../logs/checklog.gcc \
  | sed \
    -e '/# of expected passes/s/^/OK /' \
    -e '/# of unexpected passes/s/^/OK /' \
    -e '/# of expected failures/s/^/OK /' \
    -e '/# of unexpected successes/s/^/OK /' \
    -e '/# of unsupported tests/s/^/OK /' \
    -e '/# of untested testcases/s/^/OK /' \
    -e '/$^/d' \
  | sed \
    -e '/^# of/s/^/NG /' \
  | sort

 

上記の結果、全ての行の行頭が "OK" となっていれば問題ありません

なお、筆者の環境(仮想マシン)では以下のように30件のエラーが発生します

NG # of unexpected failures     12
NG # of unexpected failures     16
NG # of unexpected failures     2
OK # of expected failures               249
OK # of expected failures               3
OK # of expected failures               41
OK # of expected failures               443
OK # of expected passes         105573
OK # of expected passes         26
OK # of expected passes         44
OK # of expected passes         691
OK # of expected passes         87019
OK # of expected passes         9843
OK # of unexpected successes    2
OK # of unsupported tests               1
OK # of unsupported tests               1205
OK # of unsupported tests               274
OK # of unsupported tests               2798
OK # of unsupported tests               5

エラーが発生した場合は、以下を実行してどのテストでエラーが発生したのかを調べます。


grep '^FAIL' ../../logs/checklog.gcc

 
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -g  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -g  execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O1  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O1  execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O2 -std=c99  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O2 -std=c99  execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O2 -ftree-vectorize  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O2 -ftree-vectorize  execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O3 -g  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O3 -g  execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O3 -flto -g  execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O3 -flto -g  execution test
FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_HugeMallocTest Ident((char*)malloc(size))[-1] = 0 output pattern test
FAIL: g++.dg/cilk-plus/CK/catch_exc.cc  -O1 -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/catch_exc.cc  -O3 -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/catch_exc.cc  -g -fcilkplus execution test
FAIL: g++.dg/cilk-plus/CK/catch_exc.cc  -g -O2 -fcilkplus execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O1 execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O1 execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O3 execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O3 execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -g execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -g execution test
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -g -O2 execution test
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -g -O2 execution test
FAIL: g++.dg/ipa/pr61160-3.C -std=gnu++98 execution test
FAIL: g++.dg/ipa/pr61160-3.C -std=gnu++11 execution test
FAIL: g++.dg/ipa/pr61160-3.C -std=gnu++1y execution test
FAIL: libgomp.c/omp-loop03.c execution test
FAIL: libgomp.c++/loop-3.C execution test

上記のように、どのテストでエラーが発生したのかがわかります。

さらに、エラーの原因を調べます。 ログファイルを開き、"FAIL" で始まる行を探してエラーの原因を調べます。

なお、現在はチェンジルート中ですので、viエディタは使えません。 別途ログインし、チェンジルートせずに $MYLINUX/logs/checklog.gcc を開いてください。

  
チェンジルート用の chroot.sh は同時に実行できません。 絶対にチェンジルートしないように注意してください。
...(省略)...
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -g  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -g  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O1  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O1  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O2 -std=c99  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O2 -std=c99  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O2 -ftree-vectorize  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O2 -ftree-vectorize  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O3 -g  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O3 -g  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/spawning_arg.c  -O3 -flto -g  execution test
WARNING: program timed out.
FAIL: c-c++-common/cilk-plus/CK/steal_check.c  -O3 -flto -g  execution test
...(省略)...

上記のように、"FAIL" で始まる行の直前にはエラーの原因が表示されることがあります。

  
上記はログファイルの内容です。

なお、"program timed out." となっている場合はタイムアウトしています。 開発機の処理能力が低い場合には、テストの一部がタイムアウトすることがあります。

  
cilk-plus(インテル Cilk Plus : 並列コンピューティング)関連のタイムアウトエラーを回避するには、処理能力の高いマシンが必要なようです。 仮想マシンでは話になりませんし、実機でもかなり高性能のマシンが必要なようです。

また、g++.dg/ipa/pr61160-3.C についての3件のエラーは、GCC 4.9系の既知の不具合です。 この不具合については、不具合 #61820で報告されています。

インテル Cilk Plus関連のタイムアウトエラー、および上記の既知の不具合を除くと、筆者の環境(仮想マシン)では以下が残ります。

...(抜粋)...
FAIL: g++.dg/asan/asan_test.C  -O2  AddressSanitizer_HugeMallocTest Ident((char*)malloc(size))[-1] = 0 output pattern test
FAIL: libgomp.c/omp-loop03.c execution test
FAIL: libgomp.c++/loop-3.C execution test
...(抜粋)...
  
上記のエラーについては原因はわからなかったため筆者は無視して作業を続行しました

インストール

インストールを行います。


make install

 

インストールが終了したら、画面に出力された内容を参照し、正常に終了したことを確認します。

インストール後の追加作業

インストール後の追加作業を行います。 /usr/bin/cpp に /lib/cpp というシンボリックリンクを与えます。


ln -vsf ../usr/bin/cpp /lib

 

ソフトウェアの中には、cppのパスを/lib/cppとしてハードコーディングしているものもあります。 その参照が正常に行われるよう、シンボリックリンクを作成しています。

gcc に ccというシンボリックリンクを与えます。


ln -vsf gcc /usr/bin/cc

 

今後の作業でビルドするソフトウェアの中にはコンパイラを cc で呼び出すものもあるかもしれません。 そこで、gcc に cc という名称のシンボリックリンクを与えています。

LTOが機能するように追加インストールを行います。


mkdir -pv /usr/lib/bfd-plugins
ln -vsf ../../libexec/gcc/$(gcc -dumpmachine)/4.9.2/liblto_plugin.so /usr/lib/bfd-plugins/

 

LTOはリンク時の最適化(LTO : Link Time Optimization)の機能です。

ソースファイル付属文書のインストール

ソースファイルに付属している文書のインストールを行います。


cd ../gcc-4.9.2
mkdir -vp /usr/share/doc/gcc-4.9.2
cp -va ABOUT-NLS          /usr/share/doc/gcc-4.9.2
cp -va COPYING            /usr/share/doc/gcc-4.9.2
cp -va COPYING.LIB        /usr/share/doc/gcc-4.9.2
cp -va COPYING.RUNTIME    /usr/share/doc/gcc-4.9.2
cp -va COPYING3           /usr/share/doc/gcc-4.9.2
cp -va COPYING3.LIB       /usr/share/doc/gcc-4.9.2
cp -va ChangeLog          /usr/share/doc/gcc-4.9.2
cp -va ChangeLog.tree-ssa /usr/share/doc/gcc-4.9.2
cp -va LAST_UPDATED       /usr/share/doc/gcc-4.9.2
cp -va MAINTAINERS        /usr/share/doc/gcc-4.9.2
cp -va NEWS               /usr/share/doc/gcc-4.9.2
cp -va README             /usr/share/doc/gcc-4.9.2
cp -va INSTALL/README     /usr/share/doc/gcc-4.9.2
cp -va INSTALL/*.html     /usr/share/doc/gcc-4.9.2

 

後始末

ディスクを圧迫しないよう、ビルド用のディレクトリを削除します。


cd ..
rm -fr gcc-4.9.2
rm -fr gcc-build

 

インストールリストの生成

最後に、インストールリストを生成します。


/sources/genpostlist.sh > /dev/null 2>&1
/sources/gendifflist.sh gcc

 
  

開発ツールのテスト

新システム用のglibc、Binutils、GCCのビルド・インストールが終わりました。 ここでは、それらが正常に動作することを確認します

テスト用ソースファイルの作成

最初に、テスト用のソースファイルを作成します。


echo 'main(){}' > test.c

 

コンパイル・リンク

コンパイルおよびリンクを行います。


cc test.c -v -Wl,--verbose > test.log 2>&1

 
  
gcc ではなく cc でコンパイラを呼び出しています。

生成された実行ファイルのテスト

生成された実行ファイルの動作テストを行います。 共有ライブラリが、/lib から参照されていることを確認します。


readelf -l a.out | grep ': /lib'

 

以下が出力されることを確認します。

[Requesting program interpreter: /lib/ld-linux.so.2]

もし、/tools/libにある共有ライブラリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

crt1.o crti.o crtn.o が /usr/lib から検索されることを確認します。


grep '/usr/lib.*/crt[1in].*succeeded' test.log

 

以下が出力されることを確認します。

attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crt1.o succeeded
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crti.o succeeded
attempt to open /usr/lib/gcc/i686-pc-linux-gnu/4.9.2/../../../crtn.o succeeded

/usr/lib以外のディレクトリから検索されている場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

インクルードファイルの検索パスに /usr/include が含まれていることを確認します。


grep -B4 '^ /usr/include' test.log

 

以下が出力されることを確認します。

#include <...> search starts here:
 /usr/lib/gcc/i686-pc-linux-gnu/4.9.2/include
 /usr/local/include
 /usr/lib/gcc/i686-pc-linux-gnu/4.9.2/include-fixed
 /usr/include

/usr/include がインクルードファイルの検索パスに含まれていない場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

ライブラリの検索パスに /lib および /usr/lib が含まれていることを確認します。


grep 'SEARCH.*/usr/lib' test.log | sed -e 's|; |\n|g' | sed -e '/-linux-gnu/d' | sort

 

以下が出力されることを確認します。

SEARCH_DIR("/lib")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib");
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/usr/local/lib32")

/lib および /usr/lib がライブラリの検索パスに含まれていない場合は、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということです

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

標準Cライブラリの共有ライブラリが、/lib から参照されていることを確認します。


grep "/lib.*/libc.so.6 " test.log

 

以下が出力されることを確認します。

attempt to open /lib/libc.so.6 succeeded

もし、/tools/libにあるディレクトリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

ダイナミックリンカの共有ライブラリが、/lib から参照されていることを確認します。


grep found test.log

 

以下が出力されることを確認します。

found ld-linux.so.2 at /lib/ld-linux.so.2

もし、/tools/libにあるディレクトリが参照されていたなら、それは、標準Cライブラリの /lib および /usr/lib への切り替えが失敗しているということになります

  
正しい結果が得られなかった場合は、直前のバックアップから戻して作業をやり直してください。

後始末

テスト用のソースファイルおよび生成された実行ファイルとログファイルを削除します。


rm -vf test.c a.out test.log

 
  

まとめ

GCCは、GNUプロジェクトによる各種プログラミング言語用のコンパイラ群です。

メニュー