c 各類編譯器(gcc clang)

不少時候,出現一些相似GNU,GCC,CLANG,LLVM等與編譯器有關的名詞的時候,都不太清楚它究竟是幹嗎的,理解這些東西后,
對於xcode中不少配置型的需求修改起來都會駕輕就熟,所以有必要了解透徹他們直接的關係與區別。

1 GUN
 
「GNU,名稱來自Gnu's Not Unix"的縮寫,一個類UNIX操做系統,由GNU計劃推進,目標在於建立一個徹底兼容於UNIX自由軟件環境。」
因爲當時UNIX系統是商業軟件,是收費的,並且有一部分源碼是沒有開放的,因此在1983年,理查德·斯托曼提出GNU計劃,但願發展出一套完整的開放源代碼操做系統來取代Unix,計劃中的操做系統,名爲GNU。
所以,GNU的出現的目的就是爲了取代UNIX系統。
可是操做系統是包括不少軟件的,除了操做系統內核以外,還要有編輯器,編譯器, shell等等一些軟件來支持。
      1989年,GNU項目中的其餘部份,如編輯器、編譯器、shell等都已經完成,獨缺操做系統核心。1990年,自由軟件基金會開始正式發展Hurd,做爲GNU項目中的操做系統。
注意:linux並非GNU計劃的一部分。linux只是使用了許多GNU計劃軟件(包括GCC編譯器,文本編譯器等)。
      1991年,Linux出現,全部GNU項目中,運行於用戶空間的軟件,均可以在Linux上使用。許多開發者轉向於Linux,Linux成爲常見的GNU計劃軟件運行平臺。理查德·斯托曼主張,Linux操做系統使用了許多GNU計劃軟件,應正名爲GNU/Linux,但沒有獲得Linux社區的一致認同,造成GNU/Linux命名爭議
1992年,Linux與其餘GNU軟件結合,徹底自由的操做系統正式誕生。許多程序員參與了Linux的開發與修改,也常常將Linux當成開發GNU計劃軟件的平臺。該操做系統每每被稱爲「GNU/Linux」或簡稱Linux。但Linux自己不屬於GNU計劃的一部份,GNU計劃本身的內核Hurd依然在開發中,但直到2013年爲止,都尚未穩定版本發佈。

GNU工程十幾年以來已經成爲一個對軟件開發主要的影響力量,創造了無數的重要的工具,例如:強健的編譯器,有力的文本編輯器,甚至一個全功能的操做系統。這個工程是從1984年麻省理工學院的程序員理查德·斯托曼的想法得來的,他想要建立一個自由的、和UNIX相似的操做環境。從那時開始,許多程序員彙集起來開始開發一個自由的、高質量、易理解的軟件。
GNU計劃採用了部分當時已經可自由使用的軟件,例如TeX排版系統和X Window視窗系統等。不過GNU計劃也開發了大批其餘的自由軟件,這些軟件也被移植到其餘操做系統平臺上,例如Microsoft WindowsBSD家族、SolarisMac OS
許多UNIX系統上也安裝了GNU軟件,由於GNU軟件的質量比以前UNIX的軟件還要好。
因此,GNU計劃中的許多軟件目前在全部的操做系統中都應用普遍(Unix,mac,linux,windows,bsd...),最出名的就是GCC了

總結:
       GNU計劃原本是爲了開發一個自由系統來取代UNIX的,可是因爲開發的內核hurd一直不怎麼樣,這個系統至今都沒出穩定版本,然而GNU計劃中開發的其餘一些自由軟件,好比GCC編譯器,卻很是的好,在移植到各大操做系統上一直普遍使用至今。
注意一點:
     文中說的自由軟件,千萬別與免費軟件混淆了,自由是說你能夠自由的使用,固然前提是得到了源碼才能自由的使用。
好比,你在一個應用裏面使用了gcc計劃的軟件,你賣本身的應用多少錢你本身定。免費的軟件不必定是開源的。


2. GCC

「 GCCGNU Compiler CollectionGNU編譯器套裝),是一套由GNU開發的編程語言編譯器。它是一套以GPLLGPL許可證所發佈的自由軟件,也是GNU項目的關鍵部分,亦是自由的類Unix及蘋果電腦Mac OS X 操做系統的標準編譯器。GCC(特別是其中的C語言編譯器)也常被認爲是跨平臺編譯器的事實標準。

