? 本文共3700餘字,閱讀約需12分鐘,本文知乎鏈接:Cygwin系列(三):盤點與Cygwin相似和相反的項目,本文同步發佈於微信公眾號。


本文接上篇Cygwin系列(二):初窺Cygwin背後,介紹與Cygwin相似和相反的幾個項目。

鑒於UNIX/Linux與Windows之間巨大的差異性,要想讓UNIX/Linux的應用程序運行在Windows上,或者相反地在UNIX/Linux系統上運行Windows程序,都是在想盡辦法彌補這個差異。再次祭出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相似的

  • POSIX subsystem、SFU、WSL

把UNIX/Linux程序移植到Windows上來擴大Windows的軟體生態圈,這事兒微軟也很早就考慮過。

早在1993年,比Cygwin項目還早2年的時候,Windows NT發布第一個版本時就搭載了Microsoft POSIX subsystem,與Win32子系統、OS/2子系統和安全子系統並為4大基本子系統。Microsoft POSIX subsystem支持POSIX.1標準,使用psxss.exe和psxdll.dll兩個文件作中間層,模擬POSIX環境,但是這個子系統不提供和用戶交互的部分,比如ls這樣的命令是沒有的,真是bug到沒朋友。

一個名叫「PTC Inc.」的計算機軟體公司搞出來MKS Toolkit,將很多UNIX/Linux程序移植到了Windows上,起先是為MS DOS準備的,後來支持了Windows NT,是商業軟體,到現在一直都有更新。微軟就是用MKS Toolkit在Windows NT上又造出來一個子系統——SFU(Windows Service For UNIX)取代了上述POSIX subsystem,於1999年發布了SFU 1.0、2000年發布了SFU 2.0,從3.0起SFU內部換成了Interix,這是微軟收編的一家公司的產品,微軟將其改名為Subsystem for UNIX-based Applications (SUA)。順帶吐槽下微軟,真是熱衷改名,素有「改名部」之稱,專門負責給各種產品重命名。最終SFU在2004年發布3.5版後就逐漸淡出視線了。反正由於諸多問題,SFU的用戶可能還沒Cygwin的多。

但是,微軟豈是等閑輩?2016年,微軟在Windows 10周年更新中,引入了新的子系統WSL(Windows Subsystem for Linux),剛出來的時候叫「Bash on Ubuntu on Windows」還是測試版,到Win10 1709版時變為正式版並更名為WSL。WSL使用的技術源自Astoria項目,旨在允許Windows 10 Mobile系統上運行安卓程序。與SFU、Cygwin不同,WSL直接在二進位層面兼容Linux系統,Linux上的程序、函數庫在WSL里都能運行,根本就省了「移植」的概念了。WSL迅速贏得眾多用戶青睞,特別是開發者,乃至被戲稱「最佳Linux發行版」。能玩得動這個黑科技的,只有微軟,因為Windows NT內核只有他才清楚。

