クロスコンパイラとは、コンパイラが動作しているプラットフォームとは異なるプラットフォーム向けの実行可能コードを生成できるコンパイラのことです。例えば、PC上で動作し、 Androidデバイスで動作するコードを生成するコンパイラは、クロスコンパイラです。
クロスコンパイラは、1つの開発ホストから複数のプラットフォーム向けのコードをコンパイルするのに役立ちます。例えば、計算リソースが限られている組み込みシステムなどでは、ターゲットプラットフォーム上で直接コンパイルすることは現実的ではない場合があります。
クロスコンパイラは、ソースコードコンパイラとは異なります。クロスコンパイラは、クロスプラットフォームのソフトウェアからマシンコードを生成するためのものであり、ソースコードコンパイラは、あるプログラミング言語から別のプログラミング言語のテキストコードへの変換を行うものです。どちらもプログラミングツールです。
クロスコンパイラの基本的な用途は、ビルド環境とターゲット環境を分離することです。これは、次のような状況で役立ちます。
仮想マシン(JavaのJVMなど)を使用することで、クロスコンパイラが開発された理由の一部が解決されます。仮想マシンのパラダイムにより、同じコンパイラ出力を複数のターゲットシステムで使用できますが、仮想マシンは処理速度が遅い場合が多く、コンパイルされたプログラムはその仮想マシンがインストールされているコンピュータでしか実行できないため、必ずしも理想的とは言えません。
通常、ハードウェアアーキテクチャが異なる場合(例えば、 MIPSアーキテクチャ向けのプログラムをx86コンピュータでコーディングする場合)がありますが、クロスコンパイルは、オペレーティングシステム環境のみが異なる場合(例えば、 Linux上でFreeBSDプログラムをコンパイルする場合)や、システムライブラリのみが異なる場合(例えば、 glibcホスト上でuClibcを使用してプログラムをコンパイルする場合)にも使用できます。
カナディアンクロスは、ターゲットマシンよりも元のマシンがはるかに低速または不便な場合に、他のマシン向けにクロスコンパイラを構築するための手法です。3台のマシンA、B、Cがある場合、マシンA(例えば、IA-32プロセッサ上でWindows XPを実行)を使用してクロスコンパイラを構築し、そのコンパイラをマシンB(例えば、x86-64プロセッサ上でmacOSを実行)上で実行して、マシンC(例えば、ARMプロセッサ上でAndroidを実行)用の実行ファイルを作成します。この例における実用的な利点は、マシンAは低速だが独自のコンパイラを備えているのに対し、マシンBは高速だがコンパイラを全く備えておらず、マシンCはコンパイルに使用するには非現実的なほど低速であるという点です。
カナダ十字をGCCで使用する場合、この例のように、4つのコンパイラが関与する可能性があります。
![]()
最終結果のクロスコンパイラ(4)は、ビルドマシンAでは実行できません。代わりに、マシンBで実行され、アプリケーションを実行可能なコードにコンパイルし、それをマシンCにコピーしてマシンCで実行します。
例えば、NetBSDには という名前のPOSIX Unix シェルスクリプトがありbuild.sh、これはまずホストのコンパイラを使用して独自のツールチェーンを構築します。そして、このツールチェーンは、システム全体を構築するために使用されるクロスコンパイラを構築するために使用されます。
「カナダ十字」という名称は、これらの問題が議論されていた当時、カナダには3つの全国政党があったことに由来する。[ 1 ]
GCCは、コンパイラのフリーソフトウェアコレクションであり、クロスコンパイルを設定することができます。多くのプラットフォームと言語をサポートしています。
GCC では、対象プラットフォームごとにコンパイル済みのbinutilsが必要です。特に重要なのはGNU アセンブラです。そのため、まず binutils をconfigure スクリプト--target=some-targetに渡すスイッチを使用して正しくコンパイルする必要があります。GCC も同じオプションで設定する必要があります。binutilsが作成するツールがパスに存在すれば、 GCC は通常どおり実行できます。パスは、以下のコマンド(bash を使用する UNIX 系オペレーティングシステムの場合)で設定できます。--target
PATH=/path/to/binutils/bin:${PATH} makeGCCをクロスコンパイルするには、ターゲットプラットフォームのC標準ライブラリの一部がホストプラットフォーム上で利用可能である必要があります。プログラマはCライブラリ全体をコンパイルすることもできますが、この方法は信頼性に欠ける可能性があります。代替手段として、 Cソースコードのコンパイルに必要な最小限のコンポーネントのみを含む小さなCライブラリであるnewlibを使用する方法があります。
GNU Autotoolsパッケージ (つまりautoconf、automake、libtool ) は、ビルド プラットフォーム、ホスト プラットフォーム、ターゲット プラットフォームという概念を使用します。ビルド プラットフォームは、コンパイラが実際にコンパイルされる場所です。ほとんどの場合、build は未定義のままにしておく必要があります (デフォルトで host が使用されます)。ホスト プラットフォームは、出力が別のコンパイラであるかどうかにかかわらず、コンパイラからの出力成果物が実行される場所です。ターゲット プラットフォームは、クロス コンパイラをクロス コンパイルする場合に使用され、パッケージが生成するオブジェクト コードの種類を表します。それ以外の場合は、ターゲット プラットフォームの設定は関係ありません。[ 3 ] 例えば、Dreamcastで動作するビデオゲームをクロス コンパイルする場合を考えてみましょう。ゲームがコンパイルされるマシンがビルド プラットフォームであり、Dreamcast がホスト プラットフォームです。hostとtarget という名前は、使用されているコンパイラに対して相対的で、sonとgrandsonのようにシフトされます。[ 4 ]
組み込みLinux開発者がよく使う別の方法として、GCCコンパイラとScratchboxやScratchbox 2、PRootといった専用サンドボックスを組み合わせる方法があります。これらのツールは「 chroot」されたサンドボックスを作成し、プログラマは余分なパスを設定することなく、必要なツール、libc、ライブラリを構築できます。また、ランタイムを「だまして」、意図したターゲットCPU(ARMアーキテクチャなど)上で実際に実行されていると「思わせる」機能も提供されており、これにより設定スクリプトなどをエラーなく実行できます。Scratchboxは「chrootしない」方法に比べて動作が遅く、ホスト上のほとんどのツールは動作させるためにScratchboxに移動する必要があります。
ニュージャージー州シュルーズベリーにあるマンクス・ソフトウェア・システムズは、1980年代から、 IBM PC互換機やMacを含む様々なプラットフォーム向けのプロの開発者を対象としたCコンパイラを製造していた。
マンクスのAztec Cプログラミング言語は、 MS-DOS、Apple II、DOS 3.3およびProDOS、Commodore 64、Mac 68k [ 5 ]、Amigaなど、さまざまなプラットフォームで利用可能でした。
1980年代から1990年代にかけて、Manx Software Systemsが消滅するまで、Aztec C [ 6 ]のMS-DOS版は、ネイティブモードコンパイラとしても、Commodore 64 [ 7 ]やApple II [ 8 ]など、異なるプロセッサを搭載した他のプラットフォーム向けのクロスコンパイラとしても提供されていました。Aztec Cのインターネット上の配布版は、MS-DOSベースのクロスコンパイラを含め、現在でも存在し、今日でも使用されています。
Manx社のAztec C86は、ネイティブモードの8086 MS-DOSコンパイラであると同時に、クロスコンパイラでもありました。Commodore 64やApple II向けのクロスコンパイラであるAztec C65 6502のように、異なるプロセッサ向けのコードをコンパイルすることはできませんでしたが、当時旧式だった16ビット8086ファミリープロセッサ向けのオペレーティングシステム用のバイナリ実行ファイルを作成することができました。
IBM PCが最初に登場したとき、オペレーティングシステムはCP/M-86とPC DOSの2つから選択できました。Aztec C86には、両方のIBM PCオペレーティングシステム用のコードを生成するためのリンクライブラリが提供されました。1980年代を通じて、Aztec C86の後のバージョン(3.xx、4.xx、5.xx)では、MS-DOSの「過渡期」バージョン1と2 [ 9 ]のサポートが追加されました。これらは、Aztec C86が終焉を迎えるまでターゲットとしていた「ベースライン」MS-DOSバージョン3以降よりも堅牢性が低いものでした。
最後に、Aztec C86はC言語開発者にROM書き込み可能な「HEX」コードを作成する機能を提供し、そのコードをROMライターを使って8086ベースのプロセッサに直接転送することが可能になった。準仮想化は今日ではより一般的になっているかもしれないが、デバイスドライバ開発がアプリケーションプログラマによって個々のアプリケーション向けに行われることが多く、新しいデバイスが家内工業の様相を呈していた当時は、低レベルのROMコードを作成する手法が一人当たりでより一般的だった。アプリケーションプログラマがメーカーのサポートなしにハードウェアと直接インターフェースすることは珍しくなかった。この手法は、今日の組み込みシステム開発と似ている。
トーマス・フェンウィックとジェームズ・グッドナウ2世は、Aztec-Cの主要開発者2名でした。フェンウィックは後に、Microsoft Windows CEカーネル、または当時NK(「New Kernel」)と呼ばれていたカーネルの作者として有名になりました。[ 10 ]
Microsoft C (MSC) の歴史は他のものより短く、 1980 年代に遡ります[ 11 ]。最初の Microsoft C コンパイラはLattice Cを作成したのと同じ会社によって作成され、Microsoft によって自社ブランドとして再ブランド化されましたが、Microsoft が自社で作成した最初のバージョンである MSC 4 がリリースされました[ 12 ] 。
1987年、多くの開発者がMicrosoft Cへの移行を開始し、Microsoft Windowsが現在の形になるまでの開発過程において、さらに多くの開発者がそれに続いた。Clipperや後にClarionといった製品が登場し、クロス言語技術を用いることでデータベースアプリケーションの開発を容易にし、プログラムの一部をMicrosoft Cでコンパイルできるようにした。
ボーランドC(カリフォルニア州の企業)は、マイクロソフトが最初のC言語製品を発売する何年も前から購入可能だった。
C言語プログラムは、長らくアセンブリ言語で書かれたモジュールと連携して動作してきた。ほとんどのCコンパイラ(最新のコンパイラも含む)は、アセンブリ言語パスを提供しており(効率性を高めるために調整した後、アセンブル後にプログラムの残りの部分とリンクできる)、このパスはアセンブリ言語処理に対応している。
Aztec-Cのようなコンパイラは、すべてのコードをアセンブリ言語に個別のパスで変換し、さらに別のパスでアセンブルするという処理を行っており、非常に効率的でコードサイズも小さいことで知られていました。しかし、1987年までにMicrosoft Cに組み込まれたオプティマイザの性能が非常に向上したため、プログラムの「ミッションクリティカル」な部分のみが書き換えの対象となるのが一般的になりました。実際、C言語プログラミングは「最低レベル」言語としての地位を確立し、プログラミングは多分野にわたる成長産業となり、プロジェクト規模も拡大しました。プログラマはより高レベルの言語でユーザーインターフェースやデータベースインターフェースを作成するようになり、今日まで続くクロス言語開発の必要性が生じたのです。
1987年、MSC 5.1のリリースにより、マイクロソフトはMS-DOS用のクロス言語開発環境を提供しました。アセンブリ言語(MASM)で記述された16ビットバイナリオブジェクトコードと、QuickBASIC、Pascal、Fortranなどのマイクロソフトの他の言語を、1つのプログラムにリンクさせることができました。マイクロソフトはこのプロセスを「混合言語プログラミング」と呼び、現在は「言語間呼び出し」と呼んでいます。[ 13 ]この混合環境でBASICを使用する場合、ガベージコレクションに必要なBASICをコンパイルする内部ランタイムシステムと、MS-DOSのQBasicのようなBASICインタープリタをシミュレートするその他の管理操作をサポートするために、メインプログラムはBASICで記述する必要がありました。
特にC言語の呼び出し規約は、パラメータをスタック上で「逆順」で渡し、戻り値をプロセッサレジスタではなくスタック上に戻すというものでした。すべての言語が連携して動作するようにするための他のプログラミング規則もありましたが、この特定の規則は、Windows 16ビット版および32ビット版、そしてOS/2向けプログラムの開発を通して継続された言語間開発においても維持され、今日まで続いています。これはPascal呼び出し規約として知られています。
この時期にMicrosoft Cが使用されたもう1つのタイプのクロスコンパイルは、Symbol TechnologiesのPDT3100(在庫管理に使用)のような携帯端末を必要とする小売業向けアプリケーションでした。PDT3100は、 8088ベースのバーコードリーダーを対象としたリンクライブラリを提供していました。アプリケーションはホストコンピュータ上でビルドされ、シリアルケーブルを介して携帯端末に転送されて実行されました。これは、Symbolを買収したMotorolaなどの企業が、 Windows Mobileを使用して同じ市場向けに現在行っていることと似ています。
1990年代を通して、MSC 6(同社初のANSI C準拠コンパイラ)を皮切りに、マイクロソフトはCコンパイラを新興のWindows市場、OS/2 、そしてGUIプログラムの開発に重点を置くように再編成しました。MS-DOS側ではMSC 6まで言語の混在互換性が維持されましたが、 Microsoft Windows 3.0および3.1のAPIはMSC 6で記述されました。MSC 6は、32ビットアセンブリのサポート、そしてWindows XPの基盤となる新興のWindows for WorkgroupsおよびWindows NTのサポートを提供するように拡張されました。16ビットと32ビットのプログラム間での受け渡しを可能にするために、サンクと呼ばれるプログラミング手法が導入されました。これは、モノリシックな16ビットMS-DOSアプリケーションで好まれていた静的バインディングではなく、ランタイムバインディング(動的リンク)を利用するものでした。静的バインディングは一部のネイティブコード開発者に今でも好まれていますが、一般的には能力成熟度モデル(CMM)などの新しいベストプラクティスで求められるレベルのコード再利用は実現しません。
マイクロソフト初のC++コンパイラであるMSC 7のリリース後も、MS-DOSのサポートは継続され、C言語およびMS-DOSとの下位互換性を持ち、16ビットおよび32ビットの両方のコード生成をサポートしていた。
MSCはAztec C86の後継として事業を引き継いだ。Cコンパイラの市場シェアは、最新のWindows機能を活用し、CとC++を単一のパッケージで提供し、すでに10年以上前のMS-DOSシステムもサポートするクロスコンパイラへと移行していた。Aztec Cのようなコンパイラを製造していた小規模企業はもはや競争に勝てず、組み込みシステムのようなニッチ市場に進出するか、あるいは消滅するかのどちらかだった。
MS-DOSおよび16ビットコード生成のサポートは、Microsoft C++およびMicrosoft Application Studio 1.5(現在Microsoftが提供しているクロス開発環境であるMicrosoft Visual Studioの前身)にバンドルされたMSC 8.00cまで継続されました。
MSC 12はMicrosoft Visual Studio 6とともにリリースされ、MS-DOS 16ビットバイナリのサポートは終了し、代わりに32ビットコンソールアプリケーションのサポートを提供するようになりました。ただし、Windows 95およびWindows 98のコード生成、ならびにWindows NTのサポートは引き続き提供されました。Microsoft Windowsを実行する他のプロセッサ向けにもリンクライブラリが提供されており、これはMicrosoftが現在も継続している慣行です。
MSC 13はVisual Studio 2003とともにリリースされ、MSC 14はVisual Studio 2005とともにリリースされました。どちらもWindows 95のような古いシステム向けのコードを生成するだけでなく、モバイル市場やARMアーキテクチャを含む複数のターゲットプラットフォーム向けのコードも生成します。
2001年、マイクロソフトは共通言語ランタイム(CLR)を開発しました。これは、Visual Studio IDEにおける.NET Frameworkコンパイラの核となる部分です。オペレーティングシステム上に構築されたこのAPIレイヤーにより、Windowsオペレーティングシステム上で動作する様々なプラットフォームでコンパイルされた開発言語を混在させることが可能になりました。
.NET FrameworkランタイムとCLRは、ターゲットコンピュータ上のプロセッサとデバイスに対応するコアルーチンへのマッピングレイヤーを提供します。Visual StudioのコマンドラインCコンパイラは、さまざまなプロセッサ向けにネイティブコードをコンパイルし、コアルーチン自体を構築するために使用できます。
ARMアーキテクチャ上のWindows Mobileなどのターゲットプラットフォーム向けのMicrosoft .NETアプリケーションは、さまざまなプロセッサを搭載したWindowsマシン上でクロスコンパイルされます。また、Microsoftは、かつてのクロスコンパイラや他のプラットフォームとは異なり、ほとんど設定を必要としないエミュレータやリモート展開環境も提供しています。
Monoなどのランタイムライブラリは、クロスコンパイルされた.NETプログラムとLinuxなどの他のオペレーティングシステムとの互換性を提供します。
Qtやその前身であるXVTなどのライブラリは、ソースコードレベルで他のプラットフォームとのクロス開発機能を提供しつつ、Windows版のビルドにはMicrosoft Cを使用しています。MinGWなどのコンパイラもこの分野で人気を集めています。これらのコンパイラは、ソフトウェア開発の非Windows側を構成するUnix系システムとの互換性が高く、開発者が使い慣れたビルド環境を用いてあらゆるプラットフォームをターゲットにできるためです。
Free Pascal は、当初からクロス コンパイラとして開発されました。コンパイラ実行ファイル (ppcXXX、XXX はターゲット アーキテクチャ) は、同じアーキテクチャのすべての OS に対して実行ファイル (内部リンカが存在しない場合はオブジェクト ファイルのみ、内部アセンブラが存在しない場合はアセンブリ ファイルのみ) を生成できます。たとえば、ppc386 は、i386-linux、i386-win32、i386-go32v2 (DOS) およびその他のすべての OS に対して実行ファイルを生成できます ( [ 14 ]を参照)。ただし、別のアーキテクチャにコンパイルするには、まずクロス アーキテクチャ バージョンのコンパイラをビルドする必要があります。結果として得られるコンパイラ実行ファイルの名前には、ターゲット アーキテクチャの前に「ross」が追加されます。たとえば、コンパイラが x64 をターゲットとしてビルドされている場合、実行ファイルは ppcrossx64 になります。
選択したアーキテクチャ/OS向けにコンパイルするには、コンパイラスイッチ(コンパイラドライバfpc用)-Pと-Tを使用できます。これはコンパイラ自体をクロスコンパイルする場合にも行われますが、makeオプションCPU_TARGETとOS_TARGETで設定されます。Free Pascalにターゲットプラットフォーム用のツールが内部的に含まれていない場合は、ターゲットプラットフォーム用のGNUアセンブラとリンカが必要です。
Clangは本来クロスコンパイラであり、ビルド時にフラグを使用してClangがターゲットとするアーキテクチャを選択できます-target。[ 15 ]
異種混在システムであるPlan 9とそのツールチェーンは、クロスコンパイルとネイティブコンパイルを区別しません。Makefileはアーキテクチャに依存しません。
これは「カナダ十字」と呼ばれています。なぜなら、名前が必要だった当時、カナダには3つの政党があったからです。
日取得。i386