GCC原名爲GNU C語言編譯器GNU C Compiler),由於它本來只能處理C語言。GCC很快地擴展,變得可處理C++。以後也變得可處理FortranPascalObjective-CJavaAda,以及Go與其餘語言。html

本來用C開發,後來由於LLVMClang的崛起,令GCC更快將開發語言轉換爲C++。許多C的愛好者在對C++只知其一;不知其二的狀況下主觀認定C++的性能必定會輸給C,可是Taylor給出了不一樣的意見,並代表C++不但性能不輸給C,並且能設計出更好,更容易維護的程序 

因爲GCC已成爲GNU系統的官方編譯器(包括GNU/Linux家族),它也成爲編譯與建立其餘操做系統的主要編譯器,包括BSD家族、Mac OS XNeXTSTEPBeOS前端

GCC一般是跨平臺軟件的編譯器首選。有別於通常侷限於特定系統與運行環境的編譯器,GCC在全部平臺上都使用同一個前端處理程序,產生同樣的中介碼,所以此中介碼在各個其餘平臺上使用GCC編譯,有很大的機會可獲得正確無誤的輸出程序。 

總結:
mac以前的cocoa框架即是用GCC編譯的,因此ios與mac os都是默認使用的GCC編譯器(如今是clang與llvm,下面會有介紹)
android的系統層由於是linux內核,天然也是GCC編譯的,可是android的app由於是運行在Dalvik虛擬機因此用的不是GCC。
windows的應用,大部分都是使用的vs系列的編譯器,畢竟是windows自家的編譯器,用到GCC的很少。

3.Clang

先看看wiki百科上的官方說明:  http://zh.wikipedia.org/wiki/Clang
「  Clang 是一個CC++Objective-CObjective-C++編程語言的編譯器前端。它採用了底層虛擬機(LLVM)做爲其後端。
它的目標是提供一個GNU編譯器套裝(GCC)的替代品。 Clang項目包括Clang前端和Clang靜態分析器等。

這個軟件項目在2005年由蘋果電腦發起,是LLVM編譯器工具集的前端(front-end),目的是輸出代碼對應的抽象語法樹(Abstract Syntax Tree, AST),並將代碼編譯成LLVM Bitcode。接着在後端(back-end)使用LLVM編譯成平臺相關的機器語言 。Clang支持C、C++、Objective C。linux

Clang自己性能優異,其生成的AST所耗用掉的內存僅僅是GCC的20%左右。FreeBSD 10將Clang/LLVM做爲默認編譯器.
測試證實Clang編譯Objective-C代碼時速度爲GCC的3倍,還能針對用戶發生的編譯錯誤準確地給出建議。 

總結:
GCC目前做爲跨平臺編譯器來講它的兼容性無異是最強的,兼容最強確定是以犧牲必定的性能爲基礎的,蘋果爲了提升性能,所以專門針對mac系統開發了專用的編譯器clang與llvm,clang用於編譯器前段,llvm用於後端。

3.LLVM

LLVM它是一個編譯器的基礎建設,以C++寫成。它是爲了任意一種編程語言寫成的程序,利用虛擬技術,創造出編譯時期鏈結時期運行時期以及「閒置時期」的優化。

在Xcode4以後,蘋果將Xcode的默認編譯器變成了LLVM,爲何呢?

LLVM歷史android

    Apple(包括中後期的NeXT) 一直使用GCC做爲官方的編譯器。GCC做爲開源世界的編譯器標準一直作得不錯,但Apple對編譯工具會提出更高的要求。ios

    一方面,是Apple對Objective-C語言(甚至後來對C語言)新增不少特性,但GCC開發者並不買Apple的賬——不給實現,所以索性後來兩 者分紅兩條分支分別開發,這也形成Apple的編譯器版本遠落後於GCC的官方版本。另外一方面,GCC的代碼耦合度過高,很差獨立,並且越是後期的版本, 代碼質量越差,但Apple想作的不少功能(好比更好的IDE支持)須要模塊化的方式來調用GCC,但GCC一直不給作,從根本上限制了LLVM-GCC 的開發。 因此,這種不和讓Apple一直在尋找一個高效的、模塊化的、協議更放鬆的開源替代品,因而Apple請來了編譯器高材生Chris Lattner, LLVM就這樣產生了。

