本文4300餘字,閱讀約11分鐘,本文知乎鏈接:Cygwin系列(一):Cygwin是什麼。

本文接上篇Cygwin前傳:從割據到互補。先一句話回答標題:Cygwin是一個可原生運行於Windows系統上的POSXI兼容環境

前言:從軟體角度理解系統

計算機世界裡存在各種各樣的操作系統,目前通用操作系統有主流的三大類:

  • UNIX,通用操作系統鼻祖,發展出特別多衍生系統;
  • Windows,微軟家根基,桌面市場霸主;
  • GNU/Linux,UNIX近親,有各種發行版如Ubuntu、CentOS等。

這些系統有各自的內核,出於系統穩定性考慮是不允許用戶程序直接操作內核,同時也將內核開發和應用軟體開發隔離開來,系統將必要的函數封裝成庫供應用軟體調用,約定的規範即為應用軟體介面(Application Program Interface,API)。

軟體系統層級關係簡要示意圖

API函數庫是連接用戶軟體和系統內核橋樑,或者是「協議」,操作系統廠商寫好函數庫說明書,應用軟體開發者不必關心其內部是如何實現的,用的時候對照著API手冊查詢就夠了;應用軟體也可以越過系統函數庫通過system call(系統調用)直接調用os內核函數,如圖中紅色虛線所示,當然這種方式並不被推薦。

如果各系統平台都能提供相同的系統函數庫,那麼開發者在這個系統函數庫基礎之上編寫軟體代碼,那麼就很容易將軟體移植到各個系統平台。然而,這只是個美好的願望,IEEE就是為了達成這樣的願望才牽頭制定POSIX標準。POSIX標準主要就是針對UNIX API而制訂,不管函數如何包裝、功能如何實現,但API按照標準約定來(比如函數變數等符號名稱、數據結構、參數類型與個數、基本工具命令名稱等),Linux完全兼容POSIX標準(部分函數符合POSIX,部分函數是Linux專有,即是POSIX的超集),微軟聲稱Windows部分兼容POSIX標準。

主流os內核通常是C語言寫成,系統函數庫通常以一個或多個鏈接庫文件的形式提供,其中最重要的是C標準庫,其他的鏈接庫往往調用C標準庫而實現,當然也可能直接調用系統內核函數,甚至混合。不同系統平台有多種主流的C標準庫共存:

  • BSD libc,由BSD系統發布;
  • GNU C Library (glibc),由GNU項目發布,可在Linux、多種UNIX系統上運行;
  • Microsoft C run-time library(MSVCRT.DLL),由微軟隨Windows發布,給Visual C++編輯器鏈接使用的;
  • Newlib,由Cygnus Solution公司開發,Cygwin環境中的libc.a正是此版本,目前廣泛用在嵌入式系統中;
  • dietlibc、μClibc等,功能經過適度裁剪的C標準庫,主要用在嵌入式系統。

Cygwin的組成

先輩David Wheeler大神曾經曰過:

「All problems in computer science can be solved by another level of indirection(計算機科學領域的任何問題都可以通過增加一個間接的中間層來解決)」。

