操作系统那些事儿⑪:从 Cygwin、MinGW 到 WSL——Windows 为什么最终拥抱 Unix 世界
如果把操作系统的发展史比作《三国演义》,那么本文更像《三国演义》,而不是《三国志》。
本系列尝试用故事化的方式,讲述 Unix、Linux、BSD、GNU、Windows、macOS、Android 等操作系统背后的发展历程。
文中的人物、事件和技术演进都尽量参考公开资料,但为了让故事更容易理解,会适当简化一些历史细节,也会加入作者自己的理解。
它不是一篇学术论文,而是一段程序员视角的技术故事。
如果读完之后,你产生兴趣,愿意继续查阅官方资料,那这篇文章的目的就达到了。
引子:Windows 不是 Unix,但 Windows 里却住进了 Linux
上一篇,我们讲了 Windows。
一路从:
MS-DOS
↓
Windows 3.x
↓
Windows 95 / 98
讲到了另一条真正通往现代 Windows 的道路:
Windows NT
↓
Windows 2000
↓
Windows XP
↓
Windows 7
↓
Windows 10
↓
Windows 11
最后得出了一个很明确的结论:
Windows 不是 Unix。
今天 Windows 11 的核心血统仍然来自 Windows NT,而不是 Unix、BSD 或 Linux。
但是。
如果今天你打开一台程序员使用的 Windows 电脑。
事情可能会变得非常奇怪。
打开 Windows Terminal。
输入:
wsl
然后:
uname -a
你看到的居然是:
Linux
再输入:
ls
grep
sed
awk
ssh
gcc
python
全部能跑。
甚至:
sudo apt update
也没有问题。
Windows 还是 Windows。
Windows NT 还是 Windows NT。
可是:
Linux 居然真的住进 Windows 里了。
这件事如果放到 1990 年代来看。
多少有点魔幻。
因为在那个年代:
微软和 Unix。
Windows 和 Linux。
几乎像两个世界。
那么问题来了:
一个没有 Unix 血统、甚至长期建立自己独立生态的 Windows,为什么后来反而越来越主动地拥抱 Unix/Linux 世界?
而且:
WSL 并不是这个故事的开始。
在它之前。
程序员已经折腾了二十多年。
Cygwin。
MinGW。
MSYS。
MSYS2。
Interix。
Services for UNIX。
直到最后:
WSL。
Windows 和 Unix 的这场相遇。
其实远比想象中漫长。

第一章:两个世界,最早真的很不一样
今天很多程序员已经习惯:
Windows 上写代码。
Linux 上部署。
macOS 上开发。
GitHub 上协作。
Docker 里运行。
整个工具链已经混在了一起。
但在 1990 年代。
Windows 和 Unix 的差异非常明显。
Unix 程序员习惯:
ls
grep
sed
awk
make
gcc
sh
Windows 程序员则生活在:
C:\
以及:
Win32 API
Visual C++
cmd.exe
里面。
Unix 喜欢:
/home/user
/usr/bin
/etc
/dev
Windows 则是:
C:\Users
C:\Windows
C:\Program Files
Unix 创建进程。
很多程序天然假设:
fork()
存在。
Windows 则有自己的:
CreateProcess()
Unix 程序喜欢 Shell。
喜欢管道。
喜欢:
一个程序只做一件事,再把很多小工具组合起来。
Windows 世界则成长出了另一套完全不同的 API、工具链和软件文化。
结果一个问题越来越明显:
如果我在 Unix 上有大量现成软件,怎么把它拿到 Windows 上?
重新写一遍?
理论上当然可以。
可现实是:
一个大型 Unix 项目。
里面可能到处都是:
fork
signal
pipe
select
pthread
POSIX path
shell script
makefile
让程序员全部改成 Win32。
工程师大概只想回答:
要不还是算了。
于是有人开始想另外一条路。
第二章:Cygwin——既然 Windows 不是 Unix,那就在上面“造”一个 Unix
1995 年。
Cygnus Solutions 开始开发一个后来非常有名的项目:
Cygwin。
它的思路非常有意思。
Windows 没有 Unix 那些东西?
那我就在 Windows 和 Unix 程序之间:
加一个翻译层。
Cygwin 最核心的东西之一,是:
cygwin1.dll
这套运行时提供了大量 POSIX 功能,让很多原本为 Unix 编写的软件可以在 Windows 上重新编译后运行。Cygwin 官方至今仍把自己描述为“一大批 GNU/开源工具 + 提供大量 POSIX API 的 DLL”;它并不是直接运行 Linux 二进制程序,程序通常仍然需要针对 Cygwin 重新构建。
于是:
Unix 程序觉得自己看到的是:
fork()
signals
pipes
/dev
/usr
/home
Cygwin 在下面努力把这些东西:
翻译成 Windows 能理解的世界。
可以非常粗略地理解成:
Unix / POSIX 程序
↓
Cygwin API
↓
cygwin1.dll
↓
Windows

