2013-02-04 28 views
1

假設你正在爲一種叫做Foo的新語言設計和編寫一個編譯器,其中的優點是它對於實現編譯器特別有用。一個經典的方法是用C語言編寫第一個版本的編譯器,然後用它編寫Foo中的第二個版本,然後變成自編譯的。引導一個跨平臺的編譯器

這意味着您必須小心保留二進制文件的備份副本(與大多數只需保留源備份副本的程序相反);一旦語言從第一版本發展而來,如果你丟失了二進制文件的所有副本,那麼你就沒有能力編譯當前版本。就這樣吧。

但假設它旨在同時支持Linux和Windows。只要它實際上在兩個平臺上運行,它都可以在每個平臺上自行編譯,沒有問題。假設你在一個平臺上丟失了二進制文件(或者有理由懷疑它已經被攻擊者入侵);現在有一個問題。對於每個支持的平臺,必須保護二進制文件至少還有一個比我感到滿意的失敗點。

一個解決方案是使其成爲一個交叉編譯器,這樣任一平臺上的二進制文件都可以定位到兩個平臺。

這聽起來並不簡單 - 儘管選擇二進制輸出格式沒有問題,但每個平臺都提供了C頭文件形式的系統API,這些頭文件通常只存在於其本地平臺上,例如,即使編譯爲Linux二進制格式,也不能保證在Windows上編譯的代碼能夠在Linux上運行。

也許這個問題可以通過將Linux頭文件下載到Windows機器上並使用Windows二進制文件交叉編譯Linux二進制文件來解決。

有沒有我缺少的解決方案的任何警告?

另一種解決方案可能是在Python中維護一個單獨的最小引導編譯器,將Foo編譯爲可移植的C,只接受主Foo編譯器所需的語言子集,並執行最小錯誤檢查並且不進行優化,意圖存在引導編譯器將因此保持簡單,以便在後續語言版本中維護它不會花費太多。

再一次,有沒有解決方案我想念的任何警告?

以前有什麼方法讓人們用來解決這個問題?

+1

這真的是個問題嗎?當然,解決方案是「僅使用版本控制來維護原始源代碼」。 –

+1

爲什麼要擔心丟失二進制文件?你還有原始的來源嗎?而且您仍然需要分發原始的C源代碼,以便能夠在尚未擁有Foo編譯器的系統上引導編譯器。 –

+0

因爲隨着時間的推移,語言將會以這樣一種方式發展,即原始的C版本的編譯器將不再能夠理解它。 – rwallace

回答

3

這是C編譯器本身的問題。它通常通過使用交叉編譯器來解決,完全按照您的建議。

交叉編譯編譯器的過程並不比交叉編譯任何其他項目更困難:也就是說,它比你想要的更復雜,但絕不是不可能的。

當然,你首先需要交叉編譯器本身。這可能意味着您的構建配置系統需要進行一些重大的手術,並且您需要從目標(頭文件,庫,以及您需要在構建中引用的其他任何內容)中獲取某種「sysroot」。

因此,最終取決於編譯器的結構。要麼使用歷史資源重新引導更容易,要麼首先重複您經歷的每個語言兼容階段(您確實使用過源代碼版本控制,對嗎?),要麼更容易實現交叉編譯器配置。我無法從這裏告訴你。

多年來,GCC編譯器總是隻寫在符合標準的C代碼中,正是出於這個原因:他們希望能夠在任何操作系統上啓動它,只給出該系統的本地C編譯器。僅在2012年,它決定C++現在已經足夠普及,編譯器本身可以寫入其中。即便如此,他們只允許他們自己使用該語言的一部分。將來,如果有人希望將GCC移植到尚未擁有C++的平臺,則需要使用交叉編譯器或第一個端口GCC 4.7(最後一個主要的C-only版本),然後移至最新版本。

此外,GCC構建過程不會「信任」它所構建的編譯器。當你輸入「make」時,它首先構建一個縮減版本,然後使用該版本構建完整版本。最後,它使用完整版本來重建另一個完整版本,並比較這兩個二進制文件。如果兩者不匹配,就知道原來的編譯器有問題,並且引入了一些錯誤的代碼,並且構建失敗。