可在Windows下运行的Linux环境
2023-08-29 10:43:18 阿炯

1、Cygwin

Cygwin/gcc和下文的MinGW都是gcc在windows下的编译环境,在实际工作中如何选择这两种编译器。

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作为gcc在windows上的一个实现,由于不像cygwin的gcc在一个模拟linux上运行,同时相当一部分linux的工具不能够使用,不过现在已经有Msys这个模拟unix的shell,可以解决很多的问题。当然其还有一个轻量级的替代软件Gow


2、MSYS

MSYS:Unix-like command line utilities,包括基本的bash, make, gawk and grep等。通常也可以认为是小型的UNIX on Windows,提供在windows上模拟Unix环境来使用MinGW。

MSYS在windows下模拟了一个类unix的终端,它只提供了MinGW的用户载入环境,在MSYS模拟的unix环境下使用MinGW,就像在Unix使用gcc一样。

3、MinGW

MinGW 即 Minimalist GNU For Windows(GCC compiler suite)。它是一些头文件和端口库的集合,该集合允许人们在没有第三方动态链接库的情况下使用 GCC(GNU Compiler C)产生 Windows32 程序,原来的项目似乎已经停止更新了。不过新的项目名称为Mingw-w64,很明显支持了64位环境。

MinGW是一个可自由使用和自由发布的Windows特定头文件和使用GNU工具集导入库的集合,在基本层,MinGW 是一组包含文件和端口库,其功能是允许控制台模式的程序使用微软的标准C运行时间库(MSVCRT.DLL),该库在所有的 NT OS 上有效,在所有的 Windows 95 发行版以上的 Windows OS 有效,使用基本运行时,可以使用 GCC 写控制台模式的符合美国标准化组织(ANSI)程序,可以使用微软提供的 C 运行时扩展。该功能是 Windows32 API 不具备的。下一个组成部分是 w32api 包,它是一组可以使用 Windows32 API 的包含文件和端口库。与基本运行时相结合,就可以有充分的权利既使用 CRT(C RunTime)又使用 Windows32 API 功能。

实际上 MinGW 并不仅是一个 C/C++ 编译器,而是一套 GNU 工具集合。除开 GCC (GNU 编译器集合) 以外,MinGW 还包含有一些其他的 GNU 程序开发工具 (比如 gawk bison 等等)。开发 MinGW 是为了那些不喜欢工作在 Linux(FreeBSD) 操作系统而留在 Windows 的人提供一套符合 GNU 的 GNU 工作环境。所以使用 MinGW 就可以像在 Linux 下一样使用 GNU 程序开发工具。

GCC 就是 MinGW 的核心所在,它是一套支持众多计算机程序语言的编译系统,而且在语言标准的实现上是最接近于标准的。并且其几乎可以移植到目前所有可用的计算机平台。

GCC 本身不像VC那样拥有IDE界面(但是有很多的开源的IDE支持使用MinGW,例如codeblocks,eclipse等)。源代码编辑你可以选用任何你喜欢的文本编辑器(据说微软的开发人员包括 VC 的开发都不用 VC 所带的 IDE 编辑器,而是选用 GNU 的 VIM 编辑器)。然后使用 make 等工具来进行软件项目的编译、链接、打包乃至发布。而像 cvs(svn) 源代码版本控制工具可以让世界上任何一个角落的人都可以参与到软件项目中来。

关于 MFC,微软基础库类,这个随 VC++ 携带的一个源代码公开的开发包,和其他 Windows 程序开发包是一样的。如果有 VC++ 的授权,完全可以使用 MFC 的源代码,也就是使用 GCC 来编译 MFC 程序是完全可以的。当然 GNU 下也有很多 Windows 程序开发包,甚至有一些是支持跨平台使用的。不仅仅可以直接把源代码编译为 Windows 程序,也可以不经修改编译为其他操作系统的图形程序。

它们之间的区间可做如下简述:
MinGW 只包括gcc和g++,不支持离线安装。

MinGW Distro是打包好的MinGW,可离线安装。

Cygwin 不仅提供了gcc和g++,而且实现了大量的POSIX API,不支持离线安装。

Babun是基于Cygwin的,预置git和oh-my-zsh,支持离线安装。

MSYS2是对Windows的软件发行版和构建平台,可离线安装。

VS-MSVC则是微软官方提供的nmake等工具。ReactOSWine 也是可以选择的。


4、Windows Subsystem for Linux(WSL)

适用于Linux的Windows子系统(英语:Windows Subsystem for Linux,简称WSL)是一个为在Windows 10和Windows Server 2019以上能够原生运行Linux二进制可执行文件(ELF格式)的兼容层。它提供了一个由微软开发的Linux兼容的内核接口(不包含Linux内核代码),然后可以在其上运行GNU用户空间,例如Ubuntu,openSUSE,SUSE Linux Enterprise Server,Debian 和Kali Linux。这样的用户空间可能包含Bash Shell和命令语言,使用本机GNU/Linux命令行工具(sed,awk等),编程语言解释器(Perl,Ruby,Python等),甚至是图形应用程序(使用主机端的X窗口系统)。WSL在版本1607之后的64位版本的Windows 10与Windows 11中可用,它也可在Windows Server 2019中使用。