当然。
真实实现远比这复杂。
但从使用者角度:
Windows 里突然出现了:
bash
ls
cp
mv
grep
sed
awk
ssh
gcc
make
一个 Windows 用户打开 Cygwin。
甚至会产生一种错觉:
我是不是进了一台 Unix 机器?
Cygwin 官方甚至直接用了一个很形象的宣传语:
Get that Linux feeling - on Windows
不过严格来说。
它并不是 Linux。
甚至不能简单说它“模拟了一台 Linux”。
更准确一点:
Cygwin 是在 Windows 上构造了一套很像 Unix/POSIX 的运行环境。
Cygwin 项目的历史说明也很有意思:当初与其逐个重写 GNU 工具来适配 Win32,他们选择实现一个共享库,补上 fork、signals、select 等 Unix 程序依赖的能力。
这个选择非常重要。
因为它解决的是:
怎么让 Unix 软件比较容易地来到 Windows。
但新的问题也出现了。
第三章:Cygwin 很像 Unix,可它终究生活在 Windows 上
假设你在 Cygwin 里编译一个程序。
它可能依赖:
cygwin1.dll
也就是说:
这个程序并不是一个完全脱离 Cygwin 环境的普通 Windows 程序。
与此同时。
还有一些非常麻烦的问题。
例如:
路径。
Unix 喜欢:
/home/farseer/project
Windows 喜欢:
C:\Users\farseer\project
于是 Cygwin 还要在两种路径世界之间做映射。
例如 Windows 的:
C:\
在 Cygwin 世界里可以表现成类似:
/cygdrive/c/
Cygwin 官方文档也专门维护了一套 POSIX 视角的 Windows 文件系统映射,因为大量 Unix 软件天然假定整个文件系统从 / 开始,而不是从 C:、D: 开始。
再比如:
fork()
Unix 世界觉得:
这不是理所当然的吗?
Windows:
什么?
Windows 最接近的原生机制是 CreateProcess()。
但两个东西并不是一回事。
所以 Cygwin 必须想办法:
在一个本来不是 Unix 的操作系统上,尽量还原 Unix 程序期待的行为。
这是一件很厉害的事情。
但也注定意味着:
兼容层越强,背后的翻译工作就越复杂。
于是另一群程序员开始想:
等等。
我们的目标真的一定是:
让 Windows 假装自己是 Unix?
有没有另一种办法?
比如:
我只是想在 Windows 上用 GCC。
编译出来的东西。
最好还是一个正宗的:
hello.exe
双击就跑。
不需要整个 Cygwin 世界。
于是:
MinGW 登场了。
第四章:MinGW——别把 Windows 变成 Unix,我只想把 GNU 工具带过来
MinGW 的名字非常直白:
Minimalist GNU for Windows。
它和 Cygwin 的思路看起来很像。
都有:
GCC。
GNU 工具。
都让 Unix/Linux 程序员觉得熟悉。
但两者的目标并不一样。
Cygwin 更像:
在 Windows 上提供一个 POSIX/Unix-like 环境。
MinGW 则更像:
让 GCC 能编译真正的 Windows 程序。
也就是说:
源代码
↓
GCC / MinGW
↓
Windows API
↓
hello.exe
编译出来以后。
这个:
hello.exe
本质上仍然是:
Windows 程序。
它不是:
“跑在一个 Unix 模拟环境里的 Linux 程序。”
这点非常关键。
后来出现的 MinGW-w64,进一步扩展了原来的 MinGW,增加了 64 位支持以及更多 Windows API。MinGW-w64 官方现在对自己的定义就是:一组 Windows 头文件、导入库、运行库和工具,与 GCC 或 LLVM 组合后,可以构成完整的原生 Windows 应用开发环境;该项目在 2007 年从原 MinGW 路线分出,以支持 64 位和更新 API。
所以如果硬要用一句非常不严谨、但容易理解的话概括:
Cygwin 是:
把 Unix 环境搬到 Windows。
MinGW 是:
把 GNU 编译器搬到 Windows。

