为什么GCC-Windows依赖于cygwin?

时间:2008-10-09 16:11:21

标签: windows gcc cygwin posix compiler-construction

我不是C ++开发人员,但我一直对编译器感兴趣,而且我有兴趣修改一些GCC(特别是LLVM)。

在Windows上,GCC需要POSIX仿真层(cygwin或MinGW)才能正常运行。

为什么?

我使用许多其他软件,用C ++编写并交叉编译用于不同平台(Subversion,Firefox,Apache,MySQL),并且它们都不需要cygwin或MinGW。

我对C ++最佳实践编程的理解是,您可以编写合理的平台无关代码,并在编译过程中处理所有差异。

那么GCC的交易是什么?为什么它不能在Windows上本机运行?


编辑:

好的,到目前为止,这两个回复基本上说,“GCC使用posix层,因为它使用了posix标题”。

但这并没有真正回答这个问题。

假设我已经为我最喜欢的标准库提供了一组标题。为什么我仍然需要posix标题?

GCC是否要求cygwin / mingw实际 RUN

或者它只需要头部和库的仿真层吗?如果是这样,为什么我不能给它一个带有所需资源的“lib”目录?


再次编辑:

好的,我会再次尝试澄清这个问题......

我还在the D Programming Language中编写代码。官方编译器名为“dmd”,Windows和Linux都有官方编译器二进制文件。

Windows版本不需要任何类型的POSIX仿真。 Linux版本不需要任何类型的Win32仿真。如果编译器对其环境有假设,那么它很好地隐藏了这些假设。

当然,我必须告诉编译器在哪里找到标准库以及在哪里找到静态或动态链接的库。

相比之下,GCC坚持假装它在posix环境中运行,它要求我通过设置仿真层来幽默这些假设。

但是GCC内部究竟依赖于那层?它只是在寻找stdlib头,并假设它会在“/ usr / lib”中找到那些头文件吗?

如果是这种情况,我不应该只是告诉它查看“C:/ gcc / lib”来查找这些头文件吗?

或者GCC本身是否依赖POSIX库来访问文件系统(并做其他低级别的东西)?如果是这样,那么我想知道为什么他们不只是静态地链接他们喜欢的Windows POSIX库。为什么要求用户设置依赖项,何时可以将这些依赖项直接构建到应用程序中?

11 个答案:

答案 0 :(得分:37)

实际上,问题前提是错误的:MinGW GCC NOT 需要Cygwin。

你会发现你根本不需要Cygwin。它在Windows上本机运行(至少32位)。工具链和生成的二进制文件都独立于Cygwin。

Cygwin中可用的MinGW编译器是不同的:它们是在Cygwin平台上构建的,用于生成不依赖于Cygwin运行时的代码。在这种情况下,编译器本身依赖于Cygwin。但那是因为你是从Cygwin安装的。

答案 1 :(得分:29)

GCC的 Cygwin 版本需要为其编译的程序安装 Cygwin

MinGW 版本在编译后不需要任何内容​​,除了Windows的工作副本。

你不能真正将Cygwin环境和MinGW编译器混合在一起,因为Cygwin改变了预编译库的路径。

如果您需要bash样式的shell,但又不想使用Cygwin,我建议MSYS

Cygwin与MinGW相反

MinGW Wiki 复制

原则上Cygwin应用程序不被视为“Native Win32应用程序”,因为它依赖于Cygwin®POSIXEmulation DLL或cygwin1.dll用于Posix函数,并且不直接使用win32函数。另一方面,MinGW提供Win32 API提供的功能。在MinGW下移植应用程序时,Win32等原生函数(如fork()mmap()ioctl())需要重新实现为Win32等效项才能使应用程序正常运行。

答案 2 :(得分:7)

POSIX(可移植操作系统接口)“是一个不断发展的,不断发展的文档,由IEEE生产并由ANSI和ISO标准化.POSIX的目标是应用程序的源代码可移植性”[1]。

实际上,目标定义为编写一个源实现并使其在不同(POSIX兼容)系统上运行而只重新编译的能力。

GCC是一个能够实现这一承诺的编译器,因此,它需要一层代码才能使机器“达到”POSIX标准。

这是你问题答案的核心。

为了帮助我明白我的意思,我会为你提供这个练习:

  • 编写一个没有特定于操作系统的#ifdefs的程序,该程序从用户的某个目录路径输入,并向stdout写入其内容列表(一个级别)。

我认为您会发现编写仅使用在任何UNIX或LINUX系统上编译的本机WIN32 API的代码非常困难