虽然微软以前的项目和第三方Cygwin专注于基于POSIX标准创建自己独特的类Unix环境,但WSL的目标是原生Linux兼容性。WSL不是将非原生功能包装到Win32系统调用中,而是利用NT内核执行程序将Linux程序作为特殊的、隔离的最小进程(称为“pico-processes”)作为专用系统连接到内核模式“pico-providers”。调用和异常处理程序不同于vanilla NT进程。微软将WSL视为“主要面向开发人员的工具 — 尤其是Web开发人员以及在开源项目上工作或使用开源项目的人员”。WSL使用的资源少于完全虚拟化的机器,这是在Windows环境中运行Linux软件的最直接方式,同时还允许用户在同一组文件上使用Windows应用程序和Linux工具。

2020年9月,WSL 2开始向Windows 10 Version 1903/1909和Windows 10 May 2020(20H1/Version 2004)的用户推送。WSL 2支持GUI应用。

WSL 1

LXSS Manager Service是负责与子系统交互的服务(通过驱动程序lxss.sys和lxcore.sys),以及Bash.exe(不要与Linux发行版提供的Shell混淆)的方式启动Linux进程,以及在执行期间处理Linux系统调用和二进制锁。特定用户调用的所有Linux进程都进入“Linux实例”(通常第一个调用的进程是init)。关闭所有应用程序后,将关闭实例。

WSL 1的设计没有硬件模拟/虚拟化(与coLinux等其他项目不同),WSL直接使用主机文件系统(通过VolFS和DrvFS)和硬件的某些部分,例如网络(Web服务器,用于例如,可以通过主机上配置的相同接口和IP地址进行访问,并且对使用需要管理权限的端口或已经被其他应用程序占用的端口共享相同的限制),这保证了互操作性。即使从shell运行sudo,某些位置(例如系统文件夹)和配置的访问/修改也受到限制。必须启动具有提升权限的实例才能获得“真正的sudo”并允许此类访问。

WSL 1 无法运行所有 Linux 软件(如32位二进制文件)或需要在WSL中未实现的特定Linux内核服务的软件。由于WSL中没有“真正的”Linux内核,因此无法运行内核模块(如设备驱动程序),但是WSL 2 使用即时虚拟化的Linux内核实例。可以通过在Windows(主机)环境(例如VcXsrv或Xming)中安装X窗口系统来运行一些图形(GUI)应用程序(例如Mozilla Firefox),但是这种模式还存在一定的问题,例如缺乏音频支持或硬件加速(导致图形性能不佳)。尽管已经在计划中,但是目前还没有实现对OpenCL和CUDA的支持。

也就是说,微软明确指出WSL面向应用程序的开发者,而不是面向桌面环境或生产服务器。微软建议使用虚拟机(Hyper-V或Kubernetes)和Azure来实现这些目的。在性能测试中,WSL 1通常接近原生Linux(如Ubuntu、Debian、Intel Clear Linux或其他Linux发行版)。在某些测试中I/O是WSL的瓶颈。

WSL 2

WSL 2 引入了体系结构中的更改。微软选择了通过高度优化的Hyper-V功能子集进行虚拟化,以便运内联核和发行版(基于内核),承诺性能相当于WSL 1,为了 向下兼容,开发人员不需要更改其已发布发行版中的任何内容。 WSL 2 设置可以通过 WSL 全局设置配置进行调整,该配置位在用户配置文件文件夹中名为.wslconfig的INI文件。

发行版本安装在ext4格式的虚拟磁盘中,主机文件系统可以通过9P协议透明地访问,类似于QEMU等其他虚拟机技术。对于用户,微软承诺读写性能是WSL 1的20倍。Windows提供一个IFS网络重定向程序,使用UNC路径首码\\wsl$来访问Linux客户档。WSL 2 需要Windows 11或Windows 10版本 2004 和更新版本(组建 19041 和更新版本)。

微软声称重新设计的WSL 2后端在某些操作上的速度比WSL 1提高了20倍,2020 年 6 月,使用 AMD Threadripper 3970x 进行了 173 次测试的基准测试显示,WSL 2(20H2) 性能良好,性能仅为本机 Ubuntu 20.04.0 LTS 的 87%。这是对WSL 1的改进,在此比较中,WSL 1的性能仅为本机Ubuntu的70%。WSL 2改善了I/O性能,提供了接近本地的水准。在2020年5月,用Intel i9 10900K进行的69项测试比较显示了几乎相同的相对性能。在2020年12月,用AMD Ryzen 5900X进行的43项测试的基准显示了WSL 2(20H2)的良好性能,其性能为原生20.04.1 LTS的93%。这比WSL 1有进步,后者在这种比较中只有73%。


小结

MinGW是windows版本的gcc集合,不需要依赖中间层。