看起来只差一点点。
实际上:
目标完全不同。
第五章:可是只有 GCC 还不够
问题很快又来了。
程序员用 GCC 编译大型开源项目。
通常不仅仅需要:
gcc
还需要:
bash
make
sed
awk
grep
autoconf
automake
甚至各种:
./configure
make
make install
可是这些东西:
本来就是 Unix 世界长出来的。
于是 MinGW 旁边逐渐又需要一套:
Unix 风格的构建环境。
这就是:
MSYS。
可以粗略理解为:
MSYS
负责提供 Bash / Unix 构建工具
+
MinGW
负责生成原生 Windows 程序
这套组合思路非常聪明。
因为程序员可以:
用熟悉的 Unix 工具干活。
但最后生产出来的:
仍然是 Windows 软件。
后来:
MSYS 又进一步发展出今天更加常见的:
MSYS2。
第六章:MSYS2——终于有点像现代 Linux 开发环境了
如果你今天安装 MSYS2。
Linux 用户很容易产生一种亲切感。
打开 Shell。
然后:
pacman -Syu
等等。
pacman?
Arch Linux 用户可能突然精神起来了。
没错。
MSYS2 使用的包管理器就是:
Pacman。
你可以安装:
gcc
gdb
make
cmake
git
python
bash
vim
以及大量开发库。
整个体验越来越像:
一套真正可维护的软件发行环境。
MSYS2 官方把自己定义为 Windows 上的软件发行和构建平台:它基于现代 Cygwin 的 POSIX 兼容技术,又结合 MinGW-w64,主要目标不是制造一个完整 Unix,而是方便构建和运行原生 Windows 软件。
所以这里出现了一个非常漂亮的组合:
MSYS2
│
Unix 风格工具
│
Bash / Make / Pacman
│
├───────────┐
│ │
MSYS 环境 MinGW-w64
│ │
POSIX 兼容工具 原生 Windows 程序
如果你曾经在 Windows 上使用:
Git Bash
其实你已经和这条技术路线打过交道了。
今天的 Git for Windows 本身就建立在 MSYS2 基础之上;Git for Windows 官方甚至把自己概括成:
本质上是 MSYS2 的一个子集。
为什么装一个 Git。
结果里面有:
bash
ssh
grep
less
vim
现在就容易理解了。
因为 Git 本身:
就是从 Unix 世界长出来的软件。
要让它在 Windows 上舒服地生活。
背后其实塞进去了一小块:
Unix 风格的环境。
第七章:微软自己其实也早就尝试过 Unix
故事讲到这里。
很容易产生一个误会:
好像一直都是开源社区努力把 Unix 搬到 Windows。
微软完全不管。
其实并不是。
Windows NT 从很早的时候。
就考虑过:
POSIX 兼容。
后来微软甚至拥有一套非常有意思的技术:
Interix。
它最初来自 Softway Systems。
1999 年。
微软收购了这家公司相关资产,希望加强 Windows NT 与 Unix 环境之间的互操作。
后来 Interix 被整合进:
Windows Services for UNIX。
简称:
SFU。
它的目标之一。
也是让原来的 Unix 应用和脚本:
比较容易地迁移到 Windows。
再后来又出现:
Subsystem for UNIX-based Applications。
简称:
SUA。

