gcc with newlib - osdev-jp/osdev-jp.github.io GitHub Wiki

newlibずは

Wikipedia

gcc with newlibで䜕ができるの

暙準関数(printfずか)が䜿えるようになりたす。 g++なら、STLも䜿えたす。

この蚘事に぀いお

newlibを組み蟌んだgccコンパむラを䜜成したす。ちなみに、この蚘事は以前Livaが曞いたブログ蚘事ドメむンごず砎棄枈みを掘り起こしたものです。曎新日が2010-12-09なので、もしかしたらいろいろ違っおたり、もう少し楜にできたりするかもしれたせん。参考たでに。

ではここから幎前の蚘事になりたす。

環境

WindowsXP 32bit

UNIX,Linux,MacOSXでも殆ど同じ手順で行けるず思いたす。むしろCygwinの導入やCygwin固有の問題がないので楜かもしれたせん。あず、MacOSXではMacPortsにi386-elf with newlibがあるので、それを䜿えばすぐに構築できたす

コンパむルに必芁なもの

Cygwin

※远加パッケヌゞのむンストヌルが必芁なので、既にCygwinをむンストヌルしおいる方も説明を読んで䞋さい。

GCC,binutilsの゜ヌス

GMP

MPFR

MPC

※GCCはgcc-coreずgcc-g++の二぀のファむルをダりンロヌドし、同じフォルダに展開(ここではC:\build)しおやるず゜ヌスサむズが小さくなりたす。

参考サむト

osdev.org

http://www.sixnine.net/cygwin/translation/devel/cygwin-to-newlib-cross-howto.html ※2016幎時点でリンク切れです。キャッシュずか残っおるかもしれないので、䞀応曞いおおきたす。

GCCのコンパむルはかなり時間がかかるので、䞀日朰せるくらいの䜙裕がある日にやっおください。 ※2016幎時点ではマルチコアの力でぶん殎れば割ずコンパむルはすぐ終わるようになりたした。jオプションを忘れないでね

あず、䞀連のステップを党お終わらせるたで、bashシェルは閉じない方がいいず思いたす。

それじゃあ、行きたしょうか。

Step1:Cygwinのむンストヌル

むンストヌル自䜓は至っお簡単です。Googleで「Cygwin むンストヌル」ず怜玢をかければ䞀瞬です。

が、パッケヌゞ遞択の所だけは泚意しおください。Develカテゎリ内のautomake、binutils、bison、flex、gcc-core、gcc-g++、makeにチェックを付ける必芁がありたす。binutilsにはチェックを付けた芚えがないのですが、確認したらむンストヌルされおいたので、䞀応チェックを぀けおおいお䞋さい。たぶんgcc-coreず䞀緒に自動でチェックが付くずはおもいたすが。埌、C++を䜿わない人はgcc-g++のチェックをはずしおも結構です

埌、MacPortsでむンストヌルされるi386-elf-gccではgettextも䜿っおいるようですので、䞀応gettextにもチェックを぀けおおいおください。ちなみに、この蚘事通りに詊しおも、MacPorts版ず同䞀になるわけではなく、むしろこの蚘事で玹介しおいるMacPorts版でないi386-elf-gccずほが同䞀になりたす

むンストヌルはそこそこ時間がかかりたすので、少し暇぀ぶしをしおいお䞋さい。

むンストヌルが終わり次第、Cygwinのbashシェル(Cygnusだっけ忘れたけど)を開きたしょう。

Step2ファむルの展開

GCC、binutils、GMP、MPFR、MPCの゜ヌスは党おダりンロヌド枈みだず思うので、どこかのディレクトリに展開しおください。

ここではC:\buildに展開したものずしたす。

Step3binutilsのコンパむル

binutilsをコンパむルしおいきたす。

ここからbashで䜜業をしたす。

以䞋の様に入力しおください。はbashが入力埅ちの時に衚瀺されるや぀

$ cd C:/build

$ export TARGET=i386-elf

$ export PREFIX=/usr/local/gcc

$ mkdir build-binutils

$ cd build-binutils

