Mountain Lionユーザのためのクロスコンパイラビルド
OSを開発する上で@liva_jyくんに勧められてGCCのクロスコンパイラをMacでビルドすることにした。
クロスコンパイラを使わなくてもLinuxでOS自体はビルドできるけど、確かに面倒だし。
Macで直接ビルドして、そのままデバッグしたいのは確か。
が、前途多難でmakeが通らない。
Mountain Lionでやってるために、古い情報が追いついてない模様。
以下、悪戦苦闘の記録。
【環境】
マシン: Macbooc Pro Retina (13 inch)
OS:Mac OS X 10.8.4 (Mountain Lion)
プロセッサ: Intel Core i5 2.5 GHz
メモリ: 8GB
OSDev.orgのBuilding GCC Cross Compilerのページを見ながら進めてみる。
ビルドしなくちゃいけないもの
まずは依存関係から
これからビルドするツールのインストール先を$HOME/optということにしておきます。
export PREFIX="$HOME/opt"
GMP -> MPFR -> MPC
の順にインストールしなきゃいけなかったはず。
ダウンロードは上記のリンクから。
インストールはすべてソースコードのディレクトリで
mkdir build cd build ../configure --prefix=$PREFIX make make install
で。失敗したらbuildの中身を消して、sudoでもつけてもう一回やってみよう。
(ビルド時にbuildディレクトリを作る習慣がなかったので、今考えるといろいろとヤバかった)
binutilsのインストール
binutilsをインストールします。
(binutilsって確かバイナリ系のツールセットだったっけかな…)
これもダウンロードして
./configure --prefix=$PREFIX --disable-nls make make install
でインストール。(以下buildディレクトリを作るコマンドは省略するが、作った方が安心)
特に難しいことはない。
ちなみに、--disable-nlsオプションはNative Language Supportを切るためのオプションらしく、今回はいらないからこれを切ればビルドが速くなる程度のことらしい。
確かbinutilsと次のlibiconv辺りはmake時にエラーっぽいのが出てもインストールはできてしまったはず。
最新版libiconvのインストール
Preparing for the build:For Mac OS X Usersの項を見てみると、OS Xではlibiconvというライブラリがめっちゃ古いらしい。
てなわけでlibiconvをインストールしよう。
ダウンロードしたら
./configure -prefix=/usr/local make make install
でインストール。
最新版のlibiconvはGCCのビルドで必要になるらしいので、GCCのビルド時(configure時)には忘れずに--with-libiconv-prefix=/usr/localオプションをつけておくこと。
非llvm版のgccのインストール
さらにPreparing for the build:For Mac OS X Usersの項をよーく見てみると、脚注に「Lionよりも新しいバージョンのOSを使ってる人はllvmを使わないgccが入ってないから、非llvmのgccを頑張ってビルドしてね☆」と書いてある(意訳)。
LLVMは本筋ではないので知らなかったらググってもらうことにする。
これからどうするかというと、
非llvmのgccをビルド->非llvm-gccでクロスコンパイラをビルド
という二段構えのビルドを行うことになる。
今、どっちのgccをビルドしているかを混乱しないように、明確に区別しよう。
んで、こちらのサイトを参照せよとのこと。
しかーし!親切にスクリプトを置いてくれているが、僕はMacPortsを入れてるのでHomebrewを入れ直すのが面倒くさい!
ので、まあ一からコマンドを手打ちする。
最新版のGCCはとりあえずダウンロードしておく。
注意するのは以下の通り。
ややこしいので、クロスコンパイラをビルドするコンパイラ(今からビルドするやつ)をformer-gcc、クロスコンパイラをlater-gccとする。
基本的に(former-gccのバージョン)>=(later-gccのバージョン)じゃないと安定しにくいらしいとのことなので、それに注意しつつできるだけ新しいバージョンをビルドしよう。
ちなみに、Lion以上ではOSDev.orgのリンク先にある以下のようなオプションをconfigureでつけてやる必要がある模様。
【参考】http://apple.stackexchange.com/questions/38222/how-do-i-install-gcc-via-homebrew/38247#38247
ちなみに、ビルド前にgmp,mpfr,mpc,libiconvのソースをgccのソースディレクトリに入れておかないといけないとか。
mv gmp-x.y.z gcc-x.y.z/gmp mv mpfr-x.y.z gcc-x.y.z/mpfr mv mpc-x.y.z gcc-x.y.z/mpc mv libiconv-x.y.z gcc-x.y.z/libiconv ./configure \ --prefix=$HOME/opt/gcc-x.y.z \ --with-gmp=$TOOL_DIR \ --with-mpfr=$TOOL_DIR \ --with-mpc=$TOOL_DIR \ --program-suffix=x.y.z \ --enable-languages=c,c++ \ --with-system-zlib \ --enable-stage1-checking \ --enable-plugin \ --enable-lto \ --disable-multilib \ --with-libiconv-prefix=/usr/local sudo make bootstrap sudo make install
$TOOL_DIRは、さっきGMP、MPFR、MPCをインストールしたディレクトリ。x.y.zはビルドするgccのバージョン。
ちなみに、このビルドにはむっさ時間がかかるので、4コア使える場合はmake -j4しよう。というかそれでも時間がかかるので、時間に余裕を持ってビルドしよう。(1時間くらいは覚悟すること)
それと、こんなビルド時にこんなエラーが出るかもしれない。僕は出た。
checking LIBRARY_PATH variable... contains current directory
configure: error:
*** LIBRARY_PATH shouldn't contain the current directory when
*** building gcc. Please change the environment variable
*** and run configure again.
これは$LIBRARY_PATHにセットされている値を変えればいいらしい。
たぶんLIBRARY_PATH=/opt/local/lib:となってるだろうから、
export $LIBRARY_PATH=/opt/local/lib
とする(コロンをとってやる)。
それでもgccに怒られてビルドが通らないときは、sudoとかつけてみるとうまくいったりする。
buildディレクトリを作ってるから、失敗しても消せる。
クロスコンパイラのビルド
さあ、いよいよお待ちかねのクロスコンパイラのビルド。
さっきビルドしたGCCをこれから使って、クロスコンパイラを作ろう。
まずはそのために、環境変数にさっき作ったツールを設定しておこう。
export CC=$PREFIX/gcc-x.y.z/bin/gccx.y.z export CXX=$PREFIX/gcc-x.y.z/bin/g++x.y.z export CPP=$PREFIX/gcc-x.y.z/bin/cppx.y.z export LD=$PREFIX/gcc-x.y.z/bin/gccx.y.z
そして、クロスコンパイラのビルド先を設定しよう。
mkdir ~/opt/cross/ export PREFIX=$HOME/opt/cross/
で、クロスコンパイラのサポートアーキテクチャと、パスをちょこっと設定。
僕はi686-elf用のコンパイラを作るので以下の通り。
export TARGET=i686-elf export PATH="$PREFIX/bin/:$PATH"
環境変数関連の設定は終わり。次はbinutilsのビルド。
同様にbinutilsのソースディレクトリに入って、ビルドしよう。
mkdir build cd build ../configure --target=$TARGET --prefix=$PREFIX --disable-nls make make install
そして、最後にGCCをビルド。
mv gmp-x.y.z gcc-x.y.z/gmp mv mpfr-x.y.z gcc-x.y.z/mpfr mv mpc-x.y.z gcc-x.y.z/mpc mv libiconv-x.y.z gcc-x.y.z/libiconv cd gcc-x.y.z mkdir build cd build ../configure --target=$TARGET --prefix=$PREFIX --disable-nls --enable-languages=c,c++ --without-headers --with-libiconv-prefix=/usr/local make all-gcc make all-target-libgcc make install-gcc make install-target-libgcc