2015年02月24日
Linux上でビルドしたGCCクロスコンパイラを(簡易)テストする方法
PC Linux ホスト上で、sh の評価ボードなどホストと異なる環境をターゲットにした、GCC のクロスコンパイラ ※ をビルドするのは比較的簡単で、ウェブ上にも情報はたくさんあるのですが、それをテストする方法がなかなかわからず苦労しました。その時のメモです。
※ この記事では newlib を使用した bare-metal target、いわゆる OS レスの環境をターゲットにしたクロスコンパイラの、ソフトウェア CPU シミュレータを使用した簡易テスト方法を扱います。GCC のビルド環境や、dejagnu などの(通常のネイティブ GCC の)テスト環境は、既に整っているものとします。
※ この記事では newlib を使用した bare-metal target、いわゆる OS レスの環境をターゲットにしたクロスコンパイラの、ソフトウェア CPU シミュレータを使用した簡易テスト方法を扱います。GCC のビルド環境や、dejagnu などの(通常のネイティブ GCC の)テスト環境は、既に整っているものとします。
このサイトが非常に参考になりました。
参考サイト: MIPS Cross Compiler build
要点は
難点は、GDB のバージョンによってテスト結果が変わってしまうので、バージョンを固定する必要がありますし、あくまでも参考にしかならないということですね。それでも全くテストしないよりは安心感が違います。※4
続き: Linux上でビルドしたGCCクロスコンパイラをQEMUユーザーモードでテストする方法
※1 たいてい、自前でクロスコンパイラを用意する必要がある場合は、比較的マイナーな環境であることが多いので、Linux ディストリビューションのパッケージが存在することは期待できません。(そもそも GDB のパッケージがあるような環境ならば、たいていクロスコンパイラも用意されているはず…。)
※2 参考 : GNU による AKI-H8 のプログラム開発 / 文字列出力(printf)をシミュレータと実機両方で使えるようにする
ただし、この sim-stdio 向けライブラリは、実機では邪魔になるので、その場合は
※3 正確には、GCC のビルドディレクトリで make check-gcc した場合には、ビルドディレクトリの gcc/xgcc が使用されます。インストール済みの sh-none-elf-gcc などを実際に使用したい場合は、以下のように適当に設定ファイル site.exp を用意し(make check-gcc 時に生成されるファイルが参考になります)、runtest を実行してください。--tool に gcc/g++ を指定する場合は、srcdir に GCC のソースディレクトリの gcc/testsuite ディレクトリ、libstdc++ を指定する場合は libstdc++-v3/testsuite を指定してください。
※4 GCC や newlib の ARM などのメジャーなターゲットがバグってることは、あまりありませんが、マイナーなターゲットや、まだ枯れていない最新アーキテクチャは油断できません。(そもそもビルドがまともに通らないことの方が多いぐらいです。)できる限りのテストをやっておくにこしたことはありません。
参考サイト: MIPS Cross Compiler build
要点は
- GDB の CPU シミュレータを使って、別ターゲット向けのバイナリを実行 参考サイトと同様に、クロス GCC と一緒にクロス GDB もビルドするのが確実です ※1。その時、GCC をビルドした時の configure に指定したターゲット(以後、例として --target=sh-none-elf を使用します)に合わせて、GDB の configure 時の target も指定します。(後述しますが、デフォルトの設定ファイルでは、コンパイラとシミュレータで同じ prefix が使用されるので、target を合わせておくと追加の設定が不要で楽です。ここらへんは binutils の設定と同じです。)
- newlib は GDB の sim-stdio に対する標準入出力ライブラリを持っているので、それを使用(デフォルトで有効 ※2)
- GCC の make check の時に target_board に XXX-sim を指定
参考サイトの以下の部分です。cd mips/build/gcc-stage2 make check-gcc RUNTESTFLAGS=--target_board=mips-sim
ここを使いたい CPU に合わせて sh-sim のように指定すると、クロスコンパイラ sh-none-elf-gcc ※3 でコンパイルしてできたバイナリが、クロスコンパイラと同じ prefix の sh-none-elf-run で実行されます。
また、GDB の configure 時にシミュレータの標準入出力(sim-stdio)のサポートを有効にします。
--enable-sim-stdioビルドした GDB に PATH を通しておくのも忘れないでください。
難点は、GDB のバージョンによってテスト結果が変わってしまうので、バージョンを固定する必要がありますし、あくまでも参考にしかならないということですね。それでも全くテストしないよりは安心感が違います。※4
続き: Linux上でビルドしたGCCクロスコンパイラをQEMUユーザーモードでテストする方法
※1 たいてい、自前でクロスコンパイラを用意する必要がある場合は、比較的マイナーな環境であることが多いので、Linux ディストリビューションのパッケージが存在することは期待できません。(そもそも GDB のパッケージがあるような環境ならば、たいていクロスコンパイラも用意されているはず…。)
※2 参考 : GNU による AKI-H8 のプログラム開発 / 文字列出力(printf)をシミュレータと実機両方で使えるようにする
ただし、この sim-stdio 向けライブラリは、実機では邪魔になるので、その場合は
--disable-newlib-supplied-syscallsを configure オプションに追加して newlib をビルドします。
※3 正確には、GCC のビルドディレクトリで make check-gcc した場合には、ビルドディレクトリの gcc/xgcc が使用されます。インストール済みの sh-none-elf-gcc などを実際に使用したい場合は、以下のように適当に設定ファイル site.exp を用意し(make check-gcc 時に生成されるファイルが参考になります)、runtest を実行してください。--tool に gcc/g++ を指定する場合は、srcdir に GCC のソースディレクトリの gcc/testsuite ディレクトリ、libstdc++ を指定する場合は libstdc++-v3/testsuite を指定してください。
$ cat site.exp set target_triplet sh-none-elf set target_alias sh-none-elf set CFLAGS "" set CXXFLAGS "" set HOSTCC "gcc" set HOSTCFLAGS "-g -O2" set tmpdir /path/to/temp set baseline_subdir_switch "--print-multi-directory" $ export PATH=/path/to/gcc/sysroot/bin:$PATH $ runtest --tool gcc --srcdir /path/to/gcc-XXX/gcc/testsuite --target_board=sh-sim --ignore pch.exp以下も、必要ならば試してみると良いかもしれません。
set HAVE_LIBSTDCXX_V3 1 set ENABLE_PLUGIN 1 set PLUGINCC "g++" set PLUGINCFLAGS "-g " set ENABLE_LTO 1また、PATH を通さなくても、set rootme でインストールした GCC のルートディレクトリ(sysroot)を指定すれば良いのかもしれません。(未検証)
※4 GCC や newlib の ARM などのメジャーなターゲットがバグってることは、あまりありませんが、マイナーなターゲットや、まだ枯れていない最新アーキテクチャは油断できません。(そもそもビルドがまともに通らないことの方が多いぐらいです。)できる限りのテストをやっておくにこしたことはありません。