编写使用POSIX API的代码只会稍微困难 - 就像在任何LINUX盒子上一样 - 并且在Windows下编译它(DevStudio2005现在有大量符合POSIX标准的头文件......你可能会能够接近)。

从上面获取LINUX程序,现在在Cygwin或MinGW下运行的GCC下编译它。我打赌它会编译并运行。

海湾合作委员会是如何表现出魔力的?由Cygwin或MinGW提供的POSIX标头和实现。

GCC对Windows下的Cygwin / MinGW的依赖现在更有意义吗?

  1. POSIX.4:为现实世界编程,Bill O. Gallmeister,O'Reilly& Associates,Inc.,第2页

答案 3 :(得分:5)

我尝试让我在Windows下的程序表现得像一个优秀的Windows公民,在Linux下就像一个优秀的Linux公民。

答案 4 :(得分:4)

为什么呢?因为创建GCC时,Windows 32位甚至没有退出...

更正确---它是为UNIX / Posix OS开发的。后来它移植到了Windows。

Windows不是POSIX兼容系统。它甚至不提供非常基本的功能。尝试在Windows编译器下查找readdirstat?这是一个非常基本的功能,你需要编写编译器!

为了清楚起见,GCC编译的程序通常只需要一个mingw32.dll来添加缺少的功能才能运行。

所以......你问为什么GCC需要一些POSIX层?因为Windows OS不是POSIX操作系统。

答案 5 :(得分:3)

Windows不提供标准POSIX库,因此cygwin提供了一个(cygwin1.dll)。 cygwin附带的gcc包使用它。

另一方面,mingw不一定需要提供POSIX层。例如,我使用的mingw安装甚至没有pthread库。

我是否需要它我必须安装它。 Mingw-gcc生成Win32本机代码(实际上依赖于MSVCRT.DLL)。

编辑:阅读您的编辑我不再确定您是否在问为什么gcc本身需要mingw / cygwin库,或者如果在Win上使用gcc编译的程序需要这些库

答案 6 :(得分:3)

  

我不是C ++开发人员,但我已经   一直对编译器感兴趣,   我有兴趣修修补补   一些GCC的东西(特别是   LLVM)

请注意,LLVM和GCC不相关。 LLVM主要是Chris Lattner(http://llvm.org/developers.cgi)关于现代优化的研究成果。他的论文可在http://llvm.org上找到。如今,它得到了Apple的大力赞助。 GCC的C / C ++ / Obj-C前端用于llvm-gcc,它发出LLVM机器代码(在llvm中进行了大量优化后,最终的可执行文件出来了); llvm-gcc是一种将一些现成的C / C ++ / Obj-C-frontend耦合到LLVM的hack。

请注意,LLVM工作人员还构建了一个自己的,完整的C / C ++ / Obj-C编译器,称为clang。它的C实现已经接近完成,C ++支持越来越好,但是关于Obj-C却不知道。

所以,如果有人说“编译器llvm”,他实际上要么意思是llvm-gcc,要么是clang。 LLVM本身就是低级虚拟机,在静态单一分配表单中只有少数指令(大约32条指令,但是没有),但是在你的语法树上有一百万的优化。

答案 7 :(得分:2)

在MinGW中编译了为不同平台编译的大部分软件。与gcc的唯一区别在于它是一个编译器本身,这意味着它需要通常与程序一起编译的所有头文件,通常哪个头文件不需要运行生成的程序。 / p>

答案 8 :(得分:0)

如果您不想支持pthread或OpenMP,那么在构建gcc时可以选择指定除posix之外的enable-threads选项。毋庸置疑,这些都没有经过充分测试。 OpenMP与Windows线程有一些第三方闭源支持,但它与gcc的使用似乎违反了许可证。 由于Windows pthreads库是Windows线程功能的更高级别接口,因此当它执行得不好或遇到Microsoft拒绝关联支持时,也许并不奇怪。 直到最近,微软才开始容忍Windows上的gcc。曾经有一段时间他们实际上说他们不会处理gcc用户报告的bug,即使他们可以使用专门的Microsoft工具进行复制。

答案 9 :(得分:-1)

gcc的MinGW-w64端口为32位和64位Windows创建本机代码,没有任何其他依赖项。 有关快速入门指南,请参阅http://mstenberg.com/blog/2010/06/13/gcc-for-windows/

答案 10 :(得分:-3)

因为人们对GCC感到厌恶,所以有一天会厌恶Windows(有一天会读Stallman)。因此,当将GCC移植到Windows时,他们会尽力假装它只是另一个Unix。

那,他们可能不想花时间从代码中删除POSIX依赖项。