GCCとg ++はどのようにブートストラップされますか?


186

これはしばらくの間私を悩ませてきました。GCCとg ++はどのようにコンパイルされますか?

すべてのリビジョンが以前にビルドされたリビジョンでコンパイルされると思います。これは本当ですか?もしそうなら、最も古いg ++とGCCのバージョンがアセンブリで記述されたことを意味しますか?


13
最終的に、各リビジョンを単独でコンパイルできます。:)
マーティンヘニングス2012

4
これは、最初のコンパイラがどのようにして生まれたのかを知りたい場合に読むと興味深いでしょう。
parkovski

1
@parkovskiリンクは切れていますか?
Nubcake 2017

最後の2016年6月4日に見リンク:web.archive.org/web/20160604035203/homepage.ntlworld.com/...
akraf

回答:


175

GCCの最も古いバージョンは、別のCコンパイラを使用してコンパイルされました。史上初のCコンパイラ(1973年頃、IIRC)は、PDP-11アセンブリ、またはそれに先行するBプログラミング言語で実装されましたが、いずれの場合もBコンパイラはアセンブリで記述されていました。同様に、最初のC ++コンパイラー(CPre / Cfront、1979-1983)はおそらくCで最初に実装され、その後C ++で書き直されました。

GCCまたはその他のセルフホスティングコンパイラをコンパイルする場合、ビルドの完全な順序は次のとおりです。

  1. 既存のCコンパイラでGCCの新しいバージョンをビルドする
  2. ビルドしたばかりのGCCの新しいバージョンを再ビルドします
  3. (オプション)確認のためにステップ2を繰り返します。

このプロセスはブートストラップと呼ばれますます。コンパイラー自体のコンパイル機能をテストし、コンパイラー自体が実装するすべての最適化でコンパイラーがビルドされることを確認します。

編集:Drew Dormannは、コメントの中で、C ++の最も初期の実装に関するBjarne Stroustrupの説明を指摘しています。これはC ++で実装されましたが、StroustrupがC ++からCに「プリプロセッサ」と呼ぶものによって翻訳されました。彼の定義では完全なコンパイラではありませんが、それでもC ++はCでブートストラップされました。


19
ブートストラップビルドプロセスの3ステップバージョンは確かに検証用です。コンパイラ自体が独自のテストケースとして使用されます。[その他]でコンパイルGCCは同じ結果(同じバイナリのようなマクロを割り引く生成すべき__DATE____TIME__の呼び出しの間でさえ変化する同一の [他の] [でコンパイルGCC]でコンパイルGCCなどのコンパイラ) -ていない場合、それはバグだ、と3ステージブートストラップビルドは、それをキャッチするように設計されています。
pmdj

19
@pmjordan:「そうでない場合、それはバグです」、または可能性は低いですが、導入される過程での不正なバックドア(「信頼を信頼することについての反射」)。
Steve Jessop、2012

12
@sleske:それは真実ではありません。ステップ2のバイナリ出力は、ステップ3のバイナリ出力と同じでなければなりません。そうでなければ、どこかにバグがあります。その理由は、pmjordanが言うとおりです。NewCompiler1とNewCompiler2は、同じソース(NewCompilerのソース)を持つプログラムです。それらには同一の入力(NewCompilerのソース)が与えられます。したがって、コンパイラ自体がコンパイルされたコンパイラに関係なく、同じ出力を生成します(この場合、NewCompiler1はOldCompilerでコンパイルされ、NewCompiler2はNewCompiler1でコンパイルされました)。つまり、NewCompiler2とNewCompiler3はバイナリが同一です。
Steve Jessop、2012

12
私は今までに疑問に思った:すべてのCコンパイラバイナリを失ったらどうなるか?そして、最初からブートストラップする必要がありましたか?これが私のやり方です。TinyCコンパイラがあります(実際にはLinuxカーネルをコンパイルできるため、完全な機能を備えています)。それがすべてCのソースファイルであれば、コメントを含めてわずか30k行のコードになります。それはかなりの努力でしたが、Cを理解している人はソースからバイナリ出力を生成し、TCCソースを手作業で "コンパイル"する方法を学ぶことができました(私は実際にここでパンチカードを考えています)。次に、それを使用してTCCを再コンパイルし、それを使用してGCCなどをブートストラップします。
datenwolf

11
@datenwolf:そのようなもの、はい。すべてのCコンパイラバイナリが失われたと想定できても、アセンブラがまだある場合は、アセンブラプログラムTinyTinyCを作成します。TinyCよりも機能が完全ではないCコンパイラになります。GCCやLinuxカーネルをコンパイルできるようにする必要はなく、TinyCをコンパイルできる必要があるだけです。次に、それをTinyCのソースで実行します。これにより、Linux(およびできればglibcとGCC)をコンパイルできるCコンパイラーが提供され、ビジネスが開始されます。アセンブラさえもない場合は、最初にそれらの1つをブートストラップします。これはCコンパイラよりも簡単です。
Steve Jessop
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.