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
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
テストを行います。
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 を開いてください。
...(省略)... 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." となっている場合はタイムアウトしています。 開発機の処理能力が低い場合には、テストの一部がタイムアウトすることがあります。
また、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 ...(抜粋)...
インストール後の追加作業を行います。 /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のビルド・インストールが終わりました。 ここでは、それらが正常に動作することを確認します。
コンパイルおよびリンクを行います。
cc test.c -v -Wl,--verbose > test.log 2>&1
生成された実行ファイルの動作テストを行います。 共有ライブラリが、/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