uchan note

プログラミングや電子工作の話題を書きます

Newlibビルドメモ

Newlibをclangを使って自作OS向けにビルドしたメモ

Newlibはなぜか、host=targetでconfigureしてしまうと何もビルドが走らない。 たとえホスト環境と同じ環境で動く自作OSをビルドする際も、ちょっと違うtargetを指定する必要があるらしい。 target=x86_64-none-elfとすることでビルドが走るようになった。

(2017/07/26追記:newlib-cygwinのトップディレクトリではなく、newlib-cygwin/newlibを直接ビルドすることでhost=targetでもビルドできた。詳しくは後述)

さて、target=Xとすると、NewlibのビルドスクリプトX-cc というクロスコンパイラが PATH が通ったところに存在することを求めてくる。 gccを使ってビルドするときは、クロスコンパイルをする際にクロスコンパイラがあることが一般的なので、まあこれは妥当な仕様なのだろう。

ところがclangはクロス環境別のclangコマンドを用意しなくても、–targetオプションで好きなバイナリを出力できる。 X-cc という名前で、clang --target=X という内容のスクリプトを用意してNewlibビルドスクリプトをだます。

今回、自作OSのバイナリを位置独立実行ファイルとしたかったので CFLAGS=-fPIC を付けたい。 クロスコンパイルするので CFLAGS_FOR_TARGET という変数に設定することがミソ。CFLAGS だとlibc.aのビルドには影響を与えることができない。

git clone git://sourceware.org/git/newlib-cygwin.git

echo 'clang --target=x86_64-none-elf "$@"' > SOMEWHERE_IN_PATH/x86_64-none-elf-cc
chmod +x SOMEWHERE_IN_PATH/x86_64-none-elf-cc

mkdir build-newlib
cd build-newlib
CC=clang ../newlib-cygwin/configure CFLAGS_FOR_TARGET='-g -O2 -fPIC' --prefix=$HOME/x86_64-none-elf --target=x86_64-none-elf
make
make install

ネイティブビルド

Newlibをビルドしている環境と、Newlibの対象の環境が等しい(host=target)の場合のビルド方法。

Newlibはx86Linux環境でネイティブビルドを行うとlibtoolを用いたビルドになる。 で、おそらくその場合に --enable-multilib オプションがデフォルトで有効になっていて、 手元の実験だと -m32 付きで64ビット向けソースコードをビルドしようとしてエラーになるという間抜けなことになった。

そこで --disable-multilib でエラーを回避した。multilibは32ビット版と64ビット版を同時に生成するような機能らしいが、どうせ64ビット版ライブラリしか使わないので。

git clone git://sourceware.org/git/newlib-cygwin.git

mkdir build-newlib
cd build-newlib
CC=clang ../newlib-cygwin/newlib/configure CFLAGS='-g -O2 -fPIC' --prefix=$HOME/x86_64-pc-linux-gnu --disable-multilib
make
make install