你看这个名字:
是不是已经有那么一点:
Windows Subsystem for Linux
的味道了?
微软在 2000 年发布 Interix 2.2 时,就已经强调它可以让 Unix 应用和脚本在 Windows NT/2000 上运行,而不必彻底重写。
所以:
微软想让 Windows 和 Unix 共存,并不是 WSL 才突然冒出来的想法。
这件事折腾了很多年。
不过 SUA 最终没有成为普通开发者每天使用的主流工具。
到了 Windows Server 2012。
微软已经宣布:
SUA 被弃用。
当时微软官方给出的替代建议里。
居然直接出现:
Cygwin。
MinGW。
MinGW-w64。
这幅画面其实挺有意思。
微软自己造过 Unix 子系统。
最后告诉用户:
要不你试试 Cygwin?
但故事还没有结束。
因为接下来整个计算机世界发生了一次巨大变化。
第八章:真正改变局面的,不是桌面,而是服务器和云
如果只看个人电脑。
Windows 的地位一直非常强。
大量办公软件跑 Windows。
大量游戏跑 Windows。
各种商业软件跑 Windows。
所以微软完全可以觉得:
我为什么非得把 Linux 当回事?
可问题是:
计算机世界后来越来越不只是桌面。
互联网起来了。
Web 服务器起来了。
数据中心起来了。
云计算起来了。
然后:
Docker。
Kubernetes。
DevOps。
微服务。
云原生。
一个接一个来了。
而这些技术背后。
大量基础设施都围绕:
Linux。
程序员开始遇到一个越来越现实的问题。
我的办公电脑:
Windows
我的 IDE:
Windows
公司的 Office:
Windows
可是最终代码要跑的地方却是:
Linux Server
开发机:
Windows。
生产环境:
Linux。
于是中间经常夹着一大堆:
“在我电脑上明明是好的。”
Shell 不一样。
路径不一样。
权限不一样。
换行符不一样。
脚本不一样。
依赖不一样。
运行时行为也可能不一样。
以前解决办法是什么?
装虚拟机。
比如:
Windows
↓
VMware / VirtualBox
↓
Ubuntu
或者:
双系统。
Windows 一套。
Linux 一套。
想开发 Linux 软件:
重启电脑。
久而久之。
一个问题摆在微软面前:
如果越来越多开发者必须使用 Linux,那么 Windows 还怎么继续成为他们最喜欢的开发桌面?
这一次。
问题的性质已经变了。
以前微软想的是:
怎样把 Unix 软件迁到 Windows。
现在则变成:
怎样让 Windows 用户直接拥有 Linux 开发环境。

这两个问题:
看起来很像。
实际上完全不同。
第九章:2016——微软突然说:Windows 可以跑 Bash
2016 年。
微软 Build 大会。
一个消息出来。
很多程序员第一反应可能都是:
什么?
微软宣布:
Bash on Ubuntu on Windows。
也就是后来大家熟悉的:
WSL。
Windows Subsystem for Linux。
微软当时宣布,Windows 10 将可以直接运行 Bash 和 GNU/Linux 命令行工具,第一批公开预览随后进入 Windows 10 Insider Build。
这个变化到底有多大?
以前 Cygwin 的思路是:
Unix 程序
↓
重新编译
↓
Cygwin POSIX Layer
↓
Windows
而 WSL 1 做了一件更激进的事情:
运行未经修改的 Linux ELF 二进制程序。
比如:
/bin/bash
/bin/ls
/usr/bin/grep
这些不再是:
“给 Windows 重新编译出来的类似版本。”
而是真正面向 Linux 的二进制程序。
这一步:
非常关键。
第十章:WSL 1——Windows 开始“听懂”Linux 系统调用
但注意。
最早的 WSL:
没有 Linux Kernel。
这点非常容易搞混。
WSL 1 的思路。
某种程度上反而很像一位更加深入操作系统内部的“翻译官”。
Linux 程序说:
我要创建进程。
Linux 程序说:
我要打开文件。
Linux 程序说:
我要申请内存。
Linux 程序不断发出:
Linux system call。
WSL 1 则尝试把这些请求:
转换成 Windows 能完成的操作。
可以非常粗略地画成:
Linux ELF 程序
↓
Linux System Call
↓
WSL 1
↓
Windows NT Kernel

