为了实现c++的一次编译,到处运行的目的,我们采用cygwin和minGW。
minGW给那些习惯于在Linux上开发的人员,在windows上提供了一套类似的工具集。
cygwin主要是对于再Linux的程序,无需改动代码即可移植到windows上
Unix下编译通过的C代码,在win32下编译是不能通过的 ,当然Unix 和win32的API都是符合标准C,也就是说,大多数函数调用在unix和win32下是相同的.但是,unix有自己一些独特的API(如fork,spawn,signals,select,sockets等),如果代码中使用了这些API,在win32下当然找不到对应的库.
但是,这些API的功能在win32中也能实现,也许你已经发现了一个能让window编译Unix风格代码的方法:
1.修改编译器,让window下的编译器把诸如fork的调用翻译成等价的形式–这就是mingw的做法.
2.修改库,让window提供一个类似unix提供的库,他们对程序的接口如同unix一样,而这些库,当然是由win32的API实现的–这就是cygwin的做法.
Cygwin
这个项目的名字来源于:GNU、Cygnus、Windows,3者的缩写。Cygwin的目标是:构建一套Windows下的Linux模拟环境。因此,Cygwin是一个庞大的项目,不只包括Linux下的开发环境,也包括工作环境,和各种各样的Linux下的软件。
在早期,Cygwin的核心是cygwin1.dll,可以认为它是一个POSIX界面的实现,依靠这个动态链接库,Unix/Linux下的软件 可以很容易的移植到Windows下,并且风格保持原有的不变。不过随着Cygwin的发展,越来越多的Unix/Linux程序的移植,建立基于 Cygwin的复杂程序依赖的库也越来越多,现在装完默认配置的Cygwin后,就会发现有很多cyg打头的动态链接库。
目前Cygwin由RedHat维护和支持。在版权上,由于Cygwin不是一个软件,而是由成百上千的软件堆砌起来的系统,里面有商业软件的成分/概念,所以它的许可证有开源性质的(GPL)和商业性质的(从RedHat购买)两种。
MinGW
这个项目的名字来源于:Minimalist GNU for Windows的缩写。
最初,MinGW的目标定位为:Windows下的开源的开发环境。它包括一系列软件:编译工具、链接工具、转储工具、调试工具、和其它开发工具等。另一方面,MinGW还提供一些开源的基础支持库,像GNU的C/C++ RT库(libc、libstdc++),POSIX的基本调用界面(包括pthread),甚至还有OpenGL和Windows API的调用接口等。几乎所有MinGW中的软件都是从GNU项目或Linux下移植到Windows下的。
后来MinGW有了一个子项目叫:MSYS,其中包括了更多的Linux工具,其目标类似Cygwin:构建一套Windows下的Linux模拟环境。
总之,MinGW中的东西很杂,和Cygwin之间有相当一部分是重复的(目前,Cygwin项目中已经集成MinGW了)。但MinGW和Cygwin的实现思路和设计思想是不同的:
Cygwin通过一个中间层的动态链接库,将位于下层的Windows API,和位于上层的使用POSIX界面的应用连接起来,好处是应用在Linux与Windows之间移植更加方便,风格更加一致;缺点是发布应用时一定 要带上Cygwin的环境动态库,应用执行效率也略微有点低。
MinGW在基础支持库层次,使用静态链接的方式,这样生成的应用更加地本地化,应用执行效率也稍高一些。所以MinGW声明:基于MinGW开发的应用,不需要依赖任何第三方的C/C++ RT动态链接库,仅依赖Windows自身的运行环境:
MinGW provides a complete Open Source programming tool set which is suitable for the development of native MS-Windows applications, and which do not depend on any 3rd-party C-Runtime DLLs.
不过上面的结论不是绝对的,比如:
当你使用MinGW GCC的-mthreads选项(和线程安全异常处理有关)时,就会动态链接到 mingwm10.dll。
还有如果你使用MinGW GCC 4.4.0默认选项编译C++程序,就会动态链接到libgcc_s_dw2-1.dll,参考下面:
Dynamic linking with libgcc_s_dw2-1.dll is necessary to throw exceptions between different modules, such as between two DLLs or a DLL and an EXE. Consequently, it is the default for all languages other than C. To disable this dynamic linking, use -static-libgcc. To enable this dynamic linking in C, use -shared-libgcc.
MinGW的POSIX界面远没有Cygwin实现的那么全面(比如:连BSD/Linux Socket都没有,只能用Winsock),所以看起来MinGW只是用来开发Windows专属应用的工具集。
在版权上,MinGW比Cygwin更开放些。
我用过MSYS和Cygwin之后,发现MSYS相比Cygwin还有很多不足:
MSYS中的工具更像是Unix/Linux下的工具在Windows下的移植版,其中有些工具可以支持Windows的一些特征(比如:目录分隔 用"\"),而有些并没有Unix/Linux下原始的版本那么好用(比如:bash、sed等)。而Cygwin是努力在Windows下构建一套完全 参照Unix/Linux体验的环境。
MSYS中的工具很杂,和MinGW中的工具交织在一起(有时,开发工具和实用程序的界限并不是很截然,况且经常要配合使用),组织很松散,还有一 些爱好者自己提供软件包。如此,搭建基于MSYS的Unix/Linux环境变得稍繁琐,你需要更加谨慎地考虑软件包的依赖关系。而使用Cygwin就方 便多了,它的安装程序会归类显示软件包的组织关系,还能一定程度上帮你解决软件包的依赖关系。
推荐以下面这种方式搭建Windows下的Unix/Linux开发环境:
使用Cygwin的Unix/Linux工作环境,比如:bash、tar、awk、sed、od、man等。
使用MinGW的C/C++开发工具,比如:binutils、gcc、gdb、make、strip等;使用MinGW的基础支持库,比如:GNU的libc、libstdc++、POSIX的基本调用界面等。
根据需要,使用额外的支持/开发库,比如:pthread、openssl、libiconv、gettext、boost、wxWidgets等。
注意:
有些支持/开发库可以在MinGW项目的Sourceforge下载地址找到,像pthread(mingw gcc-4.4中包含)、openssl、libiconv、gettext等。也可以从这些库官方的项目地址,或其它的Windows移植版项目地址下载,总之,它们之间的联系比较松散。
如果有一些程序,在MinGW和Cygwin安装后有重复,可以用各种技巧设定它们被选择的优先级,比如:设置PATH环境变量中的搜索目录顺序,建立符号链接等方法。
获取最新mingw.一个make就搞定:
http://www.profv.de/mingw_cross_env/#tutorial
一般只要make gcc就OK了。
MinGW 是 GCC 編譯器的 Win32 精簡移植版,理論上 MinGW 可以將標準的 C/C++/Fortran/… 原始碼編譯成 Win32 原生程式,但實務上光移植編譯器仍然有所不足,因為很多現存的軟體只有針對 Unix-like 環境撰寫 Makefile 或 autotools 配置檔,因此有必要將建置軟體過程最常用到的 Linux 功能也一併模擬,這就是 MSYS 的由來。
MSYS 純粹就只是為了編譯程式開一條方便之門,僅提供了少許的 Linux 工具,並且模擬 Linux 的命令解釋器和目錄架構。這和 MinGW 之前的 Cygwin 有很大的不同,Cygwin 的目標是在 Windows 上盡可能完整地模擬 Linux。事實上 Cygwin 在很多場合被視為既非 Windows 亦非 Linux 的獨立 target 平台。
首先MingW和cygwin都可以用来跨平台开发。
MinGW是Minimalistic GNU for Windows的缩写,也就是Win版的GCC。
Cygwin则是全面模拟了Linux的接口,提供给运行在它上面的的程序使用,并提供了大量现成的软件,更像是一个平台。
相对的MingW也有一个叫MSys(Minimal SYStem)的子项目,主要是提供了一个模拟Linux的Shell和一些基本的Linux工具。因为编译一个大型程序,光靠一个GCC是不够的,还需要有Autoconf等工具来配置项目,所以一般在Windows下编译ffmpeg等Linux下的大型项目都是通过Msys来完成的,当然Msys只是一个辅助环境,根本的工作还是MingW来做的。
用MingW和cygwin编译出来的程序的区别。
首先MingW和cygwin都不能让Linux下的程序直接运行在Windows上,必需通过源代码重新编译。
现代操作系统包括Windows和Linux的基本设计概念像进程线程地址空间虚拟内存这些都是大同小异的,之所以二者上的程序不能兼容,主要是它们对这些功能具体实现上的差异,首先是可执行文件的格式,Window使用PE的格式,并且要求以.EXE为后缀名。Linux则使用Elf。其次操作系统的API也不一样,如Windows用CreateProcess()创建进程,而Linux使用fork()。
所以要移植程序必然要在这些地方进行改变,MingW有专门的W32api头文件,来把代码中Linux方式的系统调用替换为对应的Windows方式。而Cygwin则通过cygwin1.dll这个文件来实现这种API的转换,并模拟一个Linux系统调用接口给程序,程序依然以Linux的方式调用系统API,只不过这个API在cygwin1.dll上,cygwin1.dll再调用Windows对应的实现,来把结果返回给程序。
可以用查看他们编译好的程序的导入表来验证这点。
二者生成的程序都是能在Windows上运行的EXE文件,显然都是PE格式,用一个PE格式查看工具检查一下就能发现,Cygwin生成的程序依然有fork()这样的Linux系统调用,但目标库是cygwin1。而MingW生成的程序,则全部使用从KERNEL32导出的标准Windows系统API。
这样看来用Mingw编译的程序性能会高一点,而且也不用带着那个接近两兆的cygwin1.dll文件。
但Cygwin对Linux的模拟比较完整,甚至有一个Cygwin X的项目,可以直接用Cygwin跑X。
另外Cygwin可以设置-mno-cygwin的flag,来使用Mingw编译。
而与Cygwin更有可比性的MSys上的工具也是通过Cygwin这种模拟的方式来提供的。