GCC와 g ++는 어떻게 부트 스트랩됩니까?


186

이것은 잠시 동안 나를 괴롭 혔습니다. GCC와 g ++는 어떻게 스스로 컴파일합니까?

모든 개정판이 이전에 작성된 개정판으로 컴파일된다고 생각합니다. 이것이 사실입니까? 그렇다면 그것이 가장 오래된 g ++ 및 GCC 버전이 어셈블리로 작성되었음을 의미합니까?


13
각 개정판은 자체적으로 컴파일 될 수 있습니다. :)
Martin Hennings 2019

4
이것은 첫 번째 컴파일러에 대해 온 방법보고 싶다면 읽는 재미있다.
parkovski

1
@parkovski 링크가 죽었습니까?
Nubcake

마지막 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은 의견에서 Bjarne Stroustrup의 초기 C ++ 구현 에 대한 설명을 지적합니다 . 그것은 C ++로 구현되었지만 Stroustrup이 C ++에서 C로 "전 처리기"라고 부르는 것에 의해 번역되었습니다. 그의 정의에 의한 완전한 컴파일러는 아니지만 여전히 C ++은 C로 부트 스트랩되었습니다.


19
부트 스트랩 빌드 프로세스의 3 단계 버전은 실제로 검증을위한 것입니다. 컴파일러 자체는 자체 테스트 사례로 사용됩니다. GCC 컴파일 [기타]와 동일한 결과를 생성 (같은 매크로 할인 동일한 바이너리를해야 __DATE__하고 __TIME__이는 심지어의 호출에 따라 다를 같은 컴파일러)로 컴파일 GCC 같이 컴파일 GCC [] 기타] - 그렇지 않으면, 버그가 있다고하고, 3 단계 부트 스트랩 빌드는이를 포착하도록 설계되었습니다.
pmdj 2019

19
@pmjordan : "그렇지 않다면 버그 일 것입니다."또는 도입 과정에서 악의적 인 백도어 ( "신뢰의 반영").
Steve Jessop

12
@ sleske : 사실이 아닙니다. 2 단계의 이진 출력은 3 단계의 이진 출력과 동일해야합니다. 그렇지 않으면 어딘가에 버그가 있습니다. pmjordan이 말한 이유는 다음과 같습니다. NewCompiler1과 NewCompiler2는 동일한 소스 (NewCompiler의 소스)를 가진 프로그램입니다. 동일한 입력 (NewCompiler의 소스)이 제공됩니다. 따라서 어떤 컴파일러를 사용하여 컴파일했는지에 관계없이 동일한 결과를 생성합니다 (이 경우 NewCompiler1은 OldCompiler로 컴파일되고 NewCompiler2는 NewCompiler1로 컴파일). 즉, NewCompiler2와 NewCompiler3은 이진 동일합니다.
Steve Jessop

12
궁금한 점이 있습니다. 모든 C 컴파일러 바이너리를 잃어버린 경우 어떻게해야합니까? 그리고 처음부터 부트 스트랩을해야 했습니까? Tiny C Compiler가 있습니다 (실제로는 Linux 커널을 컴파일 할 수 있으므로 기능이 완전합니다). C 소스 파일은 주석을 포함하여 30k 줄의 코드 만 만듭니다. 비록 약간의 노력이 있었지만 C를 이해하는 사람은 소스에서 이진 출력을 생성하고 TCC 소스를 "컴파일"하는 방법을 소스에서 배울 수 있습니다 (실제로 펀치 카드를 생각합니다). 그런 다음 TCC를 다시 컴파일하여 GCC 또는 이와 유사한 부트 스트랩을 사용하십시오.
datenwolf

11
@datenwolf : 그래요. C 컴파일러 바이너리를 모두 잃었다 고 가정 할 수 있지만 여전히 어셈블러가있는 경우 어셈블러 프로그램 TinyTinyC를 작성할 수 있습니다. TinyC보다 기능이 완전하지 않은 C 컴파일러 일 것입니다. GCC 나 리눅스 커널을 컴파일하는 데 필요하지 않고 TinyC 만 컴파일 할 수 있으면됩니다. 그런 다음 TinyC 소스에서 실행하면 Linux (및 glibc 및 GCC)를 컴파일 할 수있는 C 컴파일러가 제공되며 비즈니스에 종사합니다. 우리는 어셈블러가 없다면 먼저 그중 하나를 부트 스트랩 할 것이고, C 컴파일러보다 쉽습니다.
Steve Jessop 2012
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.