所以:
WSL 1 能运行真正的 Linux 用户态程序。
但下面:
依然没有真正的 Linux Kernel。
微软自己的 WSL 文档今天也仍然明确说明:WSL 1 使用的是由 WSL 团队实现的转换层,而不是完整 Linux 内核。
这个方案非常漂亮。
因为没有传统虚拟机。
启动快。
Windows 和 Linux 文件互访也非常直接。
但它有一个天然问题:
Linux System Call:
太多了。
Linux Kernel:
还在继续发展。
各种程序越来越复杂。
Docker 之类的软件又高度依赖 Linux 内核行为。
结果微软逐渐发现:
想永远追着 Linux Kernel,把所有行为一条一条翻译出来,实在太累了。
怎么办?
答案非常有程序员风格。
既然模拟 Linux Kernel 这么麻烦。
那么:
为什么不干脆真的放一个 Linux Kernel 进去?
第十一章:WSL 2——别翻译了,Windows 里面直接跑 Linux Kernel
2019 年。
微软公布:
WSL 2。
2020 年。
WSL 2 随 Windows 10 May 2020 Update 正式进入更广泛用户手中。微软当时明确说明,WSL 2 使用由微软构建和提供的真实 Linux Kernel,并运行在轻量级虚拟机环境里。
于是架构彻底变了。
WSL 1 大概是:
Linux 程序
↓
Linux System Call
↓
翻译
↓
Windows NT Kernel
WSL 2 则变成:
Linux 程序
↓
Linux System Call
↓
Linux Kernel
↓
轻量虚拟化
↓
Windows
看见区别了吗?

这一次:
中间真的有 Linux Kernel。
而且这个 Kernel:
由微软基于上游 Linux Kernel 构建并针对 WSL 优化。
官方文档今天也明确说明,WSL 2 使用轻量级 Utility VM 运行完整 Linux Kernel,因此获得了完整系统调用兼容性。
于是很多过去 WSL 1 很难解决的问题:
突然容易多了。
为什么?
因为碰到 Linux Kernel 行为时。
已经不需要微软再问:
Windows 应该怎样模拟这个东西?
Linux Kernel 自己回答:
我来。
这可能是整个故事里最有意思的一次转折。
早年的思路是:
让 Unix 软件适应 Windows。
后来变成:
让 Windows 模拟 Linux。
最后:
算了,把 Linux 本人请进来。

第十二章:所以 Cygwin、MinGW、WSL 到底有什么区别?
讲到这里。
这几个经常一起出现的名字。
终于可以放到一张图里。

