【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>
我想让我的C ++项目跨平台,我正在考虑使用Cygwin / MinGW。 但它们之间有什么区别?
另一个问题是我是否能够在没有Cygwin / MinGW的系统上运行二进制文件?
#1楼
维基百科说 :
MinGW
从Cygwin
1.3.3版本开始。 尽管Cygwin
和MinGW
都可用于将UNIX
软件移植到Windows
,但它们有不同的方法:Cygwin
旨在提供完整的POSIX layer
,提供Linux
,UNIX
和BSD
变体上存在的多个系统调用和库的模拟。POSIX layer
在Windows
之上运行,在必要时牺牲性能以实现兼容性。 因此,这种方法要求使用Cygwin
编写的Windows
程序在copylefted兼容库之上运行,该库必须与程序一起分发,以及程序的source code
。MinGW
旨在通过直接的Windows API calls
提供本机功能和性能。 与Cygwin
不同,MinGW
不需要兼容层DLL
,因此程序不需要与source code
一起分发。由于
MinGW
依赖于Windows API calls
,因此无法提供完整的POSIX API
; 它无法编译可以使用Cygwin
编译的一些UNIX applications
。 具体来说,这适用于需要POSIX
功能的应用程序,如fork()
,mmap()
或ioctl()
以及期望在POSIX environment
运行的应用程序。 使用自己移植到MinGW
的cross-platform library
编写的应用程序,例如SDL
,wxWidgets
,Qt
或GTK+
,通常可以像在Cygwin
一样在MinGW
轻松编译。
MinGW
和MSYS
的组合提供了一个小型的自包含环境,可以将其加载到可移动媒体上,而无需在注册表或计算机上的文件中留下条目。Cygwin
Portable提供了类似的功能。 通过提供更多功能,Cygwin
安装和维护变得更加复杂。也可以
MinGW-GCC under POSIX systems
使用MinGW-GCC under POSIX systems
cross-compile Windows applications
。 这意味着开发人员不需要使用MSYS
安装Windows来编译将在没有Cygwin
情况下在Windows
运行的软件。
#2楼
Cygwin
使用兼容层,而MinGW
是原生的。 这是主要的差异之一。
#3楼
Cygwin旨在为Windows提供或多或少的完整POSIX环境,包括一系列旨在提供完整的类Linux平台的工具。 相比之下,MinGW和MSYS提供了一个轻量级,简约的POSIX类图层,只有像gcc
和bash
这样的基本工具可用。 由于MinGW更简约的方法,它没有提供Cygwin提供的POSIX API覆盖程度,因此无法构建某些程序,否则可以在Cygwin上编译。
就两者生成的代码而言,Cygwin工具链依赖于动态链接到大型运行时库cygwin1.dll
,而MinGW工具链将代码编译为动态链接到Windows本机C库msvcrt.dll
以及二进制文件的二进制文件。静态的部分glibc
。 因此,Cygwin可执行文件更紧凑,但需要单独的可再发行DLL,而MinGW二进制文件可以单独发布,但往往更大。
基于Cygwin的程序需要运行单独的DLL这一事实也会导致许可限制。 Cygwin运行时库在GPLv3下获得许可,对于具有OSI兼容许可证的应用程序具有链接例外,因此希望围绕Cygwin构建闭源应用程序的开发人员必须从Red Hat获得商业许可。 另一方面,MinGW代码可以在开源和闭源应用程序中使用,因为标头和库是许可的。
#4楼
要在商业/专有/非开源应用程序中使用Cygwin,您需要为Red Hat的“ 许可证收购 ”支付数万美元; 这会以相当大的成本使标准许可条款无效。 谷歌“cygwin许可证费用”,并看到前几个结果。
对于mingw,不会产生这样的费用,许可证(PD,BSD,MIT)非常宽松。 最多可能需要为您的应用程序提供许可证详细信息,例如使用mingw64-tdm时所需的winpthreads许可证。
编辑感谢Izzy Helianthus:商业许可证不再可用或不必要,因为在Cygwin的winsup子目录中找到的API库现在正在 LGPL下发布,而不是完整的GPL。
#5楼
从移植C程序的角度来看,理解这一点的一个好方法就是举个例子:
#include <sys/stat.h>
#include <stdlib.h>
int main(void)
{
struct stat stbuf;
stat("c:foo.txt", &stbuf);
system("command");
printf("Hello, World\n");
return 0;
}
如果我们将stat
更改为_stat
,我们可以使用Microsoft Visual C编译该程序。我们也可以使用MinGW和Cygwin编译该程序。
在Microsoft Visual C下,程序将链接到MSVC可再发行的运行时库: mxvcrtnn.dll
,其中nn
是某个版本后缀。 要运送此程序,我们必须包含该DLL。 该DLL提供了_stat
, system
和printf
。 (我们也可以选择静态链接运行时。)
在MinGW下,该程序将链接到msvcrt.dll
,这是一个内部的,未记录的,无版本的库,是Windows的一部分,并禁止应用程序使用。 该库本质上是来自MS Visual C的可再发行的运行时库的一个分支,供Windows本身使用。
在这两个方面,该计划将有类似的行为:
-
stat
函数将返回非常有限的信息 - 例如,没有有用的权限或inode编号。 - 路径
c:file.txt
根据与驱动器c:
关联的当前工作目录解析。 -
system
使用cmd.exe /c
来运行外部命令。
我们也可以在Cygwin下编译程序。 与MS Visual C使用的可再发行的运行时类似,Cygwin程序将链接到Cygwin的运行时库: cygwin1.dll
(Cygwin本身)和cyggcc_s-1.dll
(GCC运行时支持)。 由于Cygwin现在属于LGPL,我们可以打包我们的程序,即使它不是与GPL兼容的免费软件,也可以发送程序。
在Cygwin下,库函数的行为会有所不同:
-
stat
函数具有丰富的功能,在大多数字段中返回有意义的值。 - 路径
c:file.txt
根本不被理解为包含驱动器号引用,因为c:
后面没有斜杠。 冒号被认为是名称的一部分,并以某种方式进入其中。 在Cygwin中没有针对卷或驱动器的相对路径的概念,没有“当前记录的驱动器”概念,也没有每个驱动器当前工作目录的概念。 -
system
函数尝试使用/bin/sh -c
解释器。 Cygwin将根据您的可执行文件的位置解析/
path,并期望sh.exe
程序与您的可执行文件位于sh.exe
位置。
Cygwin和MinGW都允许您使用Win32功能。 如果要调用MessageBox
或CreateProcess
,则可以执行此操作。 您还可以使用gcc -mwindows
在MinGW和Cygwin下轻松构建一个不需要控制台窗口的程序。
Cygwin不是严格的POSIX。 除了提供对Windows API的访问之外,它还提供了自己的一些Microsoft C函数的实现(在msvcrt.dll
找到的东西或可重新分发的msvcrtnn.dll
运行时)。 一个例子是spawn*
函数系列,如spawnvp
。 这些是在Cygwin上使用而不是fork
和exec
的好主意,因为它们更好地映射到没有fork
概念的Windows进程创建模型。
从而:
由于需要图书馆的伴奏,Cygwin程序不比MS Visual C程序“原生”。 Windows上的编程语言实现有望提供自己的运行时,甚至C语言实现。 Windows上没有“libc”供公众使用。
MinGW不需要第三方DLL的事实实际上是一个缺点; 它取决于Visual C运行时的未记录的Windows内部分支。 MinGW这样做是因为GPL系统库异常适用于
msvcrt.dll
,这意味着可以使用MinGW编译和重新分发GPL编辑的程序。与
msvcrt.dll
相比,由于对POSIX的支持范围更广,更深入,因此Cygwin是移植POSIX程序的优越环境。 由于它现在属于LGPL,它允许重新分发具有各种许可证(开放源代码或封闭源代码)的应用程序。 Cygwin甚至包含VT100仿真和termios
,它们可与Microsoft控制台配合使用! 使用tcsetattr
设置原始模式并使用VT100代码控制光标的POSIX应用程序将在cmd.exe
窗口中正常工作。 就最终用户而言,它是一个本机控制台应用程序,可以通过Win32调用来控制控制台。
然而:
- 作为一个原生的Windows开发工具,Cygwin有一些怪癖,比如Windows的外来路径处理,依赖于某些硬编码路径,如
/bin/sh
和其他问题。 这些差异使得Cygwin程序“非本地”。 如果程序将路径作为参数或从对话框输入,则Windows用户希望该路径的工作方式与在其他Windows程序中的工作方式相同。 如果它不起作用,那就是一个问题。
插件:在LGPL发布后不久,我启动了Cygnal (Cygwin Native Application Library)项目,提供了一个Cygwin DLL的分支,旨在解决这些问题。 程序可以在Cygwin下开发,然后使用Cygnal版本的cygwin1.dll
进行部署而无需重新编译。 随着这个库的改进,它将逐渐消除对MinGW的需求。
当Cygnal解决路径处理问题时,可以开发一个单独的可执行文件,当作为带有Cygnal的Windows应用程序提供时,它可以与Windows路径一起使用,并且当安装在Cygwin下的/usr/bin
时,可以无缝地与Cygwin路径一起使用。 在Cygwin下,可执行文件将透明地使用/cygdrive/c/Users/bob
类的路径。 在与cygwin1.dll
的Cygnal版本链接的本机部署中,该路径没有意义,而它将理解c:foo.txt
。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3152383