使用mingw32构建时与cygwin1.dll链接?

时间:2013-12-09 17:46:36

标签: c++ dll cygwin cross-platform mingw

我希望尽可能少地将Linux C ++应用程序移植到Windows(即根本不需要修改代码,也不需要全新的构建系统)。

该应用程序主要对SDLOpenGL进行API调用,两者都可在Windows上使用。但是,它还使用了POSIX等功能,例如ptys,这使我无法使用mingw32工具链。

Cygwin,或者更确切地说,cygwin1.dll,实现了整个POSIX API,并在内部将其转换为Win32。我知道Cygwin也有自己的编译器套件,但根据我的理解,不可能直接调用Win32或其他Windows库(例如SDL或{{1} })。

因此,我的想法是使用OpenGL构建项目(在大多数发行版中也可以方便地作为交叉编译器使用),但此外还与mingw32链接。然而,我怀疑互联网上似乎没有人试过这个,以及Linux上的cygwin编译器似乎不可用。

所以我的问题是:

  • 这是一个合法的想法,或者即使我设法将它一起破解,一切都会失败吗?
  • 这样做的合法方式是什么(我在哪里获取cygwin标头和dll文件)?

许可不是问题。

2 个答案:

答案 0 :(得分:4)

这不可行。关键问题是C运行时库(CRT)有两个不同且不兼容的版本 - Cygwin的GNU库(glibc)和Microsoft的C运行时。 MinGW工具链使用Microsoft CRT,而Cygwin GCC工具链使用Cygwin CRT。

这两个CRT中的每一个都以不同的方式实现。以malloc()函数为例。两个CRT都以不同的方式实现malloc(),可能是通过用VirtualAlloc()从操作系统分配虚拟内存,然后以自己的方式相应地对其进行分割。如果你有一个程序将两个CRT加载到它中并且你从一个CRT调用malloc()但是然后在另一个CRT中尝试free()它会崩溃,因为每个CRT都不知道如何底层数据结构在另一个中起作用。

所以,即使你设法在这里拼凑了一些东西并且没有错误地编译和链接,它仍然会在运行时以“不可能”的方式崩溃,因为这种基本的不兼容性。

现在,在这里做事的正确方法是什么?您需要决定要使用哪个CRT。 Microsoft CRT不支持许多POSIX功能,因此如果您不想重写代码以避免所有缺少POSIX功能,则必须使用Cygwin CRT,并且必须将其用于所有项目中的代码(所有源文件,所有静态库,所有DLL等)。

您对Win32的理解是错误的 - 您可以从Cygwin程序调用原始Win32 API。 Cygwin GCC工具链甚至带有自己的<windows.h>头文件。对调用CreateFileVirtualAlloc

等函数没有限制

对于您正在使用的其他库,例如SDL和OpenGL,您需要针对您所针对的相同CRT编译的那些库的版本。如果您有库的源代码,那么您可以自己编译它们。

Here are instructions用于为Cygwin编译SDL。对于OpenGL,您可以通过Cygwin设置安装一堆软件包来获取OpenGL头文件和库,例如: libEGL-devellibGL-devellibGLU-devellibglut-devellibGLw-devel个包。

答案 1 :(得分:3)

我强烈建议不要这样做。在链接阶段,最重要的是在运行时,您肯定会遇到二进制不兼容问题和许多其他细微问题。每个工具链都有其用途,因此请更好地使用符合您要求的工具链。

  • 是否愿意放弃平台相关功能(在代码中直接使用POSIX)?然后消除它并转到 MinGW-w64
  • 否?您别无选择,只能使用Cygwin及其附带的GCC工具链。顺便说一句,他们最近推出了64位(x64)版本的Cygwin(以及随附的GCC工具链),效果非常好。

对我而言,两种方法都很好看。 Cygwin的翻译开销实际上是最小的,并且您不必为您的应用程序分发整个Cygwin,而只需要运行时DLL。不过,就个人而言,我认为现代跨平台应用程序应该很难真正跨平台而不能直接使用这样的低级API作为POSIX,因为这实际上是第一个应用程序的缺陷声称是跨平台的地方。感谢上帝,今天我们有大量现代化和高质量的图书馆来帮助我们。例如,在我的项目中,我总是坚持第一种方法,到目前为止我不得不承认它总是可行的,但有时候只需要一些你不应该害怕的麻烦,因为它肯定会在未来得到回报。