1. 程式人生 > >Cygwin、MinG、MSys區別與聯絡(轉)

Cygwin、MinG、MSys區別與聯絡(轉)

轉自:https://www.biaodianfu.com/cygwin-ming-msys.html

什麼是Cygwin?
Cygwin,原Cygnus出品(已被紅帽收購),目前是RedHat名下的專案。專案的目的是提供運行於 Windows 平臺的類 Unix 環境(以 GNU 工具為代表)。為了達到這個目的,Cygwin 提供了一套抽象層 dll,用於將部分 Posix 呼叫轉換成 Windows 的 API 呼叫,實現相關功能。這裡面最典型的,最基本的模擬層就是那個cygwin1.dll。除此之外,隨著 Linux 系統的發展壯大,目前的 Cygwin 已經不僅僅提供 POSIX 相容,因此也順帶多了更多模擬層的依賴關係。Cygwin的主要目的是通過重新編譯,將POSIX系統(例如Linux、BSD,以及其他Unix系統)上的軟體移植到Windows上。

Cygnus當初首先把gcc,gdb,gas等開發工具進行了改進,使他們能夠生成並解釋win32的目標檔案。然後,他們要把這些工具移植到 windows平臺上去。一種方案是基於win32 api對這些工具的原始碼進行大幅修改,這樣做顯然需要大量工作。因此,他們採取了一種不同的方法——他們寫了一個共享庫(就是cygwin dll),把win32 api中沒有的unix風格的呼叫(如fork,spawn,signals,select,sockets等)封裝在裡面,也就是說,他們基於 win32 api寫了一個unix系統庫的模擬層。這樣,只要把這些工具的原始碼和這個共享庫連線到一起,就可以使用unix主機上的交叉編譯器來生成可以在 windows平臺上執行的工具集。以這些移植到windows平臺上的開發工具為基礎,cygnus又逐步把其他的工具(幾乎不需要對原始碼進行修改, 只需要修改他們的配置指令碼)軟體移植到windows上來。這樣,在windows平臺上執行bash和開發工具、使用者工具,感覺好像在unix上工作。

Cygwin 的目錄結構基本照搬了 linux 的樣子,但同時,也相容了 Windows 的許多功能:大部分應用使用 Unix 風格的路徑,Windows的碟符通過類似掛載點的方式提供給 Cygwin 使用;Cygwin 中既可以執行 Cygwin 的應用(依賴模擬層),又可以執行 Windows 應用,而傳遞給應用的路徑會經過它的模擬層變換,以此保證程式執行不會出錯。

由於它的模擬層實現了相當良好的 Posix 相容,人們試著將許多重要的 Linux/BSD 應用移植到了Cygwin下,使得Cygwin越來越大,功能也越來越豐富,以至於目前很多人直接把將Linux應用移植到Windows平臺的任務都交給了Cygwin(當然,這種移植並非原生)。

Cygwin是運行於Windows平臺的POSIX“子系統”,提供Windows下的類Unix環境,並提供將部分Linux 應用“移植”到Windows平臺的開發環境的一套軟體。cygwin官方的一個定義是Cygwin is not a way to run native linux apps on Windows. You have to rebuild your application from source if you want it to run on Windows。cygwin不是讓linux程式能在windows上執行的方法,如果你想要讓linux程式能在windows執行,那麼你只有用cygwin來重新編譯一下原始檔。這句話完全反駁了無縫執行在linux的說法。就是說你在linux上編譯的elf程式不能直接拿到cygwin上執行,同樣,你用cygwin編譯的程式也不是linux的elf格式,而是exe格式,exe是無法在linux上執行的。

官方網站:https://www.cygwin.com/

什麼是MinGW?
MinGW,Minimalist GNU for Windows,用於開發原生(32位) Windows 應用的開發環境。它主要提供了針對 win32 應用的 GCC、GNU binutils 等工具,以及對等於 Windows SDK(的子集)的標頭檔案和用於 MinGW 版本 linker 的庫檔案(so、a等,而不是 VC 的 lib)。

