Cygwin 系列(一):Cygwin 是什么

Cygwin 系列(一):Cygwin 是什么

本文 4300 余字,阅读约 11 分钟,本文知乎链接:Cygwin 系列(一):Cygwin 是什么

本文接上篇 Cygwin 前传:从割据到互补。先一句话回答标题:Cygwin 是一个可原生运行于 Windows 系统上的 POSXI 兼容环境

前言:从软件角度理解系统

计算机世界里存在各种各样的操作系统,目前通用操作系统有主流的三大类:

  • UNIX,通用操作系统鼻祖,发展出特别多衍生系统;
  • Windows,微软家根基,桌面市场霸主;
  • GNU/Linux,UNIX 近亲,有各种发行版如 Ubuntu、CentOS 等。

这些系统有各自的内核,出于系统稳定性考虑是不允许用户程序直接操作内核,同时也将内核开发和应用软件开发隔离开来,系统将必要的函数封装成库供应用软件调用,约定的规范即为应用软件接口 (Application Program Interface,API)。

img

软件系统层级关系简要示意图

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(计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决)”。

img

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。*

img

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 的模拟层,其使用场合也就是针对这两点。

img

高效命令行工具 (图片来源于网络)

常见的应用场合包括但不限于:

(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 下开发者自己可以任意选取、混合使用。

参考

更多阅读

上一篇 silaoA:Cygwin 前传:从割据到互补zhuanlan.zhihu.com图标

下一篇 Cygwin 系列(二):初窥 Cygwin 背后zhuanlan.zhihu.com图标

posted @ 2020-07-27 10:28  别再闹了  阅读(3313)  评论(0编辑  收藏  举报