MSYS是小型的linux的环境的模拟,可以与MinGW结合来模拟linux环境下使用MinGW的gcc。

Cygwin是功能强大的linux环境,由于有cygwin1.dll实现了底层的windows api到linux api的转化。所以在Cygwin里开发就相当于在linux上开发,对于开发人员来说就相当于调用linux类型的api,所以这样开发的程序也可以直接移植到linux上。但是如果这样的程序要在windows上执行的话,运行时必须要cygwin1.dll支持。

根据以上的分析,如果在windows开发linux跨平台的程序,linux模拟器Cygwin以及所包含的gcc是很好的选择,但是开发的程序必须依赖一个cygwin1.dll。如果你只是想在windows下使用gcc编译器也不想依赖其他的dll,mingw是很好的一个选择。在无法完全转换到Linux系统的前提下,可一直在 Cygwin 下工作,使用全套的Linux移植工具,学习Bash编程;Cygwin由于工作在模拟模式下,速度较慢,相比而言,MinGW 就要快不少。


特点CygwinMinGW/MSYSMSYS2
是否GNU
更多软件支持?支持绝大多数的 GNU 软件支持常用软件,git、Vim等软件需要独立支持支持大多数 GNU 软件
更类Linux?Cygwin在Windows中就好像Wine在Linux中实现了Bash等主要的Linux程序原生64/32bit支持
GCC编译内含MingGW32交叉编译功能,既支持依赖cygwin1.dll的程序编译,也支持独立的Windows程序编译;可以直接编译Linux下的应用程序支持独立的Windows程序编译支持独立的Windows程序编译
中文支持直接支持中文显示和输入法需要配置才能支持中文显示和输入,删除一个中文字符需要删除2次支持中文显示和输入法,中文帮助系统和中文提示(部分软件)
运行速度

再来较为详细的小结

1).Cygwin和MSYS2——作为项目有着显著不同的目标。

Cygwin试图将POSIX兼容的环境引入Windows,以便在unix上运行的大多数软件都可以在Cygwin上构建和运行,而无需进行任何重大修改。Cygwin提供了大量包含此类软件的软件包,以及用于其开发的库。MSYS2试图为构建本机Windows软件提供一个环境。

MSYS2提供了大量包含此类软件的软件包,以及用于其开发的库。由于大部分软件使用与unix世界紧密耦合的GNU构建工具,因此该环境也与POSIX兼容,并且实际上基于Cygwin。MSYS2提供了运行autotools和其他构建系统所需的最小要求,这些系统从不同的存储库从Internet获取软件源,配置并构建它们。shell和core工具的存在主要是为了允许移植Unix程序在Windows上本机运行(即不需要POSIX仿真层)。MSYS2并不试图复制Cygwin的工作,因此提供的POSIX仿真软件数量非常少。

2).MSYS2使用Pacman(来自Arch Linux)来管理其软件包,并附带三个不同的软件包存储库:
msys2:包含依赖msys2的软件
mingw64:包含64位本机Windows软件(使用mingw-w64 x86_64工具链编译)
mingw32:包含32位本机Windows软件(使用mingw-w64 i686工具链编译)

Cygwin只附带依赖Cygwin的软件。它使用自己的包管理系统,通常称为setup.exe。

3).Cygwin提供了一个名为cygwin1.dll,在必要时提供POSIX兼容层。该库的MSYS2变体称为msys-2.0.dll,包括以下更改以支持使用本机Windows程序:
(1).动态地将命令行参数和环境变量的路径自动分配到Windows窗体。(这可以有选择地关闭。)
(2).能够使用环境变量(MSSYSTEM,值为MSYS2、MINGW32和MINGW64)更改报告的操作系统。这使得mingw-w64软件可以在本机构建模式下构建(与交叉编译模式相反)。
(3).通过删除尾随“\r”字符,将本机Windown应用程序的输出从Windows行结尾转换为POSIX行结尾,以便如bb=$(gcc--打印搜索目录)按预期工作。
(4).用复制替换符号链接,这样Windows程序就不会在这些文件上出错。MSYS2还支持创建本机NTFS符号链接,但在其他方面受到限制。
(5).删除自动装载的/cygdrive前缀。这是为了保持与支持MSYS的软件的兼容性,该软件假设/c/等同于c:/,并且节省了一点输入。
(6).在默认挂载上切换到noacl。这可以防止来自MSYS2的任何权限损坏。

MSYS2版本可能在Cygwin版本之前或之后。

4).其他显著差异:
(1).系统根目录是/usr,不是/。
(2).删除系统集成内容,例如cyglsa、cygserver、cygstart。
(3).动态库的前缀是msys而不是cyg(大多数其他平台,包括mingw-w64,都使用lib)。
(4).在shell中的pwd命令中添加“-W”选项,以与旧的MSYS兼容。

实用程序中的各种更改有助于保持兼容性和互操作性。例如Perl将msys报告为$^O,或者Sed将CRLF识别为行尾。