在基本層,MinGW 是一組包含檔案和埠庫,其功能是允許控制檯模式的程式使用微軟的標準C執行時間庫(MSVCRT.DLL),該庫在所有的 NT OS 上有效,在所有的 Windows 95 發行版以上的 Windows OS 有效,使用基本執行時間,你可以使用 GCC 寫控制檯模式的符合美國標準化組織(ANSI)程式,可以使用微軟提供的 C 執行時間擴充套件。該功能是 Windows32 API 不具備的。下一個組成部分是 w32api 包,它是一組可以使用 Windows32 API 的包含檔案和埠庫。與基本執行時間相結合,就可以有充分的權利既使用 CRT(C Runtime)又使用 Windows32 API 功能。

MinGW 能夠替代 cl 用於編譯不包含 MFC 的、以 WinSDK 為主的 Windows 應用,並且編譯出來的應用不依賴於第三方的模擬層支援,其執行時為大部分 Windows 標配的 msvcrt(故稱原生 Windows 應用)。除此之外,MinGW 也支援 GCC 支援的其他語言。因為這些原因,MinGW 被許多 Linux 上發展起來的開發工具選擇為 Windows 版本的預設編譯器,例如 Code:Blocks,例如 Dev C++。

MinGW是從Cygwin(1.3.3版)基礎上發展而來。

前面提到的 MinGW,是針對 32 位 Windows 應用開發的。而且由於版本問題,不能很好的支援較新的 Windows API。MinGW-W64 則是新一代的 MinGW,支援更多的 API,支援 64 位應用開發,甚至支援 32 位 host 編譯 64 位應用以及反過來的“交叉”編譯。除此之外,它本身也有 32 位和 64 位不同版本,其它與 MinGW 相同。

官方網站:http://www.mingw.org/

什麼是MSys?
MSYS的全稱叫Minimal SYStem,是MinGW的一個子系統,Unix-like command line utilities,是一套執行在Windows上的bash,包括基本的bash, make, gawk and grep 等等。也就是執行在Win上的Linux Terminal。通常也可以認為是小型的UNIX on Windows。提供在windows上模擬Unix環境來使用MinGW。這個比較好理解,其實就是在Win上使用Linux的命令列進行操作,可以代替cmd來使用。對一些GNU的開源軟體,MSYS可能是必需的,因為它們通常需要./configure然後make才能執行。

編譯一個大型程式,光靠一個GCC是不夠的,還需要有Autoconf等工具來配置專案,所以一般在Windows下編譯ffmpeg等Linux下的大型專案都是通過Msys來完成的,當然Msys只是一個輔助環境,根本的工作還是MingW來做的。

與 Cygwin 的大而全不同,MSYS 是衝著小巧玲瓏的目標去的,所以整套 MSYS 以及 MinGW,主要以基本的 Linux 工具為主,大小在 200M 左右,並且沒有多少擴充套件能力。MSYS 是用於輔助 Windows 版 MinGW 進行命令列開發的配套軟體包,提供了部分 Unix 工具以使得 MinGW 的工具使用起來方便一些。如果不喜歡龐大的 Cygwin,而且使用不多,可以試試。不過喜歡完整體驗、不在乎磁碟佔用等等,還是推薦 Cygwin 而不是 MSYS。

由於 MinGW 萬年不更新,MSYS 更是,Cygwin的許多新功能 MSYS 沒有同步過來,於是 Alex 等人建立了新一代的 MSYS 專案。仍然是 fork 了 Cygwin(較新版),但有個更優秀的包管理器 pacman,有活躍的開發者跟使用者組,有大量預編譯的軟體包(雖然肯定沒有Cygwin多)……對於不喜歡龐大的 Cygwin 的使用者而言,推薦試試 msys2。

MSYS2 is an updated, modern version of MSYS, both of which are Cygwin (POSIX compatibility layer) forks with the aim of better interoperability with native Windows software.

The name is a contraction of Minimal SYStem 2, and aims to provide support to facilitate using the bash shell, Autotools, revision control systems and the like for building native Windows applications using MinGW-w64 toolchains.

MSYS2 (Minimal SYStem 2) 是一個MSYS的獨立改寫版本,主要用於 shell 命令列開發環境。同時它也是一個在Cygwin (POSIX 相容性層) 和 MinGW-w64(從”MinGW-生成”)基礎上產生的,追求更好的互操作性的 Windows 軟體。MSYS2 是MSYS的一個升級版,準確的說是集成了pacman和Mingw-w64的Cygwin升級版, 提供了bash shell等linux環境、版本控制軟體(git/hg)和MinGW-w64 工具鏈。與MSYS最大的區別是移植了 Arch Linux的軟體包管理系統 Pacman(其實是與Cygwin的區別)。

