UNIX 上でのクロス gcc のビルド with newlib

gcc + newlib 環境

今の gcc だとすごく簡単にクロス環境を作ることができます。 特に、ライブラリなしの C 言語コンパイラなら何も考えずに configure + make で 作ることができます。

しかしながら、ライブラリがないのはさみしいので、 ここでは Cygnus の newlib による標準 C ライブラリ実装を 使えるようにする方法を説明します。 これと同じことを実現しているものに、DevKitAdvance という 定番環境がありますが、

という事情があるので、ここでは

という(この文書執筆時点での)最新環境に、 Windows 版 DevKitAdvance の最新のランタイムライブラリ環境を 組み合わせた環境を UNIX で構築します。

ソースの取得

binutils と gcc は、GNU のミラーから適当に持ってきてください。 newlib は RedHat から落とせます。

これらに加えて、私の作ったパッチが ここ にあるので、適当に一番新しそうな奴を持ってきておいてください。

(2003-12-10 以前のパッチを使う場合には、cube さんによる このような修正 もしておいたほうが良いかもしれません。 2004-07-15 以降のパッチには含まれていますし、 2003-12-10 以前のパッチを使う必要はほとんどないと思いますが。 あえて旧バージョンのツールを使いたい場合でも、 binutils 以外はオフセットが出るだけでそのままパッチが当たるような気もします)

ビルドとインストール

物がそろったら、以下のような作業を行います。 パスは適宜読み替えてください。

展開とパッチ当て:

% tar zxf binutils-2.15.tar.bz2
% tar zxf gcc-3.4.1.tar.bz2
% tar zxf newlib-1.12.0.tar.gz
% patch -p0 < patches-devgba-2004-07-15/binutils-2.15.patch
% patch -p0 < patches-devgba-2004-07-15/gcc-3.4.1.patch
% patch -p0 < patches-devgba-2004-07-15/newlib-1.12.0.patch

gcc と一緒に newlib をコンパイルするための symlink:

% cd gcc-3.4.1
% ln -s ../newlib-1.12.0/newlib ../newlib-1.12.0/libgloss \
        ../newlib-1.12.0/COPYING.NEWLIB .

binutils のビルドとインストール:

% cd ../binutils-2.15
% mkdir _build_
% cd _build_
% ../configure  --prefix=/usr/local/apps/cross-arm-agb-elf \
                --target=arm-agb-elf --disable-nls --with-cpu=arm7tdmi \
                --enable-targets=arm-elf,arm-coff,arm-aout
% gmake
% sudo gmake install

gcc / newlib のビルドとインストール:

% cd ../../gcc-3.4.1
% mkdir _build_
% cd _build_
% PATH=/usr/local/apps/cross-arm-agb-elf/bin:$PATH ../configure \
      --prefix=/usr/local/apps/cross-arm-agb-elf --target=arm-agb-elf \
      --disable-nls --with-cpu=arm7tdmi \
      --enable-targets=arm-elf,arm-coff,arm-aout --with-newlib \
      --with-headers=`pwd`/../newlib/libc/include/ --with-gc=simple \
      --enable-multilib --enable-interwork --enable-languages=c,c++ \
      --disable-threads --disable-shared
% PATH=/usr/local/apps/cross-arm-agb-elf/bin:$PATH gmake
% PATH=/usr/local/apps/cross-arm-agb-elf/bin:$PATH sudo gmake install

C++ について

C++ の利用もできます。 しかしながら、libstdc++ のコンパイルにすごく時間がかかります。 コンパイルに時間がかかっているのは主に locale や iostream 系といった 組み込みプログラムではまず使われない部分なので、多少馬鹿馬鹿しいですね。

C++ が必要なければ gcc の configure における引数 --enable-languages から c++ を外してください。

crt0 について

私のパッチに含まれている crt0 および ldscript は、 Windows 版の DevKitAdvance の R5beta3 から持ってきたものです。 デフォルトで使われる crt0.o は、

という設定になっていますので、 これ以外の場合には自前で crt0.o を用意してやる必要があります。

(*) 「これがないと割り込みが使えない」というわけではなくて、 単に isr.S を入れてないだけです。自前で ISR を用意すれば使えます。 たとえば、 GBAプログラミング研究所 さんのサンプル(後述「テスト」を参照)に IRQ_devkit というのがありますが、 これは自前でハンドラを用意しているので isr.S を組み込んだ crt0.o を 別途用意する必要はありません。

イメージの作り方

上のような設定で build された gcc は ELF イメージを吐くので、 実際に GBA で使えるようにするには objcopy で raw image を吐かせます:

% arm-agb-elf-gcc -o hoge.elf hoge.c
% arm-agb-elf-objcopy -O binary hoge.elf hoge.bin

テスト

GBAプログラミング研究所 さんの GCCコンパイラ利用法 DevKitAdvance編 というページから適当なサンプルを拾ってきて、

とした上で、適当に PATH を設定して make を走らせるとコンパイルできるはずです。

IRQ_devkit だけは Makefile がないので、

% arm-agb-elf-gcc -o test.elf main.c spprint/nums.c
% arm-agb-elf-objcopy -O binary test.elf test.gba

とすると良いでしょう。

出来上がったバイナリは、シグネチャがないので実機では動きませんが、 VisualBoyAdvance ならば元気に動きます:


塩崎 拓也 <tshiozak@bsdclub.org>