C/C++編譯器的一些易混淆概念,總結一下。
關於什麼是Unix-like操做系統,常見操做系統間差別,什麼是操做系統接口等等,請參考《操做系統寶鑑》。java
首先是如雷貫耳的這幾位仁兄,MSVC、GCC、Cygwin、MingW(Cygwin和MingW的英文發音),另外還有些小衆和新秀,像ICC(Intel C/C++ Compiler)、BCC(Borland C/C++ Compiler,快銷聲匿跡了)、RVCT(ARM的彙編/C/C++編譯器,內置在ARM的IDE——RVDS中)、Pgi編譯器……其實有一大串,咱們只要熟悉經常使用的最強大的幾款就能夠了。算法
MSVCshell
MSVC是微軟Windows平臺Visual Studio自帶的C/C++編譯器。編程
優勢:對Windows平臺支持好,編譯快。windows
缺點:對C++的新標準支持得少。網絡
GCCsocket
GCC原名GNU C Compiler,後來逐漸支持更多的語言編譯(C++、Fortran、Pascal、Objective-C、Java、Ada、Go等),因此變成了GNU Compiler Collection(GNU編譯器套裝),是一套由GNU工程開發的支持多種編程語言的編譯器。GCC是自由軟件發展過程當中的著名例子,由自由軟件基金會以GPL協議發佈,是大多數類Unix(如Linux、BSD、Mac OS X等)的標準編譯器,並且適用於Windows(藉助其餘移植項目實現的,好比MingW、Cygwin等)。GCC支持多種計算機體系芯片,如x8六、ARM,並已移植到其餘多種硬件平臺。編程語言
優勢:類Unix下的標準編譯器,支持衆多語言,支持交叉編譯。工具
缺點:默認不支持Windows,須要第三方移植纔可用於Windows。性能
Cygwin
Cygwin是一個Windows下Unix-like模擬環境,具體說就是Unix-like接口(OS API,命令行)重定向層,其目的是不修改軟件源碼僅從新編譯就能夠將Unix-like系統上的軟件移植到Windows上(這個移植也許還算不上嚴格意義上的無縫移植)。始於1995年,最初做爲Cygnus軟件公司工程師Steve Chamberlain的一個項目。
和GCC的關係:Cygwin是讓Windows擁有Unix-like環境的軟件而不是編譯器,GCC是安裝在Cygwin上的編譯器。
優勢:能夠比MingW移植更多的軟件到Windows上,對Linux接口模擬比MingW全面。
缺點:軟件運行依賴cygwin1.dll,速度受點影響。
注意:Unix-like模擬環境不是Unix虛擬環境,不少論述中都聲稱Cygwin是在Windows上儘量模擬類Unix環境,這容易形成誤解,好像類Unix的elf程序能夠直接運行在安裝了Cygwin的Windows上同樣。Cygwin和Wine的思路是不一樣的。在Windows+Cygwin上你能夠像類Unix那樣使用命令行和編程,但elf等非exe格式的程序是不能被Cygwin運行的,因此Cygwin和Unix虛擬機、Wine是徹底不一樣的,叫Unix-like環境,模擬非虛擬,是有限的選擇性的模擬,請不要誤解。
MingW
MingW(Minimalist GNU on Windows)是一個Linux/Windows下的能夠把軟件源碼中Unix-like OS API調用經過頭文件翻譯替換成相應的Windows API調用的編譯環境,其目的和Cygwin相同。從而把Linux上的軟件在不修改源碼的狀況下編譯爲可直接在Win下執行的exe。
和GCC的關係:MingW是編譯環境,不是編譯器,GCC是MingW中的核心組成。
優勢:在Win下能夠和Linux同樣的方式編譯C/C++源碼,能夠說是Win版的GCC,其生產的Windows PE程序相比Cygwin不依賴任何第三方庫,比Cygwin純粹,理論上也更快速。
缺點:編譯速度、編譯出的程序在算法上可能都比MSVC慢。
注意:與Windows下其它編譯器不一樣的是,MinGW與Linux下普遍使用的GNU近乎徹底兼容,這意味着,在Linux下如何編譯源代碼,在MinGW中也能夠以徹底相同的方式編譯。有些Linux下的開發人員(好比開源陣營)發佈的源代碼一般只提供Linux下的編譯方式,而不提供Windows下的編譯方式(這可能與其不熟悉windows操做系統有關),但確實有很多用戶須要在在Windows下編譯使用此源代碼。這在種狀況下,若是Windows用戶想用VC、BC等編譯器編譯該源代碼,必須重寫Makefile(各類編譯器所支持的Makefile不盡相同),工做量比較大不說,還很難保證不出錯。MinGW的出現,提供了兩個平臺下的「跨平臺編譯方案」。MinGW與MSYS相配合,連./configure都有了。與GNU不一樣的是,MinGW編譯生成的是Windows下的可執行文件(.exe)或庫文件(.dll,.lib)——不過編譯過程當中的的中間文件仍然是.o文件,而不是.obj文件(這固然無所謂了,中間文件嘛,編譯完成後就沒有用了)。
在咱們對比Cygwin和MingW以前,請先理清一件事,那就是,
現代操做系統包括Windows和Linux的基本設計概念,像進程線程地址空間虛擬內存這些都大同小異,兩者之上的程序之因此不兼容,主要是它們對這些功能具體實現上的差別:
首先,是可執行文件的格式,Window使用PE的格式,而且要求以.EXE爲後綴名,Linux則使用Elf。
其次,操做系統API也同,好比,Windows用CreateProcess()建立進程,而Unix-like系統則使用fork(),其餘還有不少諸如spawn、signals、select、sockets等。
分析以後可知,要把Unix-like系統上的軟件移植到Windows上,有幾種思路:
第一種:修改軟件源碼並從新編譯,這個方法最笨,類Unix下大量的軟件要修改工做量很大,編譯生成目標平臺可執行文件格式。
第二種:不修改軟件源碼但把類Unix接口調用悄悄替換爲WinAPI,仍是須要從新編譯,編譯生成目標平臺可執行文件格式。
第三種,無縫移植的運行環境,無需從新編譯,在一種OS上創建另外一中OS的應用軟件虛擬環境(和虛擬機不同),好比Wine(把Windows上的可執行程序直接原樣移植到Linux上)。
做爲編譯環境時,都依賴於GCC
用它們做編譯環境、交叉編譯,根本上都是由於GCC編譯器的支持,它們作的工做是爲GCC的編譯掃除Unix-like、Windows間OS API的差別這個障礙。
兩者都必須從新編譯後實現移植,生成的程序都是PE格式
兩者都不能讓Linux下的程序直接運行在Windows上(無縫移植),必須經過源代碼從新編譯。有些人聲稱cygwin支持rpm的壓縮包,注意,rpm壓縮包實際上是src.rpm,內部仍是源碼而非elf格式,cygwin不支持常規rpm包的安裝。
Cygwin運行在Windows上,MingW運行在Linux或者Windows上
Cygwin是Windows上運行的Unix-like環境,MingW是運行在Linux或者Windows上的Windows PE編譯環境。
MingW中的子項目MSys和Cygwin更像
Cygwin除了全面模擬Linux的接口(命令行,OS API),提供給運行在它上面的的Windows程序使用,並提供了大量現成的軟件,更像是一個平臺。MingW也有一個叫MSys(Minimal SYStem)的子項目,主要是提供了一個模擬Linux的Shell和一些基本的Linux工具。由於編譯一個大型程序,光靠一個GCC是不夠的,還須要有Autoconf等工具來配置項目,因此通常在Windows下編譯ffmpeg等Linux下的大型項目都是經過Msys來完成的,固然Msys只是一個輔助環境,根本的工做仍是MingW來作的。
實現思路有同有異
Cygwin和MingW都是第二種軟件移植思路,固然,兩者仍是有區別,區別就在於「替換」方式,Cygwin編譯時,程序依然以Linux的方式調用系統API,只不過把Unix-like接口link到本身的cygwin1.dll上,而後在cygwin1.dll中從新調用Windows API,cygwin1.dll再調用Windows對應的實現,來把結果返回給程序。也就是說,他們基於Win32 API中寫了一個Unix系統API的重定向層,因此用它移植的軟件都依賴於cygwin1.dll,MingW編譯時經過特有的WinAPI頭文件把類Unix-like調用替換爲WinAPI,用它移植的軟件無需依賴第三方庫,可直接運行在Windows平臺。爲了達到類Unix軟件僅經過從新編譯移植到Win的目的,Cygwin在運行時偷樑換柱,MingW在編譯時偷樑換柱。
用一個PE格式查看工具檢查一下就能發現,Cygwin生成的程序依然有fork()這樣的Linux系統調用,但目標庫是cygwin1。而MingW生成的程序,則所有使用從KERNEL32導出的標準Windows系統API。
使用方式有同有異
把類Unix上的軟件移植到Windows是兩者的主要目標,除此以外,順帶的,MingW和Cygwin均可以用來跨平臺開發等等其餘事情,
Windows + Cygwin:能夠在Windows上學習Linux命令,還能夠在Windows上作Linux軟件的開發,包括用GCC編譯elf(交叉編譯)。
Linux + MingW:能夠在Linux上作Windows軟件的開發,包括用GCC編譯exe(交叉編譯)。
Windows/Linux + MingW:能夠擺脫MSVC的「束縛」,用GNU的自由軟件來編譯生成不依賴第三方庫的純粹Windows PE格式(exe)二進制程序。
Cygwin重量級,MingW輕量級
與MingW思路一致的,二者相比,Cygwin是重量級的(需下載50M以上直至數百兆不等,安裝後佔用空間可達1G),MinGW是輕量級的(需下載的文件只有20M,安裝後70M左右),這是單純從體積上說的,另外Cygwin如今聽說也不是徹底免費的了。
網絡上的對比列表(UnxUtils自行無視,僅供參考)
功能 |
UnxUtils |
MinGW |
Cygwin |
設計原理 |
原生 |
原生 |
模擬 |
運行依賴 |
無依賴 |
依賴msys.dll(必定依賴它嗎?值得驗證) |
依賴cygwin.dll |
運行性能(比較) |
最快 |
中等 |
慢 |
DOS執行 |
能夠 |
能夠 |
不能夠 |
更新速度 |
完善中止更新 |
較慢 |
基本同步gcc |
shell命令 |
較多 |
較少 |
較多 |
uname |
WindowsNT |
MINGW32_NT-5.1 |
CYGWIN_NT-5.1 |
env |
同Windows |
同Windows |
不徹底同Windows |
root |
C:/ |
C:/ |
/ |
home |
C:/Documents and Settings/test |
/home/test: No such file or directory |
/home/test |
pwd |
C:/bin |
/usr/bin |
/home/test |
df |
cannot read table of mounted filesystems |
無 |
/cygdrive/c |
vi |
無 |
無 |
有 |
gcc套件 |
無 |
有 |
有 |
開發庫 |
無 |
WinAPI |
POSIX |
圖形庫 |
無 |
GTK/QT |
GTK/QT |
可移植性 |
無 |
Win32API不可移植 |
無縫移植 |
程序運行 |
無 |
原生 |
模擬 |
程序依賴 |
無 |
無 |
cygwin.dll |
程序性能(比較) |
無 |
較快(慢於VC和Linux下的gcc) |
較慢(快於java) |
一個編譯器編譯時可否調用編譯其餘編譯器產生的lib、dll?
不能夠,name***不一樣,也就是名字混淆方式不一樣。
http://rendao.org/blog/1071/