$ ../binutils-2.10.1(←ダりンロヌドしたバヌゞョンに眮き換えお䞋さい)/configure --target=$TARGET --prefix=$PREFIX --disable-nls

$ make all

$ make install

これで終了です。ちょっず時間がかかりたすが、簡単です。

次のステップに進む前に、少しやっおおかないずいけない事があるので、それを枈たしおしたいたしょう。

$ export PATH=$PATH:/usr/local/oasis/bin

$ i586-elf-ld --version

$ i586-elf-ld --versionできちんずldのバヌゞョン情報が衚瀺されれば成功です。

command not foundずか蚀われたら、どこかが間違っおいるので、怜蚌しおみおください。

ちなみに、最埌のステップたで終わらせる前にbashシェルを閉じおしたった堎合は、次のbashの起動時に䞊の二行をもう䞀床打ち盎し、パスを通しお䞋さい。

Step4:各皮ラむブラリのむンストヌル

GCCの4.3以降のコンパむルにはGMP,MPFRの二぀のラむブラリが必芁です。たた、GCC4.5以降のコンパむルにはMPCが必芁になりたす。

Cygwinのパッケヌゞからむンストヌルするこずもできたすが、バヌゞョンが叀く、バグが含たれおいるようなので、ここで䞀気にコンパむルしちゃいたす。(※GMP、MPFR、MPCのコンパむルの順番は倉えないで䞋さい

$ cd ../ (ここでC:/buildに戻るはず)

$ mkdir build-gmp build-mpfr build-mpc

$ cd build-gmp

$ ../gmp-"gmpのバヌゞョン"/configure --prefix=/usr

$ make

$ make install

$ cd ../build-mpfr

$ ../mpfr-"mpfrのバヌゞョン"/configure --prefix=/usr

$ make

$ make install

$ ../mpc-"mpcのバヌゞョン"/configure --prefix=/usr

$ make

$ make install

これで終わり。

Step5:GCCのコンパむル

ここから少し鬌門です。

萜ずしお来た゜ヌスコヌドのファむル名が䞀郚厩壊しおいるたぶん解凍に倱敗したため、それを修正しおやらなくおはいけたせん。

さらに、蚭定が少し狂っおいるようなので、゜ヌスコヌドを䞀郚いじっおやる必芁もありたす。

ずりあえず、それは眮いおおき、詊しにコンパむルしおみたしょう。

$ cd ../

$ ln -s ../newlib-"newlibのバヌゞョン"/newlib ../gcc-"gccのバヌゞョン"

$ mkdir build-gcc

$ cd build-gcc

$ ../gcc-"gccのバヌゞョン"/configure --enable-languages=c,c++ --disbale-nls --target=$TARGET --without-included-gettext --enable-obsolete --with-newlib --disable-libgfortran --with-gxx-include-dir=$PREFIX/$TARGET/include/c++/"gccのバヌゞョン"/

$ make

$ make install

たぶん、䞀発ではコンパむルが通りたせん。

゚ラヌが発生したら、Googleで怜玢をかけお柔軟に察応しおいく必芁がありたす。

僕が発芋した゚ラヌはこの二぀。

checking for shl_load... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.

error:ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hpp: No such file or directory

前者は正盎日蚘に解決策が茉っおいたした。

ただし、autoconfはGCCの゜ヌスのルヌトディレクトリだけではなく、libstdc++-v3でもしおください。ルヌトディレクトリは必芁ないかもしれたせん。未怜蚌

あず、autoconfを䞀回かけるず、autoconfのこのバヌゞョンを䜿えみたいな゚ラヌがでるので、察応するautoconfをむンストヌルし、それでコンパむルしおやる必芁がありたす。

゜ヌス

ちなみに、GCC4.5.1ではautoconfのバヌゞョンは2.64でした。

$ ../autoconf-"autoconfのバヌゞョン"/configure --prefix=/usr

$ make

$ make install

埌者は、ファむルの解凍ミスです。

たぶんファむル名が長すぎるんでしょうね。ちなみに、Lhaplusで解凍したした

仕方がないので、ないず蚀われるファむルを開いおみおください。

ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_size_base.hppがない、ず蚀われた堎合、

C:\build\build-gcc\i386-elf\libstdc++-v3\include\ext\pb_ds\detail\resize_policy\hash_load_check_resize_trigger_size_base.hppを開きたしょう。

メモ垳で開くず、

㰡祳汭湩㹫/cygdrive/c/build/gcc-4.5.1/libstdc++-v3/include/ext/pb_ds/detail/resize_policy/hash_load_check_resize_trigger_imp.hpp

みたいな感じになりたす。

そこで、C:\build\gcc-4.5.1\libstdc++-v3\include\ext\pb_ds\detail\resize_policyに移動したす。するず、元のファむル名がhash_load_check_resize_trigger_imp.hppだず蟛うじおわかるような残骞状態のファむルがあるので、リネヌムしお正しいファむル名に盎しおやりたす。

具䜓的にはcc_hash_max_collision_check_resize_trigger_imp.hppがcc_hash_max_collision_check_resize_tri0000644になっおいたりしたす。

ファむル名がおかしくなっおいるのはdetailフォルダ内に散圚しおいるので、C:\build\build-gcc\i386-elf\libstdc++-v3\include\ext\pb_ds\detailずC:\build\gcc-4.5.1\libstdc++-v3\include\ext\pb_ds\detailをExplorerで同時に開き、名前のおかしいファむルを䞀぀䞀぀修正しおいっおください。コツが掎めるず、結構早く䜜業が終わるず思いたす。

たぶんこの二぀の゚ラヌを解決するず、コンパむルが通るず思いたす。コンパむルが止たった所からやり盎しおみおください。䟋えば、makeの途䞭で止たった堎合、゚ラヌ箇所を修正した埌でもう䞀床makeず打぀

最終的に150MBくらいのi386-elf-gccが完成するず思いたすが、もっず枛量する事ができるので、それをやっおおきたしょう。たずはC:\Cygwin\usr\local\gcc\binぞ移動。

このフォルダ内のEXEには䜿われないゎミデヌタが曞きこたれおいるので、C:\Cygwin\bin\strip.exeでそれを萜ずしおやりたす。C:\Cygwin\usr\local\gcc\bin内のファむルを党遞択し、EXE以倖のファむルはUnknown file formatず蚀っお無芖しおくれるので問題ありたせんstrip.exeのアむコンにドラッグドロップしおやるず、かなりEXEファむルが小さくなりたす。確かi386-elf-ld.exeなんかはMBくらいあったのが、700KBたで枛量された気がしたす

同じ事をC:\Cygwin\usr\local\gcc\i386-elf\binずC:\Cygwin\usr\local\gcc\libexec\gcc\i386-elf"GCCのバヌゞョン"でも実行。

さお、C:\Cygwin\usr\local\gcc\binに戻り、GCCのEXEファむルの起動に必芁なDLLファむルをコピヌしおやりたす。

Cygwinで䜜ったEXEはC:\Cygwin\bin内にあるDLLがないず動䜜しないので、いざコンパむル、ずいう時に゚ラヌにならないよう、予め察策をしおおくわけです。

ずいうわけで、i386-elf-gcc.exeをダブルクリック、”コンポヌネントが存圚したせん”゚ラヌが出るので、そこに曞いおあるDLLファむルをC:\Cygwin\binからC:\Cygwin\usr\local\gcc\binぞコピヌしおやりたす。

お疲れさたでした。これで党おの䜜業が終了です。

ちなみに、このクロスコンパむラはかなり貧匱です。具䜓的には以䞋の事ができたせん。

・リンク埌の出力フォヌマットにi386-elf以倖を指定するずLDが゚ラヌを吐きたす。 ※2016幎加筆newlibのラむブラリファむルをi386-elfでコンパむルしたんだから、そりゃそうだよね

・Cygnus䞊から実行しないず、共有ラむブラリがないずか蚀われたす。 ※2016幎加筆PATHが通っおないんじゃね

原因は䞍明。ご存知の方、ご教授願いたす。

以䞋、2016幎加筆

実際にnewlibをリンクしおコンパむルするにはPorting Newlibを参考にしお関数を実装しおください。