GCC và g ++ được khởi động như thế nào?


185

Điều này đã được lỗi tôi cho một lúc. Làm thế nào để GCC và g ++ tự biên dịch?

Tôi đoán rằng mọi sửa đổi sẽ được biên dịch với một phiên bản được xây dựng trước đó. Điều này có đúng không? Và nếu có, điều đó có nghĩa là các phiên bản g ++ và GCC lâu đời nhất đã được viết bằng cách lắp ráp?


13
Mỗi sửa đổi cuối cùng có thể được biên soạn bởi chính nó. :)
Martin Hennings

4
Điều này rất thú vị để đọc nếu bạn muốn xem trình biên dịch đầu tiên xuất hiện như thế nào.
parkovski

1
@parkovski Liên kết có chết không?
Nubdding

Liên kết nhìn thấy lần cuối vào ngày 04 Tháng 6 năm 2016: web.archive.org/web/20160604035203/homepage.ntlworld.com/...
akraf

Câu trả lời:


175

Phiên bản cũ nhất của GCC được biên dịch bằng trình biên dịch C khác, vì có những phiên bản khác khi nó được viết. Trình biên dịch C đầu tiên từ trước đến nay (khoảng năm 1973, IIRC) đã được triển khai trong lắp ráp PDP-11 hoặc bằng ngôn ngữ lập trình B đi trước nó, nhưng trong mọi trường hợp, trình biên dịch B được viết theo cụm.Tương tự, trình biên dịch C ++ đầu tiên (CPre / Cfront , 1979-1983) có thể được triển khai lần đầu tiên trong C, sau đó được viết lại trong C ++.

Khi bạn biên dịch GCC hoặc bất kỳ trình biên dịch tự lưu trữ nào khác, toàn bộ thứ tự xây dựng là:

  1. Xây dựng phiên bản mới của GCC với trình biên dịch C hiện có
  2. xây dựng lại phiên bản GCC mới với phiên bản bạn vừa xây dựng
  3. (tùy chọn) lặp lại bước 2 cho mục đích xác minh.

Quá trình này được gọi là bootstrapping . Nó kiểm tra khả năng tự biên dịch của trình biên dịch và đảm bảo rằng trình biên dịch kết quả được xây dựng với tất cả các tối ưu hóa mà chính nó thực hiện.

EDIT : Drew Dormann, trong các bình luận, chỉ ra tài khoản của Bjarne Stroustrup về việc triển khai C ++ sớm nhất . Nó được triển khai trong C ++ nhưng được dịch bởi cái mà Stroustrup gọi là "tiền xử lý" từ C ++ sang C; không phải là một trình biên dịch đầy đủ theo định nghĩa của anh ta, nhưng C ++ vẫn được bootstraged trong C.


19
Phiên bản 3 bước của quy trình xây dựng bootstrap thực sự là để xác minh: chính trình biên dịch được sử dụng làm trường hợp thử nghiệm của chính nó. GCC được biên dịch với [khác] sẽ tạo ra cùng một kết quả (nhị phân giống hệt nhau, các macro giảm giá như __DATE____TIME__khác nhau ngay cả giữa các lệnh của cùng một trình biên dịch) như GCC được biên dịch với [GCC được biên dịch với [khác]] - nếu không, đó là một lỗi và bản dựng bootstrap 3 giai đoạn được thiết kế để nắm bắt điều đó.
pmdj

19
@pmjordan: "nếu không, đó là một lỗi" hoặc, ít có khả năng, một cửa hậu lệch lạc trong quá trình được giới thiệu ("Phản ánh về niềm tin tin cậy").
Steve Jessop

12
@sleske: điều đó không đúng Đầu ra nhị phân của bước 2 phải giống hệt với đầu ra nhị phân của bước 3, nếu không có lỗi ở đâu đó. Lý do là như pmjordan nói: NewCompiler1 và NewCompiler2 là các chương trình có nguồn giống hệt nhau (của NewCompiler). Chúng được cung cấp đầu vào giống hệt nhau (nguồn cho NewCompiler). Do đó, chúng sẽ tạo ra đầu ra giống hệt nhau cho dù chúng được biên dịch với trình biên dịch nào (trong trường hợp này, NewCompiler1 được biên dịch với OldCompiler và NewCompiler2 được biên dịch với NewCompiler1). Đó là, NewCompiler2 và NewCompiler3 giống hệt nhau nhị phân.
Steve Jessop

12
Tôi có bao giờ bạn tự hỏi: Điều gì sẽ xảy ra nếu chúng ta mất tất cả các nhị phân trình biên dịch C? Và phải bootstrap từ đầu? Đây là cách tôi thực hiện: Có Trình biên dịch Tiny C (thực sự có thể biên dịch nhân Linux, vì vậy nó hoàn toàn có tính năng hoàn chỉnh). Tất cả các tệp nguồn C chỉ tạo ra 30k dòng mã, bao gồm cả các nhận xét. Mặc dù đó là một nỗ lực khá lớn, nhưng ai đó hiểu C có thể học hỏi từ các nguồn, cách tạo đầu ra nhị phân và "biên dịch" các nguồn TCC từ tay (tôi thực sự nghĩ về thẻ đục lỗ ở đây). Sau đó biên dịch lại TCC với điều đó và sử dụng nó để khởi động GCC hoặc tương tự.
datenwolf

11
@datenwolf: đại loại như thế, vâng. Nếu chúng ta có thể giả sử rằng chúng ta đã mất tất cả các nhị phân trình biên dịch C, nhưng chúng ta vẫn có một trình biên dịch chương trình, thì chúng ta có thể viết một chương trình biên dịch chương trình TinyTinyC. Nó sẽ là một trình biên dịch C hoàn chỉnh ít tính năng hơn TinyC: chúng tôi không cần nó để có thể biên dịch GCC hoặc kernel linux, chúng tôi chỉ cần nó để có thể biên dịch TinyC. Sau đó chạy nó trên nguồn TinyC, cung cấp cho chúng tôi trình biên dịch C có khả năng biên dịch Linux (và hy vọng là glibc và GCC) và chúng tôi đang kinh doanh. Nếu chúng ta thậm chí không có trình biên dịch chương trình, thì trước tiên chúng ta sẽ tự khởi động một trong số đó, nó dễ hơn trình biên dịch C.
Steve Jessop
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.