GNU Toolchain

2011-02-28
Author:g新部 裕
Date:2011-02-25

本日は、GNU Toolchain の話をします。GNU Toolchain は GNU Project において自由なコンピューティングのために作られた開発環境のことです。

1983 年にアナウンスされた GNU Project の目的は自由なコンピューティングのために自由なる OS を作ることでした。

自由なる OS とは、誰もが目的を問わず利用することができ、誰もが自由に配布でき、(すべてのソースコードが開示され)誰もが自由に研究し改変が可能で、その改変を発表できる... このような自由が担保されている OS のことです。

自由の OS のためには自由の開発環境が必要となります。GNU Project は、当初、GNU Emacs に始まり、開発環境の整備に注力することとなりました。

1990年代に入り、カーネル Linux の登場により(Linux は GNU Project の外の自由ソフトウェアです)、GNU Project の当初の目的は達成されることとなりました。自由ソフトウェア(だけ)の OS が実現したのです。

この OS を GNU/Linux と呼びます。

カーネルは一般のプログラミングには直接は影響しない(べきな)ので、アプリケーションプログラミングの観点からは GNU C library を基本とする OS のことを、GNU と呼ぶ方が技術的側面としては正しいと言えましょうか。いろいろな (かつては)UNIX があり、仕様の規格としては POSIX ができて、GNU の拡張があると整理するとわかりやすいと思います。

自由の OS のために作られた GNU Toolchain ですが、さまざまな環境に移植されました。そのため、自由の OS のため以外にも広く用いられる開発環境となっています。

GNU Toolchain は、大きく分けて二つの使われ方があります。すなわち、

  • ネイティブ開発: 対象となる環境と開発環境が同じ
  • クロス開発: 対象となる環境と開発環境が異なる(例:組み込み機器のソフトウェアの開発)

本日は、クロス開発の話題を中心としますが、比較として GNU/Linux のネイティブ開発の話もします。

GNU Toolchain (狭義)

GNU Toolchain とは狭い意味では GNU C Compiler (ここでは gcc と略します)を中心とする開発環境です。略語の GCC は以前は GNU C Compiler を指していましたが、GNU では様々な言語がサポートされて、現在は GNU Compiler Collection の略です。

GNU C Compiler を中心とする開発環境とは、GNU Binary Utilities (binutils と呼ばれます: アセンブラ, リンカ, などなど), GNU C Compiler, GNU Debugger (gdb と略されます)のことです。

Toolchain とは、「一連の道具の一揃い」という感じでしょうか。

流れを図示すると、ソースコードをコンパイラが翻訳してアセンブリ言語とし、アセンブラがオブジェクト形式にし、リンカがオブジェクト形式を結合して実行形式を得るとなります。

Source code => [Compiler] => [Assembler] => [Linker] => Executable

Executable => [Debugger] -> Target Machine

そしてデバッガで、対象の機器に送り込んで、実行/デバッグします。

この一連の道具が(狭義には) Toolchain です。

GCC について

GCC, the GNU Compiler Collection は今や、C, C++, Objective-C, Fortran, Java, Ada, および Go Programming Language をサポートします。 GCC に含まれるライブラリには libstdc++, libgcj, libffi, libgc があります。 GCC の開発の進展についてはまた詳しくのちの機会で。

GCC Getting Started, GCC Developers' Summit, International Workshop on GCC Research Opportunities などを参照してください。

GNU Toolchain (もう少し広く)

実際の開発には、binutils, gcc, gdb 以外の道具立ても必要となります。

通常の開発では、狭義の Toolchain に加えて GNU Make, GNU sed, GNU bash および GNU coreutils が使われます。場合によっては、GNU Bison, GNU M4 も使われます。

さらに、autotools とひとまとまりとして呼ばれる、GNU Build System が利用されることが多くあります。GNU Build System とは、Autoconf, Automake, Libtool のことです。場合によっては加えて AutoGen が使われることもあります。書籍の GNU Autoconf, Automake and Libtool [1] が参考となります。

[1]GNU Autoconf, Automake and Libtool, by G. V. Vaughan, B. Elliston, T. Tromey, and I. L. Taylor. SAMS (originally New Riders), 2000, ISBN 1578701902.

GNU Toolchain に加えて必要となるもの

ネイティブ開発には、GNU Toolchain に加えて、C ライブラリをはじめとするライブラリが必要になります。GNU Project では GNU C library というソフトウェアがあります。

クロス開発には、GNU Toolchain に加えて、ほとんどの場合には C ライブラリが必要です。多くの場合、newlib と言う名前の自由ソフトウェアが使われます。ChibiOS/RT などのカーネルと組み合わせて使われることもあります。

(GNU Toolchain を呼び出す)統合開発環境として GNU Emacs や Eclipse が使われることも多くあります。

Automake は Perl を利用するので、場合によっては Perl も必要となります。 GCC の test suite をはじめとして、OpenOCD のスクリプトなど、(なぜか) Tcl が使われることもままあります。

クロス開発に実機ではなく、エミュレータを使うこともままあります。qemu がよく使われるでしょうか。