Cygwin
核心问题:
怎样在 Windows 上提供 Unix/POSIX 环境?
大概是:
Unix 源代码
↓
重新编译
↓
Cygwin
↓
Windows
重点:
兼容 Unix/POSIX。
MinGW / MinGW-w64
核心问题:
怎样在 Windows 上使用 GCC 等 GNU 工具编译原生 Windows 程序?
大概是:
源代码
↓
GCC
↓
MinGW-w64
↓
Windows API
↓
.exe
重点:
生成原生 Windows 软件。
MSYS2
核心问题:
怎样给 Windows 原生开发提供一套舒服的 Unix 风格构建环境?
所以它把:
Bash。
Pacman。
Make。
Autotools。
MinGW-w64。
各种开源工具。
组织到了一起。
重点:
Unix 风格开发环境 + 原生 Windows 构建。
WSL 1
核心问题:
怎样直接运行 Linux 二进制程序,又不用真的跑 Linux Kernel?
所以:
翻译 Linux System Call。
WSL 2
核心问题:
既然大家真正需要的就是 Linux。
那么:
直接运行 Linux Kernel。
微软官方目前也给出了很直接的定位:如果只是需要 Linux CLI 工具,或者开发的软件最终就是部署到 Linux 服务器上,WSL 通常更加合适;而 MSYS2 的强项仍然是构建原生 Windows 程序。
所以这些工具:
其实并不是简单的一代淘汰一代。
它们解决的是:
不同的问题。
第十三章:WSL 出现以后,Cygwin 和 MinGW 就没用了吗?
并没有。
这是另一个很容易产生的误解。
今天如果你的目标是:
开发一个最终运行在 Ubuntu Server 上的程序。
那么:
WSL 2 通常非常舒服。
你可以直接:
apt install gcc
直接:
cmake
make
python
node
go
docker
你的环境本身:
就是 Linux。
但如果你的目标是:
编译真正的 Windows
.exe。
MinGW-w64 依然非常有价值。
MSYS2 也依然非常活跃。
如果你有大量老的 Unix/POSIX 软件。
需要它们和 Windows 环境深度结合。
Cygwin 同样没有消失。
今天 Git for Windows。
背后仍然能看到:
MSYS2。
Cygwin。
MinGW。
这些技术留下来的痕迹。Git for Windows 的 Bash 和部分 POSIX 工具依赖 MSYS2 的兼容层,而 Git 本身则可以作为 MinGW 原生程序构建。
所以:
WSL 并没有把前面的历史全部推倒。
它只是把:
“我想要一个真正 Linux 环境”
这个问题:
解决得更加彻底了。
第十四章:微软为什么变了?
现在终于可以回到文章标题:
Windows 为什么最终拥抱 Unix 世界?
很多人喜欢把这个故事理解成:
早年的微软反对 Linux。
后来微软突然“想通了”。
其实真实原因可能没那么浪漫。
更现实。
也更商业。
第一:开发者变了
以前 Windows 软件开发者的目标通常是:
Windows
现在一个 Windows 程序员可能写的是:
Python。
Node.js。
Go。
Rust。
Java。
Cloud Native。
后端服务。
AI 应用。
最终运行环境却可能是:
Linux
如果 Windows 不能很好服务这些程序员。
他们最简单的选择是什么?
直接用 Linux 或 macOS。
对于微软来说:
这显然不是一个理想结果。
于是 Windows 必须回答:
怎么让一个以 Linux 为目标平台的程序员,仍然愿意使用 Windows 开发?
WSL:
就是其中一个答案。
第二:服务器世界变了
Windows 最强大的传统领地之一:
是 PC。
但云计算时代。
服务器、容器、云原生基础设施越来越重要。
而 Linux 已经成为这个世界里极其重要的平台。
Docker。
Kubernetes。
大量云原生软件。
开源数据库。
Web 服务。
AI 基础设施。
大量默认文档第一句都是:
sudo apt install ...
微软当然可以坚持:
你们全部改成 Windows。
问题是:
用户凭什么听你的?
更现实的做法是:
用户喜欢 Linux,那 Azure 就跑 Linux。
开发者需要 Linux,那 Windows 就提供 Linux。
这是一种非常典型的平台思维。
第三:开源已经从“对手”变成基础设施
1990 年代。
商业软件和自由软件之间的阵营感非常强。
但后来:
Git。
Linux。
Python。
Node.js。
Kubernetes。
PostgreSQL。
OpenSSH。
LLVM。
各种开源项目。
逐渐变成整个软件工业共同使用的基础设施。
企业可以不用 Linux Desktop。
但它很难做到:
完全不接触 Linux 和开源生态。
微软自己也越来越深地进入开源世界。
.NET 跨平台。
PowerShell 跨平台。
Windows 自带 OpenSSH。
VS Code 跨平台。
Azure 支持 Linux。
WSL 运行 Linux。
到了今天。
微软自己的 WSL 官方介绍页面甚至直接有一节:
Microsoft loves Linux。
如果把时间拨回几十年。
这个画面确实很难想象。
第十五章:Windows 没有变成 Unix,它只是学会了和 Unix 一起生活
这里必须再强调一次。
WSL 出现以后:
Windows 仍然不是 Unix。
Windows 11 的核心仍然是:
Windows NT。
Windows 程序依然大量运行在:
Win32
体系上。
Windows 仍然有:
注册表。
盘符。
NTFS。
Windows Security Model。
Windows Driver Model。
Win32 API。
它没有因为:
wsl
就突然变成:
Unix。
这点和上一篇讲 Windows 血统时的结论并不矛盾。上一篇最后其实已经留下了这个伏笔:Windows 仍然不是 Unix,但它开始把 Linux、OpenSSH、跨平台开发工具主动请进自己的生态。
真正改变的是另一件事情:
Windows 不再要求整个世界都必须按照 Windows 的方式工作。
早年的目标可能更像:
Unix 软件
↓
移植
↓
Windows 软件
后来则越来越变成:
Windows 软件 ──────────┐
│
Linux 软件 ────────────┤
│
Cloud / Container ─────┤
↓
同一台开发电脑
这其实是一种很重要的平台思维变化。
以前:
Windows 想成为目的地。
现在:
Windows 更愿意成为平台。
你最后的软件跑在 Windows?
可以。
跑 Linux?
也可以。
跑容器?
可以。
部署 Azure?
可以。
本地一边运行 Visual Studio。
另一边:
ssh
gcc
docker
python
也可以。
只要:
你还愿意坐在 Windows 前面开发。