Clang歷史

    Apple吸取Chris Lattner的目的要比改進GCC代碼優化宏大得多——GCC系統龐大而笨重,而Apple大量使用的Objective-C在GCC中優先級很低。此 外GCC做爲一個純粹的編譯系統,與IDE配合得不好。加之許可證方面的要求,Apple沒法使用LLVM 繼續改進GCC的代碼質量。因而,Apple決定從零開始寫 C、C++、Objective-C語言的前端 Clang,徹底替代掉GCC。程序員

    正像名字所寫的那樣,Clang只支持C,C++和Objective-C三種C家族語言。2007年開始開發,C編譯器最先完成,而因爲Objective-C相對簡單,只是C語言的一個簡單擴展,不少狀況下甚至能夠等價地改寫爲C語言對Objective-C運行庫的函數調用,所以在2009年時,已經徹底能夠用於生產環境。C++的支持也熱火朝天地進行着。  shell

更詳細的緣由:

總結:
由於GCC的編譯器已經慢慢沒法知足蘋果的需求,所以,蘋果開發了Clang與LLVM來徹底取代GCC,Xcode4以後,蘋果的默認編譯器已是LLVM了。Clang做爲編譯器前端,LLVM做爲編譯器後端。
在Xcode6.0中查看默認編譯器:

4.編譯器相關知識
問題:蘋果以clang做爲編譯器前端,llvm做爲編譯器後端,那麼編譯器的先後端究竟是什麼東西呢?
     咱們先回到一個常識性的問題,什麼是編譯器呢?簡單地說,編譯器能夠看做是一個語言翻譯器。就像把中文翻譯成英語同樣,編譯器能夠把高級語言翻譯成計算機可以執行的機器語言。這樣看來,GCC能夠算得上是一個精通多國語言的高級翻譯官了。
最簡單的GCC使用指令以下所示:
gcc  hello.c  -o  hello
GCC接受hello.c做爲輸入,最後產生目標可執行代碼hello。這個簡單的流程實際上經歷了不少步驟,以下圖所示:
雖然咱們只用了一條命令就完成了編譯,但實際上gcc命令依次呼叫了cpp,gcc本身,gas以及ld來進行完整的編譯流程,最後生成最終的可執行文件hello。 

學過編譯原理這門課程的同窗對下面這副圖應該很熟悉,這是經典的編譯流程。編程

 

下面以GCC編譯器爲例,GCC做爲經典的編譯器,天然也是遵循這個教科書流程(實際GCC的處理更復雜點,但本質上是同樣的)。咱們先簡化一下上面這幅圖,以中間代碼爲分界,前面的詞法分析、語法分析、語義分析咱們把它稱之爲前端處理,後面的優化和目標代碼生成咱們稱之爲後端處理。windows

試想一下,是否能夠爲不一樣的高級語言單獨寫一個前端,而後爲不一樣的處理器架構單獨寫一個後端呢?後端

 

GCC基本上也是這麼實現的,不過不要誤會,並無一個統一的gcc執行程序可以處理如此多的前端和後端,每一個語言的編譯器都是一個獨立的程序(如C語言 的編譯器是gcc,C++的編譯器是g++),而不一樣的後端也要對應不一樣的可執行程序。你能夠下載單獨的一份GCC源代碼,經過不一樣的configure 來生成本身須要的編譯器。

並且,編譯器的實現也比上圖要複雜的多,前端的主要功能是產生一個可供後端處理的語法樹,而語法樹結構實際上很難與處理器架構脫鉤,這些都是編譯器應用中須要解決的問題。

GCC強大的真正緣由是什麼?是由於它支持了衆多的前端和後端嗎?這些都不過是一個表象而已。GCC是一款真正自由的編譯器,咱們能夠隨時把代碼拿過來修 改以實現本身須要的功能。若是你的硬件平臺增長了一些指令,而普通的編譯器並不能產生這些指令怎麼辦?在GCC後端添加這些指令吧。若是你以爲C語言用的 不太順手,想給它添加一些功能怎麼辦?修改GCC的前端吧。由於有了GCC,咱們才擁有這些自由,以及迅速實現本身想法的能力,而這些纔是GCC強大背後 的基礎。

相關文章
相關標籤/搜索