为什么GCC-Windows依赖于cygwin?
我不是一个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版本不需要任何forms的Win32仿真。 如果编译器对其环境做出假设,它就会很好地隐藏这些假设。
当然,我必须告诉编译器在哪里find标准库以及在哪里find静态或dynamic链接的库。
相比之下,海湾合作委员会坚持假装它是在一个POSIX环境中运作的,并要求我通过build立一个仿真层来幽默这些假设。
但是,GCC内部依赖于这一层呢? 它只是寻找stdlib头,它假定它会在“/ usr / lib”中find这些头?
如果是这样的话,我不应该只是告诉它在“C:/ gcc / lib”中查找这些头文件吗?
还是GCC本身依靠POSIX库来访问文件系统(以及做其他低级的东西)? 如果是这样的话,那么我想知道他们为什么不只是静静地链接到他们最喜欢的windows POSIX库。 为什么要求用户设置依赖关系,何时才能将这些依赖关系直接构build到应用程序中?
其实这个问题的前提是错的: MinGW GCC不需要Cygwin。
你会看到你根本不需要Cygwin。 它在Windows上本地运行(至less32位)。 工具链和生成的二进制文件都是独立于Cygwin的。
Cygwin中可用的MinGW编译器不同:它们构build在Cygwin平台上,生成不依赖于Cygwin运行时的代码。 在这种情况下,编译器本身也依赖于Cygwin。 但那是因为你从Cygwin安装了它们。
Cygwin版本的GCC需要安装Cygwin ,用于编译程序。
MinGW版本编译后不需要任何东西,除了Windows的工作副本。
你不能真的把Cygwin环境和MinGW编译器混合在一起,因为Cygwin改变了预编译库的path。
如果你需要一个bash风格的shell,但不想使用Cygwin,我会推荐MSYS 。
Cygwin与MinGW相反
从MinGW维基复制
Cygwin应用程序原则上不被视为“原生Win32应用程序”,因为它依赖于Cygwin®POSIX仿真DLL或
cygwin1.dll
Posix函数,并不直接使用win32函数。 另一方面,MinGW提供了由Win32 API提供的function。 在MinGW下移植应用程序时,需要将不是Win32原生的函数fork()
例如fork()
,mmap()
或ioctl()
重新实现到Win32等价物中,以使应用程序正常工作。
POSIX(Portable Operating System Interface,便携式操作系统接口)“是由IEEE制定的,由ANSI和ISO进行标准化的不断发展的不断发展的文档,POSIX的目标是应用程序的源代码可移植性[1]。
实际上,目标被定义为编写一个源实现的能力,并且只在重新编译时才能在不同的(符合POSIX的)系统上运行。
GCC是一个能够实现这一承诺的编译器,因此它需要一层代码来使机器达到POSIX标准。
这是你的问题的答案的核心。
为了明白我的意思,我会为您提供这个练习:
- 编写一个没有操作系统特定的#ifdefs的程序,该程序从用户input一些目录path,并向stdout写入其内容列表(一个级别)。
我想你会发现编写只使用在任何UNIX或LINUX系统上编译的本地WIN32 API的代码是非常困难的
编写使用POSIX API的代码只要稍微简单一些,就像在任何LINUX框中一样 – 然后在Windows下进行编译(DevStudio2005现在拥有令人惊讶的POSIX兼容的头文件数量…你可能能够得到关)。
从上面的LINUX程序,现在编译它在GCC运行在Cygwin或MinGW下。 我敢打赌,它编译和运行。
GCC是如何执行这一点魔法的? Cygwin或MinGW提供的POSIX头文件和实现。
GCC在Windows下对Cygwin / MinGW的依赖更有意义吗?
- POSIX.4:为真实世界编程,Bill O. Gallmeister,O'Reilly&Associates,Inc.,第2页
我试图让Windows下的程序像一个好的Windows公民一样,在Linux下像一个好的Linux公民一样。
为什么? 因为当GCC创build时,Windows 32位甚至没有退出…
为了更加正确—它是为UNIX / Posix OS开发的。 后来它被移植到窗口。
Windows不是POSIX compient系统。 它甚至不提供非常基本的function。 尝试findWindows编译器下的readdir
或stat
? 而这是非常基本的function,你需要编写编译器!
要清楚的是,GCC编译的程序通常只需要一个mingw32.dll就可以添加缺less的function来运行。
所以…你问为什么GCC需要一些POSIX层? 因为Windows OS不是POSIX操作系统。
Windows不提供标准的POSIX库,所以cygwin提供了一个(cygwin1.dll)。 cygwin自带的gcc包使用它。
另一方面,mingw并不需要提供POSIX层。 我使用的mingw安装,例如,甚至没有一个pthread库。
我应该需要它,我将不得不安装它。 Mingw-gcc生成Win32本机代码(实际上依赖于MSVCRT.DLL)。
编辑:读你的编辑我不再确定如果你问为什么gcc本身需要mingw / cygwin图书馆,或者如果用gcc在Win上编译的程序需要这些图书馆
我不是一个C ++开发人员,但是我一直对编译器感兴趣,而且我有兴趣修改一些GCC的东西(特别是LLVM)
请注意,LLVM和GCC不相关。 LLVM在很大程度上是由Chris Lattner( http://llvm.org/developers.cgi )对现代优化所做的研究的结果。 他的论文可以在http://llvm.org上find 。 如今,它是由苹果公司赞助的。 GCC的C / C ++ / Obj-C前端用于llvm-gcc,它发出LLVM机器代码(在llvm中进行了大量优化之后,最终的可执行文件出来了)。 llvm-gcc是一种将一些现成的C / C ++ / Obj-C前端连接到LLVM的一种方法。
注意,LLVM人员还build立了一个自己的,完整的C / C ++ / Obj-C编译器,叫做clang。 它的C实现接近完成,C ++支持越来越好,不过关于Obj-C不知道。
所以,如果有人说“编译器llvm”,他真的意味着llvm-gcc或clang。 LLVM本身就是低级虚拟机,只有less数静态单指派指令(大约32条指令,afair),但是在你的语法树上会有大量的优化。
大部分针对不同平台编译的软件都是在MinGW中编译的。 与gcc唯一的区别在于它是一个编译器本身 ,这意味着它需要所有的头文件,这些头文件通常被程序编译,通常哪个头文件不需要运行结果程序。
如果您不想支持pthread或OpenMP,则在构buildgcc以指定除posix之外的其他启用线程选项时,您可以select一个选项。 不用说,那些testing不够好。 OpenMP与Windows线程有一些第三方的闭源支持,但是它与gcc的使用似乎违反了许可证。 由于Windows pthreads库是Windows线程function的更高级别接口,因此,如果性能不佳或遇到Microsoft拒绝关联支持,则可能并不奇怪。 直到最近微软才开始在Windows上容忍gcc。 有一段时间,他们实际上表示不会处理海湾合作委员会用户报告的错误,即使这些错误只能通过微软的工具进行复制。
gcc的MinGW-w64端口为32位和64位Windows创build了本地代码,没有任何额外的依赖关系。 请参阅http://mstenberg.com/blog/2010/06/13/gcc-for-windows/的快速入门指南。;
因为人们激动地抨击GCC憎恨Windows(有一天会阅读Stallman)。 所以在将GCC移植到Windows时,他们尽力装扮成另一个Unix。
那么,他们可能不想花时间从代码中删除POSIX依赖关系。