また、最近の組み込み向けの CPU では、On-Chip Debugging と呼ばれる機能がサポートされているため、この機能を gdb から使うために OpenOCD (Open On-Chip Debugger)が使われることが多くなってきました。On-Chip Debugging では、JTAG という通信ポートを使うので JTAG Debugger と呼ばれることもあります。

GNU Toolchain うんちく

GNU Emacs が GNU Project で最初に作られたソフトウェアです。

GNU Project の Documentation は GNU Info を対象としています。OpenOCD なども GNU Info で書かれています。

UNIX では man 形式での documentation が標準です。GNU Project のソフトウェアの場合、man 形式の documentation は自動生成されたものであったり、「詳しくはinfo を見てね」というものだったりします。一次情報がどこかを知っておくと良いと思います。

GNU Triplet

  • arch-vendor-os という形式
  • arch-vendor-kernel-os という形式
例:
  • i686-none-linux-gnu
  • arm-none-linux-gnueabi
  • arm-none-elf
  • arm-none-eabi

Build, Host, Target

構築する環境(Build)と、出来上がったバイナリの稼働するホスト(Host)が異なる場合、クロス開発と言います。

一番複雑となるのが、稼働するホストが異なるクロスコンパイラを構築する場合。

例:

GNU/Linux 上で Mac OS X で稼働する、ARM 向けのクロスコンパイラを構築する。

GNU Toolchain のインストール

GNU Toolchain の構築は一筋縄ではいかないので、一般にはバイナリパッケージをインストールすることが多いでしょう。

ホスト OS が GNU/Linux でターゲットが ARM で OS が GNU/Linux のクロス開発をする場合、最近は Linaro でしょうか。こちら: Linaro Download

ホスト OS が Windows でターゲットが ARM で組み込み向けのクロス開発をする場合は、最近は YAGARTOでしょうか。こちら: Yet Another GNU ARM Toolchain

ちゃんとサポートしてもらいたい向きには、CodeSourcery 社の Sourcery G++ が良いかもしれません。

GNU Toolchain の移植

GNU の OS の移植を考える際には、config.guess/config.sub (Debian だと autotools-dev パッケージ)も重要なスクリプトです。

binutils の一部の port では、CGEN という生成の仕組みが使われます。CGEN は GNU Guile で動くソフトウェアです。

gcc をサポートするには、gcc の backend を移植する必要があります。機種に合わせて libgcc を設計します。

C 以外にもサポートを広げる場合、libffi や libgc も機種依存なので移植する必要があります。

gdb の移植では、ホスト側、ターゲット側両方のサポートが必要です。

いろいろな情報は Sourceware のサイトが参考となります。

C library

GNU C library は ISO C99 の機能に加えて、POSIX の機能、pthread の実装、ld.so や nsswitch などなどたくさん含んでいます。

newlib は ISO C99 を中心としたところだけです。

組込み開発では必ずしも C library を必要としませんが、

  • stdio で printf をしたい
  • malloc を使いたい
  • setjmp/longjmp を使いたい

という場合にはお手軽でしょう。自分で書いてもいいですけれども。

リンカについて

Linker script は読み書きできると良いでしょう。

また、リンカまわりの技術については、やはり 1999 年ころの書籍ですが、 Linkers and Loaders [2] が参考になります。

[2]Linkers and Loaders, by John R. Levine, Morgan Kaufmann, 1999, ISBN13 9781558604964

GNU Toolchain の構築

GNU Toolchain の構築が一筋縄でいかないのは、別々のプロジェクトのソフトウェアに複雑な依存関係があるからです。

C コンパイラの gcc は C ライブラリに依存します。しかし、C ライブラリを構築するためには C コンパイラが必要です。このため、構築は少なくとも二段階となり、最初は C ライブラリ抜きでできるとこまでの C コンパイラを作り、このコンパイラで C ライブラリを作ってから再度 gcc を構築するという手順となります。

C コンパイラの gcc がどのように C ライブラリに依存するかですが、gcc のソースコードで inhibit_libc で検索してみてください。例えば、プロファイルを取るときにはファイルに出力する必要があるので gcc のランタイムライブラリは C ライブラリを使います。

具体的な構築手順ですが、GNU/Linux の場合、Linux From Scratch が参考となるでしょう。ここで C ライブラリの構築にはカーネルのヘッダファイル(Debian だと linux-headers-2.X.X...)が必要であることに注意してください。

ARM の場合、Summon Arm Toolchain が参考となるでしょう。g新部は、Uwe's SAR を利用しています。これは当初は GNU Toolchain だけを対象としていましたが、今では OpenOCD などなどを含むようになってきました。

歴史的には、1999 年ころの CrossGCC Frequently Asked Questions が参考になります。

2005 年ころの Building and Testing gcc/glibc cross toolchains も参考となります。

Summon Arm Toolchain (SAR)

後の時間は Summon Arm Toolchain で何をやっているか、どうやって Toolchain を構築するか勉強しましょう。

対象は binutils-2.21, newlib-1.19.0, gcc 4.5.2, gdb-7.2 です。