David Wheeler ( 圖片來源:https://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist) )

就如同上圖,在硬體基礎之上逐步堆疊了系統內核、系統函數庫等中間層,在應用程序內部還可以繼續細分多個層次,這樣把最終用戶與硬體隔離開來,增強了抽象能力、屏蔽底層細節,也讓開發者分工,專註於各自層次的開發,同時降低了軟體遷移的難度。

Cygwin就是在Windows中增加了一個中間層——兼容POSIX的模擬層,並在此基礎上構建了大量Linux-like的軟體工具。再來解釋本文開頭的回答,如下圖,POSXI兼容環境包括以下兩部分:

  • cygwin1.dll,作為實現POSIX系統調用的模擬層,可原生運行在Windows中;
  • 在cygwin1.dll之上構建的大量函數庫、應用程序,如libc、zlib、bash、gcc、vim、awk、sed、git等等,與UNIX/Linux幾乎等同*。

*註:Cygwin的libc是Newlib,Linux的libc是GNU libc,UNIX有的是BSD libc。

Cygwin環境層次簡要示意圖

Cygwin API首先儘可能地遵從Single Unix Specification V3(2018版),這個標準內容同時也是POSIX.1和IEEE Std 1003.1的標準內容,由Open Group和IEEE共同制定,最新已更新到V4(2018版),其次再儘可能地遵從Linux最佳實踐。Cygwin API中還有些是Cygwin獨有的,在POSIX中並未涉及。

Cygwin將cygwin1.dll、函數庫、應用程序等文件按照UNIX/Linux的目錄樹架構進行組織存放,如/bin、/usr、/lib、/etc、/var、/home等等都存在於Cygwin安裝路徑下,用戶從終端登陸進Cygwin的shell後,就可以像在UNIX/Linux系統那樣使用相同的命令、工具,隨著開發工作推進,越來越多的GNU、UNIX、Linux軟體都移植到了Cygwin中。不僅如此,甚至像X Server、Gnome/KDE桌面環境等都移植到了Cygwin中,UNIX/Linux系統中的圖形界面軟體也能使用。

Cygwin的優點

  • 首先自然是近乎一致的UNIX/Linux體驗;
  • 完備且相對輕量,普通用戶不必安裝整個Linux系統或虛擬機,就可以獲得近乎一致的體驗,Cygwin的程序運行與Windows互不干擾,高效的命令行工具與Windows圖形界面各有所長、形成互補;
  • 開源免費,cygwin1.dll本身是按照GPLv3協議發布的,其他的應用程序有GPL、LGPL、X11等多種協議;
  • 安裝卸載方便,Cygwin提供了包管理工具,可按需安裝/卸載軟體包,一個能運行起來的最小Cygwin系統只需要幾十上百MB,而完全的Cygwin系統需要幾十GB;
  • 源碼級兼容性,GNU、UNIX、Linux軟體的源代碼幾乎不用修改就可以在Cygwin環境中編譯構建成功;
  • 與Windows互操作,Cygwin把Windows的磁碟掛載到/cygdrive下,如c盤就是/cygdrive/c、d盤就是/cygdrive/d,Cygwin中的應用程序可以讀寫Windows磁碟中的文件,Windows應用程序也可以讀寫Cygwin目錄中的文件(但要注意不要把文件搞亂了);Cygwin的shell中可以啟動Windows程序,Windows的cmd中也可以啟動Cygwin的程序,但由於字元編碼不同可能造成亂碼;
  • 多一套可用的API,對於Windows開發者,程序代碼既可以調用Win32 API,又可以調用Cygwin API,甚至混合。

Cygwin的不足

  • 效率相對低,由於是在Win32系統之上模擬實現POSIX兼容層,應用程序在底層就多了一個層級的函數調用,效率比UNIX/Linux系統上原生的應用程序肯定低,不過這也是在效率和兼容性之間選擇的一個平衡;
  • 未實現二進位文件級別的兼容,Cygwin系統上的應用程序編譯後仍然是Windows PE格式的可執行文件,UNIX/Linux系統上的二進位可執行文件在Cygwin上不能運行
  • 與Windows互操作不足,Windows原生程序並不能利用cygwin1.dll提供的與UNIX/Linux兼容的信號、pty設備等,除非改寫程序代碼重新編譯,但這樣新的程序就依賴於cygwin1.dll,就不是「Windows原生程序」了。

Cygwin常見應用場景

Cygwin可資利用的是已經移植的大量GNU、UNIX、Linux軟體和兼容POSIX的模擬層,其使用場合也就是針對這兩點。

高效命令行工具 (圖片來源於網路)

常見的應用場合包括但不限於:

(1)Shell命令行使用

Shell是UNIX/Linux的精華所在,骨灰級玩家可以做到不用滑鼠只敲命令完成所有工作,用戶最常用的大量命令在Cygwin下均可照常使用,在UNIX/Linux編寫的腳本也可以幾乎不加修改地在Cygwin下運行。例如安卓廚房本是在Linux-like環境下運行的腳本集合,用於修改安卓系統固件包,有了Cygwin,Windows用戶也可以拿來修改安卓系統固件包。高效的命令行工具與Windows圖形界面各有所長、形成互補。

(2)交叉編譯構建環境搭建

Cygwin環境中已移植好了gcc等開發工具,大量的交叉工具鏈(如arm-none-gnu-eabi-gcc、arm-none-gnu-eabi-binutils)也可以在Cygwin中製作,就算只有Windows原生版本的,Cygwin shell中也能調用,那麼利用Cygwin就能搭建起交叉編譯構建環境;另外,使用Cygwin API,編寫代碼以及後續編譯構建過程,與在UNIX/Linux中差異也很小了。

(3)程序移植

把符合POSIX標準的程序移植到Windows下,還有更多正在由個人、社區、商業公司、研究機構不斷貢獻的開源自由軟體,造福廣大Windows用戶,利用已有的GNU、UNIX、Linux軟體會使程序移植越來越容易。這一點不多說。

(4)兼用POSIX API和Win32 API開發

有的開發者可能對UNIX/Linux和Win32的API都熟悉,兩套API也各有其優點,在Cygwin下開發者自己可以任意選取、混合使用。

參考

  • zh.wikipedia.org/zh-cn/
  • zh.wikipedia.org/wiki/P
  • en.wikipedia.org/wiki/C
  • http://www.cygwin.com
  • en.wikipedia.org/wiki/L
  • en.wikipedia.org/wiki/C
  • unix.org/apis.html

更多閱讀

silaoA:Cygwin前傳:從割據到互補?

zhuanlan.zhihu.com
圖標

本文對你有幫助?請轉發分享,歡迎關注與留言交流

? 本文為原創文章,如需轉載請私信知乎賬號或聯繫公眾號:偽碼人(We_Coder)。


推薦閱讀:
相关文章