微軟擁抱開源(圖片來源 https://cloudblogs.microsoft.com)
  • MinGW/MSYS

MinGW/MSYS經常拿來和Cygwin對比,很多人對此傻傻分不清,但其實二者有根本不同。

MinGW是「Minimalist GNU for Windows」的縮寫,即只是一個自由開源的最小開發工具集:mingw-gcc編譯工具鏈、mingw軟體包管理器(mingw-get),用於開發Windows原生程序。第一版的mingw-gcc是利用早期的Cygwin套件編譯而成,這個過程和Cygwin系列(二):初窺Cygwin背後中Cygwin DLL構建類似,隨後mingw-binutils、mingw-make等其他工具鏈也都逐漸移植成功,MinGW逐漸完全脫離了Cygwin。

mingw-gcc利用早期的Cygwin套件編譯而成

MinGW中的程序是不依賴POSIX兼容層的Windows原生程序,MinGW項目並不打算造一個POSIX兼容層,工具鏈工作的時候也是將程序直接與Windows系統自帶的函數庫(user32、kernel32、gdi32、MSVCRT等DLL)鏈接,還有編譯Windows資源文件的能力。MinGW項目中包含了w32api-header包、w32api-runtime包便於開發者利用Win32 API。

MinGW項目強調簡潔和性能,放棄POSIX兼容性,Cygwin重視POSIX兼容性而放棄性能。此外,二者在版權協議上也有差異。可以把MinGW視為MS Visual C++/Studio的開源替代品。

更顛覆認知的是,MinGW被移植到UNIX/Linux、Cygwin上,成為其中的一個「交叉」工具鏈,從而允許開發者在UNIX/Linux、Cygwin上交叉開發Windows原生程序。有的項目,如TDM-GCC、Windows版的Qt Creator也集成了MinGW。

MSYS和MinGW兩者有較大的獨立性。MSYS是「Minimal SYStem」的縮寫,是一個基於Bourne Shell的命令行系統,用於替代Windows中的cmd.exe,提供一個像Linux/UNIX的命令行環境。MSYS是基於Cygwin早期版本(v1.3)發展而來,包含了少部分Linux/UNIX程序,沒有編譯工具鏈,而且與Linux/UNIX原生程序或Cygwin程序相較丟失了很多功能特性,運行依賴於POSIX兼容層(msys-1.0.dll)。

如果沒有MSYS,在cmd中也可以正常運行MinGW程序,但MinGW和MSYS配合起來,就組成了一個類似Linux/UNIX的、包含常用程序和完整開發工具的輕量但完備的系統環境,MinGW的安裝路徑可以掛載到MSYS目錄樹中任何位置。

  • MinGW-w64/MSYS2

MinGW項目僅支持32位程序,對C89標準不完全支持、無法支持C99標準等缺陷給移植程序帶來很多問題,項目本身也發展緩慢。2005年,MinGW-w64項目基於MinGW創建,改善了MinGW的相關缺陷,並既支持32位程序又支持64位程序。MinGW-w64項目開發活躍,被很多Linux發行版採用為交叉工具鏈,而MinGW事實上已被拋棄。

MSYS項目僅支持32位程序,項目本身也發展緩慢。MSYS2基於最新版的Cygwin而創建,完全獨立於MSYS而重寫的版本(項目名字里的2就是區別於原MSYS),並既支持32位程序又支持64位程序,POSIX兼容層為msys-2.0.dll。MSYS2由msys2、mingw32、mingw64三個子系統組成,mingw32、mingw64對應於mingw-w64的32位和64位版本。還有一個特色就是,MSYS2移植了Arch Linux中的包管理器——pacman,清華大學還提供了MSYS2軟體鏡像源。

可以認為,MinGW-w64/MSYS2是MinGW/MSYS更先進的替代者。

  • UWIN、GnuWin32、UnxUtils

這幾個項目做著和Cygwin、MinGW/MSYS類似的工作,但比他們都差,逐漸淡出視線。

與Cygwin相反的

  • ReactOS

ReactOS並不是一個在UNIX/Linux系統運行Windows應用程序的「間接中間層」,而是一個全新的操作系統,而且它與前文MinGW-w64及下文要介紹的Wine、Longene有著密切聯繫,在此先介紹。

ReactOS(圖片來源於網路)

大約1995~1996年的時候,正值微軟的Windows 95系統大獲成功,一群開源愛好者、Windows發燒友認為Windows非常優秀,但唯一的缺點就是不開源!於是這群狂熱分子討論開發一版與Windows完全兼容的新系統,項目名叫「FreeWin95」,但難度較大,長時間並未產出什麼東西。

項目成員在1998年重新發起了一個項目,就是ReactOS,目標是從零實現一個開源版的Windows NT。為了保證ReactOS完全自由開源不受污染,項目組還專門花了幾年時間審查代碼庫,剔除逆向Windows而來的代碼。歷經20年ReactOS項目依舊活躍,2018年發布了0.4.10版,高度兼容Windows的硬體驅動、應用程序。

ReactOS的內核獨立於UNIX/Linux/Windows的任何API,完全是憑藉對Windows「連蒙帶猜」的理解從零開始寫,並基於這個內核實現Win32子系統,Win32子系統、子系統之上的函數庫和服務參考/使用了很多Wine項目的源代碼。

ReactOS為在其他系統(如UNIX/Linux)上構建Windows兼容環境提供了寶貴的技術路線和經驗,如接下來要說的Wine和Longene。

  • Wine

1993年,Linux發行版已初步擁有了一些用戶,微軟相繼發布了16位的Windows 3.0和3.1,其圖形界面操作簡單的特點取得巨大成功。Bob Amstadt發起了Wine項目,目的是在Linux系統上運行16位的Windows程序。隨著計算機軟體發展,Wine也一路跟隨兼容到32位、64位Windows程序,Wine所支持的運行系統從Linux擴大到BSD等POSIX兼容的系統上,甚至Android。

Wine項目(圖片來源於網路)

Wine是「Wine Is Not an Emulator」的遞歸簡寫,字面意思為Wine不是模擬器,它的工作原理是在運行時通過一個Wine Server進程將Windows系統調用「翻譯」成為POSIX兼容的等價調用,比如Windows的PushButton(按鈕)翻譯為X11協議的對應控制項。在這一點上,Wine和WSL很類似,只是作用方向相反。

Wine在Linux/UNIX系統的用戶空間重建了Windows系統的目錄結構,重新實現Windows系統函數庫、系統服務、IE、註冊表等重要組件。此外還提供了Winelib輔助Windows程序移植,其作用類似於Cygwin DLL,只是作用方向相反;源代碼從鏈接Windows DLL切換到鏈接Winelib重新編譯,生成(Linux系統上)ELF格式的二進位程序,獲得更高的效率。可以說,Wine是一個開源、自由的Windows兼容層,從二進位到源代碼都兼容,甚至Windows上的bug特徵都保持一致

由於Windows閉源,大量API、文件格式、協議等不對外提供說明文檔,外界無從得知Windows內部的邏輯、確切的API列表及功能,而且由於版權,Wine項目必須另外自行實現一套Windows系統的DLL庫,同時保持兼容性,相當於只憑藉模糊不清的照片重建一棟功能、外觀一致的房子。這項工作難度很大,Wine直到15年後的2008年才發布1.0穩定版,項目依舊活躍,2018年發布最新的4.0穩定版。儘管已經高度兼容,但由於Windows體系架構、設計概念與Linux/UNIX迥異,Wine不能完全模擬Windows環境,Windows原生設備驅動程序就不能運行。

總結起來,要讓Windows程序在Linux/UNIX系統上運行,通過Wine有2種辦法:

  1. 讓Wine啟動二進位程序文件,但如果程序調用了未被微軟公開的Windows API,Wine的系統函數庫無法提供,運行失敗;
  2. 有程序源代碼,修改配置文件讓鏈接庫指向Winelib,重新編譯生成(Linux系統上)ELF格式的二進位程序,同樣,Winelib不可能覆蓋100%的Windows API,可能編譯失敗;通過源代碼編譯,程序可以同時使用POSIX API和Windows API,這和Cygwin上一樣。

Wine官網上有個AppDB,列出了可以在Wine上運行較為良好的Windows程序。

Wine項目受到CodeWeavers公司贊助,後者售賣基於Wine的商業化產品——CrossOver,國內製作的Deepin Linux發行版,經商業合作內置CrossOver。

  • Longene

Wine項目的思路是在Linux用戶空間造兼容層,未觸及Linux內核,缺點是效率低,既然Linux內核與Windows迥然不同,何不幹脆進一步多改點內容,在Linux內核空間里實現Windows兼容層,把Window內核一併實現了?

2005年,大名鼎鼎的《Linux內核源代碼情景分析》《Windows內核情景分析:採用開源代碼ReactOS》的作者、浙江大學教授毛德操發起了Linux兼容內核(Linux Unified Kernel)自由軟體項目,也叫Longene,中文翻譯「龍井」,受浙大網新有限公司贊助。

毛德操教授(圖片來源於網路)

毛德操教授在網上發表了《Linux兼容內核》《漫談兼容內核》《漫談Wine》等系列文章,指出項目的開發路線。Longene主要做以下三方面工作:

  1. 以可運行的Wine為起點,以Linux內核函數為材料,在內核空間逐步替換Wine在用戶空間的功能組件(如Wine Server等),但運行Windows程序仍需要Longene版的Wine支持,剔除了Wine Server;
  2. 借鑒ReactOS、NDISWrapper項目,實現Windows設備驅動框架;
  3. 借鑒ReactOS、NDISWrappe項目和Linux內核,實現Windows內核API;

最終的目標是實現一個同時支持Linux和Windows的「兼容內核」。

2008年,一個中文Linux發行版MagicLinux 2.1採用了Longene 0.2.2內核。2013年至2014年初Longene發布了1.0-rc1和rc2版。但後來項目逐漸停滯,官網www.Longene.org也關閉了,相關代碼公開在GitHub上。

參考

  • en.wikipedia.org/wiki/M
  • en.wikipedia.org/wiki/M
  • en.wikipedia.org/wiki/W
  • https://www.mkssoftware.com
  • en.wikipedia.org/wiki/W
  • docs.microsoft.com/en-u
  • http://www.mingw.org
  • mingw-w64.org/doku.php
  • github.com/msys2/msys2/
  • https://reactos.org
  • https://www.winehq.org
  • github.com/tsuibin/long

更多閱讀

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

zhuanlan.zhihu.com
圖標
silaoA:Cygwin系列(一):Cygwin是什麼?

zhuanlan.zhihu.com
圖標
silaoA:Cygwin系列(二):初窺Cygwin背後?

zhuanlan.zhihu.com
圖標

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

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


推薦閱讀:
相关文章