こ のページでは、Windows 上で動作する unix (Linux? posix?) 環境エミュレータである cygwin を利用したソフトウェアのクロス開発環境(主に C コンパイラ)について説明しています。
ハー ドウェアが主体のサイトですので、ソフトウェアアーキテクチャ的な正確さよりもハードウェアを扱う人がわかりやすい表現を心がけています。用語や説明に は、一部あえて厳密な正確さよりもわかりやすさを優先している部分があります。学術的な内容を学びたい方にはお勧めしません (^_^; ので注意ください。
Cygwin (http://www.cygwin.com) とは旧 Cygnus 現 Red Hat が開発しているフリーのエミュレータです。
エミュレータなので、実行 する環境とエミュレートする環境は異なります。Cygwin の場合は、Microsoft Windows(x86) 上で動作し Linux(x86) の環境(具体的には API と標準コマンド)をエミュレートしています。
当 初は特定のプラットフォームではなく所謂 unix系 (or posix) の API をエミュレートするという位置づけでしたが、現在では Linux をターゲットとしており、Web Site にも明示的に Linuix API emulator と書かれています。
Cygwin の機能は主に cygwin1.dll という Windows の DLL で実現されており、この DLL 内で Linux API を Windows API に翻訳することで Linux API を使用したプログラムを Windows 上で動作可能にしています。API でのエミュレーションで Linux の ABI の互換性はありませんので、Linux のバイナリが動作するわけではありません。
前述のように cygwin1.dll による API の翻訳が主な機能となりますので、異なる CPU アーキテクチャをエミュレートすることはできず、現状では x86 32bit 環境でのみ使用できます。また、cygwin1.dll 自体のバージョンが変わるとアプリケーションはそのままでも動作が変わる場合がまれにありますので注意が必要です。
エ ミュレータの常として、複雑な API や、エミュレート元と先の API 仕様が大きく異なるものの動作はネイティブの場合に比べ遅くなります。Cygwin の場合には、ファイルシステムに関する操作がこれにあたり、演算のみの処理がネイティブとほとんど変わらない速度で実行できるのと対照的です。
ソ フトウェア開発環境の場合ファイルアクセスはそれなりに発生しますが、細かなファイルを多数生成したりアクセス権の変更をまとめて行ったりはしないので、 Cygwin 上でもそれほど遅いという感覚はないと思います。体感したい奇特な方は find 等を使用すると遅さを実感できると思います。
Cygwin のパッケージには inetd などのデーモン系のバイナリも含まれていますが、cygwin1.dll を使用するというアーキテクチャ上、プロセス間の情報のやり取りは比較的アクロバティックな実装を使用しています。このため、これらの機能を使用する際に はセキュリティ的なリスクについてよく理解して使用する必要があります。最近ではこのような問題を解決し、Cygwin 内でグローバルな情報を保持するための cygserver という Windows のサービスを使用する方法も安定して使用できるようになっていますので、これを使用することでより安全に動作させることができる部分もあります。
Cygwin の情報は多くの Web Site に掲載されており日本語のサイトも多く存在しますので、より詳細に知りたい方は Web 検索してみてください。古い情報がそのままのサイトもありますので、複数のサイトで確認することをお勧めします。
Cygwin のインストールは以下の手順で行います。(画面イメージ付は こちら;
別 Window で開きます)
sohda さんの "Using Cygwin"
のサイトの方が親切です (^_^;
難し いところはありませんが、開発環境として使用する際には以下の点を注意してください。このサイトのバイナリを使用する際にはこの設定以外では動作しない可 能性があります。
gcc は GNU Project (http://www.gnu.org/index.ja.html) が開発しているコンパイラで "GNU Compiler Collection" の略です。当初は C Compiler のみで、"GNU C Compiler" でしたが、FORTRAN や Ada および Java などをサポートするようになり現在の名称になりました。
一 般的に gcc 環境と呼ぶ場合には、gcc (Compiler 本体)の他に、Assembler や Linker さらに標準ライブラリをも含む場合が多いようです。以下に、C Compiler を使用する際に関連する必須となるパッケージの一覧を挙げておきます。
実際の開発では、Makefile によるコンパイルの手順化や、作成したバイナリのインストールなども行いますので、これらを含めると非常に多くのパッケージが必要になります。但し、クロ ス開発環境(実行する環境と、ターゲットの環境が異なる開発環境)でター ゲットに依存するのは上記の3つで、その他は実行環境のものがそのまま使用されます。
な お、GNU の標準 C library は glibc ですが、組み込み向けの小規模なシステムや、OS を使用しないシステムでは、最小限の機能を組み込み向けにそろえた RedHat の newlib を使用する方が環境の構築が容易です。但し、使用できる関数には制限があります。
Cygwin を使用する場合も同じで、上記3つのパッケージはターゲットごとに作成・インストールする必要がありますが、make や install などその他のコマンドは Cygwin のパッケージのものを使用します。
開発環境を作成する際には、ターゲットとなる環境を理解することが必要になります。なぜ ならば、同じ gcc および関連パッケージを使用しても、ターゲット環境によって異なる configuration が必要になるためです。
開 発環境にとって、一つの重要な差異は OS 環境の差異です。同じプロセッサを使用していても OS が異なればサポートする API / ABI が異なり、必然的に開発環境が出力するものも異なってきます。最も極端な場合は OS が存在しない場合で、開発環境が出力するバイナリは単独で動作可能なものとならなければなりません。
OS 上で動作するアプリケーションの開発の場合、例えば標準入出力やファイルシステムなどの I/O 操作、メモリ管理、割込み (signal) 処理、さらにはプログラムのロードと初期化の一部は OS が面倒を見てくれます。したがって、開発環境が生成するオブジェクトは、これらの処理を内包せずに OS に任せることが可能です。
一 方、OS が存在しないターゲットの場合には、これらの処理をす べて開発環境が生成するオブジェクト内で実現する必要があります。多くの場合、これらの処理を実現する責任はプログラム作成者にあり(=OS がなくても動作する機能のみを使用するかプログラム内に代替処理を用意する)、開発環境自体でできることは少ないのですが、一部の I/O やメモリの操作は C の標準関数や、Compiler の builtin 関数で使用するので、この部分を何らかの形で処理する必要があります。
gcc を使用した開発環境の場合、これは newlib 内の nullmon と呼ばれるライブラリでこれを処理する方法があります。(基本的に何もしないまたは決まった値を返すのみですが)
gcc + binutils + newlib を使用したクロス開発環境の make は以下の手順で行います。手順自体はセルフ環境の場合と同じですので、それぞれの処理の意味などは沢山ある gcc などの解説ページを検索してください。
4. の作業は、OS を搭載するターゲットの場合は必要ありませんが、OSを搭載しないターゲットの場合は環境に合わせた設定をしたほうが使いやすくなります。
実 際に投入するコマンドまたは操作は、例えば Compact Board Computers のページで紹介している SEMB1200A 向けの場合には以下のようになります。 (MAKE_DIR で make し、/usr/local にインストールする場合; [...] 部分はファイルのパス名を [ ] なしで入力)
GNU の開発ツール系の configure で指定するターゲット名は [プロセッサモデル]-[ベンダ名など]-[OS環境] という構成になっています。
上 記の場合 [OS 環境] は "elf" で、これは OS に依存しない汎用的な elf 形式を出力することを意味しています。汎用的というと語感は良いですが、要は OS 依存の便利な機能は使用しない/できないことを意味しています。
[ベ ンダ名など] の部分は歴史的な経緯もありあまり統一された使われ方をしていません。OS が搭載されていればベンダ依存は無いのが理想ですので、その意味ではこの部分は使われないのが本来の姿ともいえます。実際ほとんどのシステムではこの部分 は使用せず、"mipsel-linux" のように省略されていますが、ここでは OS が存在せずボードごとに異なった configuration とする可能性がありますので、勝手にボード名から "semb" の部分を使用しています。
な お、[プロセッサモデル] の部分は、SEMB1200A 搭載の UX1200E がサポートする MIPS の Little Endian を示す "mipsel" にします。
ところで、libc (ここでは newlib) には例えば I/O 関連など OS 依存の関数があります。本来はこの部分を作成しなければならないのですが、今回は I/O は直接操作することとし、リンクでエラーにならないように stub 関数のみ用意します。この用途には newlib に含まれる nullmon がそのまま使用できます。
Cygwin の環境では (Cygwin の) gcc で生成される実行可能バイナリは Windows の流儀に従って ".exe" という拡張子が付与されます。しかし、unix系 の多くのソフトウェア(の Makefile 等)は拡張子をケアしていません(unix系では拡張子はあくまで単なるファイル名の一部なので当然ですが)。コンパイル時に実行可能バイナリを扱う部分 があるとそのままではエラーになる場合があります。
これを回避するためには、コンパイル時に使用しそうなコマンド が ".exe" をケアすれば良いわけで、私は以下のコマンドでは ".exe" の有無をケアするようにスクリプトを作成しています。
このスクリプトもバイナリと一緒において置きます。
クロスコンパイルの場合でも、コンパイルの方法はセルフの場合とほぼ同じです。
注 意すべき点は、下記の3点でしょう。
SEMB1200A を例に構築した開発環境の使い方の例は こ ちら (別 Window で開きます) を見てください。
なお、MIPS のアドレス空間に知識が必要になりますので、MIPS のアドレス空間の説明 (別 Window で開きます) もあわせて読んでください。
ここには、Compact Board Computers のページで紹介しているボードに対応したクロス開発環境を作成するのに必要なソースまたはソースの情報と、私がコンパイルしたバイナリをおいて置きます。
GPL のソフトウェアですので、扱いは GPL に従って下さい。
なお、Cygwin 上で動作するバイナリはコンパイル時の cygwin の version が実行環境の cygwin の version より新しいと、ABI の互換性の問題が発生する可能性があります。最近は最新版の cygwin を使用していればあまり問題にはなりませんが、雑誌などから古い cygwin をインストールして使用している場合には注意が必要です。雑誌付録の cygwin は 1.3 ベースがまだ多いので、1.3 ベースでコンパイルしたものも置くようにします。また、雑誌付録の場合はあまり問題ありませんが、1.3 系の cygwin はまれに不安定な version がありましたので、特に理由がなければ 1.5 系に update することをお勧めします。
無
保証・無サポートですが、フィードバックは歓迎しま
す。私の itscom のアドレスへメールください。
(ユーザ名: robin3, サブドメイン: m05, ドメイン: itscom.net です)