程序的编写

操作系统(三)跨平台移植 - 图1

3个阶段的主导角色分别是:文本编辑器(Editor)、编译工具链(Tool chain,链的意思是一系列工具而不止一个)、程序加载器(Loader)。要实现跨平台移植,就要从这三方面入手。

  • 源代码编写过程在不同系统平台可以看作没有差异。

  • 系统A上的目标文件、库文件、可执行文件在系统B上一般是不可直接识别的;如果他们能做到相互识别,那可称这两个系统ABI(Application Binary Interface,应用程序二进制接口)兼容。

操作系统(三)跨平台移植 - 图2

  • os 内核创建一个新的进程,装载器,或者叫加载器,在内存开辟一片区域,从外部存储空间(如磁盘)中复制可执行文件内容到内存相关的段(segment)中,再跳转到程序入口并执行。

交叉工具链

image.png
Windows NT和Windows 95的目标文件使用COFF格式,Windows系统的可执行文件格式PE(Portable Executable)和Linux系统的可执行文件格式ELF(Executable Linkable Format)都是COFF的变种,而且此时GNU项目的gcc编译工具链已经支持COFF格式和newlib C标准库。

改写 gcc 源代码,使其编译出文件符合 windows 上的文件格式,在 linux 环境上行链接,编译出来的即是交叉工具链。

这个 “交叉”版的gcc运行于Linux系统,但生成Windows系统的目标文件,正因运行系统(host)和目标系统(target)不同,所以它才叫“交叉”工具链。

系统函数库

要让这个Windows版的gcc真正运行起来,还依赖于bash、POSIX兼容的系统调用等等系列程序和环境,一种思路是把这些依赖程序使用Win32 API重写、再编译构建,但这要花大量的时间将每一个程序都重写。

公司放弃了这种思路,使用 Win32 API重写一个函数库(Cygwin DLL),提供 Win32 API 所缺少的必要的POSIX API,如fork、spawn、signals、select、sockets等,事实上Cygwin DLL还调用了部分Windows Native API,并且由于os设计理念上的差异,以及Windows中有大量未对外公开的Win32 API、Windows Native API,有些POSIX API根本无法用它们模拟,Cygnus Solutions公司只能完全从零重写,而且为了处理 POSIX 和Windows中的差异还写了一部分Cygwin专有的函数。

image.png

bash 等移植后的工具,调用移植后的 newlib 库,newlib 库中调用 Cygwin DLL 中的模拟层,模拟层是来模拟 linux 系统中的内核的 API 接口。

image.png

mingw

Cygwin是用一个dll模拟linux环境来“欺骗”应用程序,好像自己运行在linux环境下;而mingw是在编译时提供linux到windows必要代码的“翻译”转换,用到的还是windows运行时库。

在cygwin下编译出来的程序需要cygwin.dll才能在windows下运行,源码拿到linux环境下重新编译就可以在linux下跑起来;mingw环境下编译出来的程序,只能在windows下跑,源码在linux环境下编译多半通不过。

msys

MSYS,由于 MinGW 本身仅代表编译工具链,而在 Windows 下,由于那个shi一样的cmd,以及配套的命令行工具不够齐全(也不舒服),因此,MinGW 开发者从曾经比较旧的 Cygwin 创建了一个分支,也用于提供类 Unix 环境。但与 Cygwin 的大而全不同,MSYS 是冲着小巧玲珑的目标去的,所以整套 MSYS 以及 MinGW,主要以基本的 Linux 工具为主,大小在 200M 左右,有包管理器 pacman。

MSYS 是用于辅助 Windows 版 MinGW 进行命令行开发的配套软件包,提供了部分 Unix 工具以使得 MinGW 的工具使用起来方便一些。如果不喜欢庞大的 Cygwin,而且使用不多,可以试试。不过喜欢完整体验、不在乎磁盘占用等等,还是推荐 Cygwin 而不是 MSYS。