官方網站:http://www.msys2.org/

Cygwin、MinGW、MSys比較
特點 Cygwin MinGW/MSYS MSYS2
是否GNU 否 是 是
更多軟體支援? 支援絕大多數的 GNU 軟體 支援常用軟體,git、Vim等軟體需要獨立支援(詳細介紹見下方) 支援大多數 GNU 軟體
更類Linux? Cygwin在Windows中就好像Wine在Linux中 實現了Bash等主要的Linux程式 原生64/32bit支援
GCC編譯 內含MingGW32交叉編譯功能,既支援依賴cygwin1.dll的程式編譯,也支援獨立的Windows程式編譯;可以直接編譯Linux下的應用程式 支援獨立的Windows程式編譯 支援獨立的Windows程式編譯
中文支援 直接支援中文顯示和輸入法 需要配置才能支援中文顯示和輸入,刪除一箇中文字元需要刪除2次 支援中文顯示和輸入法,中文幫助系統和中文提示(部分軟體)
執行速度 慢 快 快
Unix下編譯通過的C程式碼在win32下編譯是不能通過的,Unix 和win32的API都是符合標準C,大多數函式呼叫在unix和win32下是相同的。但unix有自己一些獨特的API(如fork,spawn,signals,select,sockets等)如果程式碼中使用了這些API在win32下當然找不到對應的庫。

區別總結:

修改編譯器,讓window下的編譯器把諸如fork的呼叫翻譯成等價的形式,這就是mingw的做法。
修改庫,讓window提供一個類似unix提供的庫,他們對程式的介面如同unix一樣,而這些庫當然是由win32的API實現的,這就是cygwin的做法。
MingW和cygwin都不能讓Linux下的程式直接執行在Windows上,必需通過原始碼重新編譯。主要是它們對這些功能具體實現上的差異:

可執行檔案的格式,Window使用PE的格式,並且要求以.EXE為字尾名。Linux則使用Elf。
作業系統的 API也不一樣,如Windows用CreateProcess()建立程序,而Linux使用fork()。
cygwin/gcc完全可以和在linux下的gcc化做等號,這個可以從boost庫的劃分中可以看出來端倪,cygwin下的gcc和linux下的gcc完全使用的是相同的Toolsets。所以完全可以和linux一起同步更新gcc版本,而不用擔心問題,並且在cygwin/gcc做的東西(不用win32的)可以無縫的用在linux下,沒有任何問題。是在windows下開發linux程式的一個很好的選擇。但是在cygwin/gcc下編譯出來的程式,在windows執行必須依賴cygwin1.dll,並且速度有些慢,如果不想依賴這個東西的化,必須在gcc的編譯選項中加入-mno-cygwin。加入這個選項其實gcc編譯器就會自動的選擇在安裝cygwin/gcc時安上的mingw,這個mingw就是gcc的一個交叉編譯。

MinGW相比CygWin/gcc來講,更加貼近win32。因為它幾乎支援所有的Win32API。它所連線的程式,不需要任何第三方庫即可執行。CygWin/gcc,其實這是兩個東西。CygWin是一個讓Windows擁有Unix-like環境的軟體。而gcc就是安裝在CygWin上的編譯器。

二者生成的程式都是能在Windows上執行的EXE檔案,都是PE格式,用一個PE格式檢視工具檢查一下就能發現,Cygwin生成的程式依然有 fork()這樣的Linux系統呼叫,但目標庫是cygwin1。而MingW生成的程式,則全部使用從KERNEL32匯出的標準Windows系統 API。這樣看來用Mingw編譯的程式效能會高一點,而且也不用帶著那個接近兩兆的cygwin1.dll檔案。但Cygwin對Linux的模擬比較完整,甚至有一個Cygwin X的專案,可以直接用Cygwin跑X。另外Cygwin可以設定-mno-cygwin的flag,來使用Mingw編譯。而與Cygwin更有可比性的MSys上的工具也是通過Cygwin這種模擬的方式來提供。

Cygwin、MinGW、MSys如何選擇?
如果在windows開發linux程式,cygwin是很好的選擇。如果你開發的程式不介意有一個cygwin1.dll的話,也是可以選擇cygwin的。如果你是想開發windows下的程式,還要必須用gcc的話,mingw是很好的一個選擇。總起來說,在Windows系統下,還是用VC編譯比較合適,沒辦法的情況下才會選擇MinGW。