第十六章:从“模拟 Unix”到“真的运行 Linux”
现在回头看这三十年的故事。
会发现一条非常清楚的路线。
最开始:
Windows 和 Unix 是两个世界。
于是 Cygwin 出现:
让 Windows 看起来更像 Unix。
然后 MinGW 出现:
让 GNU 工具能够生产 Windows 软件。
MSYS / MSYS2 又进一步解决:
怎样用 Unix 风格的工具舒服地开发 Windows 软件。
微软自己也尝试过:
Interix。
Services for UNIX。
SUA。
后来云计算和 Linux 彻底改变开发环境。
于是 WSL 1 来了:
直接运行 Linux 二进制程序,但自己翻译 System Call。
翻着翻着。
发现 Linux Kernel 越来越复杂。
于是到了 WSL 2:
不翻译了。
直接运行 Linux Kernel。
整个过程可以极度简化成:
1990s
Windows 与 Unix 是两个世界
↓
Cygwin
在 Windows 上构造 POSIX 环境
↓
MinGW
用 GNU 工具构建原生 Windows 软件
↓
MSYS / MSYS2
Unix 工具链 + Windows 原生开发
↓
Interix / SFU / SUA
微软自己的 Unix 兼容尝试
↓
2016
WSL 1
直接运行 Linux ELF
System Call 翻译
↓
2019 / 2020
WSL 2
真正的 Linux Kernel
↓
今天
Windows + Linux
成为同一套开发工作站
如果把这几十年压缩成一句话:

可能就是:
最开始,人们想办法让 Unix 软件适应 Windows。
最后,Windows 决定直接给 Unix/Linux 留一个位置。
写在最后:那个没有 Unix 血统的巨人,最终把 Unix 请进了家里
上一篇写 Windows 时。
我把 Windows 比作:
Unix 家族大树旁边,另一棵独立成长起来的巨树。
它没有 Unix 血统。
它有自己的:
Windows NT。
Win32。
注册表。
驱动体系。
软件生态。
而且:
这棵树长得非常成功。
它几乎统治了 PC 世界几十年。
但计算机世界并没有因此停止变化。
互联网来了。
Linux Server 来了。
开源来了。
云计算来了。
Docker 来了。
Kubernetes 来了。
DevOps 来了。
AI 基础设施来了。
越来越多软件最终运行的土地:
已经不一定是 Windows。
于是微软慢慢发现:
真正重要的问题已经不是:
Windows 能不能消灭 Unix?
而是:
Unix/Linux 世界如此庞大以后,Windows 怎样继续成为程序员愿意使用的平台?
于是:
Cygwin 尝试搭了一座桥。
MinGW 又搭了一座。
MSYS2 把桥修得更舒服。
微软自己也折腾过 Interix 和 SUA。
最后:
WSL 出现。
到了 WSL 2:
微软甚至干脆在 Windows 里面:
真的运行了一个 Linux Kernel。
这可能是整个故事最有戏剧性的地方。
Windows 并没有输掉自己的血统。
它还是 Windows NT。
Linux 也没有变成 Windows。
它还是 Linux。
两个曾经隔得很远的世界。
最终没有谁吞掉谁。
而是:
决定住在了一台电脑里。
今天一个开发者完全可以:
左边打开:
Visual Studio
右边打开:
Ubuntu
上面跑:
Windows 11
下面藏着:
Linux Kernel
然后:
git clone
cmake
make
docker
kubectl
ssh
再把程序部署到远处的一台 Linux Server。
此时:
Windows 是 Windows。
Linux 是 Linux。
但程序员:
已经不太在乎这条边界了。
所以如果上一篇 Windows 的故事告诉我们:
Windows 没有 Unix 血统,也可以成长为一个庞大的操作系统帝国。
那么这一篇留下的故事可能是:
真正成熟的平台,不一定要把所有人变成自己。
有时候。
更强大的选择反而是:
让不同的世界,都能在自己这里生存。
从 Cygwin。
到 MinGW。
从 MSYS2。
到 WSL。
Windows 花了几十年。
终于从:
“怎样让 Unix 软件变成 Windows 软件?”
走到了:
“既然你需要 Linux,那 Linux 就住进来吧。”
而这大概也是 Windows 历史上最有意思的一次转身:
那个没有 Unix 血统的巨人,最终没有变成 Unix。
它只是张开门,把 Unix 世界请进了自己的家里。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)