39

我不是 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 才能实际运行

还是只需要头文件和库的仿真层?如果是这样,为什么我不能只给它一个包含所需资源的“lib”目录?


再次编辑:

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

我还用D 编程语言编写代码。官方编译器名为“dmd”,并且有适用于 Windows 和 linux 的官方编译器二进制文件。

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

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

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

但是,在 GCC 中,究竟是什么依赖于该层?它只是在寻找 stdlib 标头,并假设它会在“/usr/lib”中找到这些标头吗?

如果是这样的话,我不应该告诉它在“C:/gcc/lib”中查找那些头文件吗?

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

4

11 回答 11

37

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

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

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

于 2008-10-26T12:36:21.360 回答
29

GCC的Cygwin版本需要安装Cygwin才能编译程序。

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

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

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

Cygwin 与 MinGW 的对比

复制自MinGW Wiki

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

于 2008-12-10T00:49:36.047 回答
7

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

实际上,目标被定义为编写一个源代码实现并让它在不同的(符合 POSIX 的)系统上运行的能力,而只需重新编译。

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

这是您问题答案的核心。

为了帮助理解我的意思,我将为您提供以下练习:

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

我想你会发现很难编写只使用在任何 UNIX 或 LINUX 系统上编译的本机 WIN32 API 的代码

编写使用 POSIX API 的代码——就像在任何 LINUX 机器上一样——并让它在 Windows 下编译(DevStudio2005 现在有数量惊人的符合 POSIX 的标头......你可能会得到关)。

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

GCC 是如何发挥这种魔力的?Cygwin 或 MinGW 提供的 POSIX 标头和底层实现。

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

  1. POSIX.4:面向现实世界的编程,Bill O. Gallmeister,O'Reilly & Associates, Inc.,第 2 页
于 2009-04-19T03:43:18.910 回答
7

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

于 2008-11-04T10:48:19.087 回答
3

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

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

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

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

于 2008-10-09T16:25:11.970 回答
3

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

更准确地说——它是为 UNIX/Posix OS 开发的。后来被移植到windows上。

Windows 不是 POSIX 兼容系统。它甚至不提供非常基本的功能。试试看readdir还是stat在windows下编译?这是非常基本的功能,您需要编写编译器!

需要明确的是,GCC 编译的程序通常只需要一个 mingw32.dll 来添加缺少的功能即可运行。

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

于 2009-04-19T04:45:10.273 回答
3

我不是 C++ 开发人员,但我一直对编译器很感兴趣,而且我对修补一些 GCC 的东西很感兴趣(尤其是 LLVM)

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

无论如何请注意,LLVM 团队还构建了一个自己的、完整的 C/C++/Obj-C 编译器,称为 clang。它的 C 实现接近完成,C++ 支持越来越好,但不知道 Obj-C。

所以,如果有人说“compiler llvm”,他的意思要么是llvm-gcc,要么是clang。LLVM 本身只是低级虚拟机,只有少数静态单一分配形式的指令(大约 32 条指令,公平的),但是大量的优化传递到你的语法树上。

于 2009-05-05T14:15:00.710 回答
2

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

于 2008-10-09T16:18:15.637 回答
0

因为支持 GCC 的人满怀热情地讨厌 Windows(总有一天会读到 Stallman)。因此,当将 GCC 移植到 Windows 时,他们尽最大努力假装它只是另一个 Unix。

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

于 2010-01-10T06:27:50.050 回答
0

The MinGW-w64 port of gcc creates native code for 32- and 64-bit Windows without any additional dependencies. See for example http://mstenberg.com/blog/2010/06/13/gcc-for-windows/ for a quick getting-started guide.

于 2010-06-22T19:17:03.087 回答
0

如果您不想支持 pthread 或 OpenMP,则在构建 gcc 时可以选择指定 posix 以外的 enable-threads 选项。不用说,这些都没有经过很好的测试。有一些第 3 方对带有 Windows 线程的 OpenMP 的封闭源代码支持,但它与 gcc 的使用似乎违反了许可。由于 Windows pthreads 库是 Windows 线程功能的更高级别接口,因此当它性能不佳或遇到 Microsoft 拒绝支持亲和性支持时,这可能并不奇怪。直到最近,微软才开始在 Windows 上容忍 gcc。曾经有一段时间,他们实际上说他们不会处理 gcc 用户报告的错误,即使它们可以用专门的 Microsoft 工具复制。

于 2015-09-06T15:32:34.627 回答