简体   繁体   English

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

[英]Linking with cygwin1.dll while building with mingw32?

I wish to port a Linux C++ application to Windows with the minimum possible effort (ie no code modifications at all, and no entirely new build system). 我希望尽可能少地将Linux C ++应用程序移植到Windows(即根本没有代码修改,也没有全新的构建系统)。

The application is mainly doing API calls to SDL and OpenGL , which both are available on Windows. 该应用程序主要对SDLOpenGL进行API调用,这些调用都可以在Windows上使用。 However, it also uses POSIX functionality such as ptys, which are preventing me from using the mingw32 toolchain. 但是,它也使用POSIX功能,如ptys,这阻止我使用mingw32工具链。

Cygwin , or, more precisely, cygwin1.dll , implements the whole POSIX API and internally translates it to Win32 . Cygwin ,或者更确切地说, cygwin1.dll ,实现了整个POSIX API,并在内部将其转换为Win32 I understand that Cygwin also comes with its own compiler suite, but to my understanding it is impossible to directly make calls to Win32 or other Windows libraries (such as SDL or OpenGL ). 我知道Cygwin也有自己的编译器套件,但根据我的理解,不可能直接调用Win32或其他Windows库(如SDLOpenGL )。

Hence, my idea is to build the project with mingw32 (which is conveniently also available as a cross-compiler on most distros), but in addition also link with cygwin1.dll . 因此,我的想法是使用mingw32构建项目(在大多数发行版中也可以方便地作为交叉编译器使用),但此外还与cygwin1.dll链接。 I am, however, getting suspicious by the fact that nobody on the internet seems to have tried this, and the seeming unavailability of the cygwin compiler on Linux. 然而,我怀疑互联网上似乎没有人试过这个,以及Linux上的cygwin编译器似乎不可用。

So my question would be: 所以我的问题是:

  • Is this a legitimate idea, or will everything fail horribly even if I manage to hack it together? 这是一个合法的想法,或者即使我设法将它一起破解,一切都会失败吗?
  • What's the legitimate way of doing it (where do I get the cygwin headers and dll file)? 这样做的合法方式是什么(我在哪里获得cygwin头文件和dll文件)?

Licensing is not an issue. 许可不是问题。

This cannot possibly work. 这不可行。 The key issue is that there are two different and incompatible versions of the C runtime library (CRT) -- Cygwin's GNU library (glibc) and Microsoft's C runtime. 关键问题是C运行时库(CRT)有两个不同且不兼容的版本 - Cygwin的GNU库(glibc)和Microsoft的C运行时。 The MinGW toolchain uses the Microsoft CRT, while the Cygwin GCC toolchain uses the Cygwin CRT. MinGW工具链使用Microsoft CRT,而Cygwin GCC工具链使用Cygwin CRT。

Each of these two CRTs is implemented differently. 这两个CRT中的每一个都以不同的方式实现。 Take the malloc() function, for example. malloc()函数为例。 Both CRTs implement malloc() differently, perhaps by allocating virtual memory from the OS with VirtualAlloc() and then divying it up accordingly in their own manner. 两个CRT以不同方式实现malloc() ,可能是通过VirtualAlloc()从OS分配虚拟内存,然后以自己的方式相应地对其进行分割。 If somehow you had a program which loaded both CRTs into it and you called malloc() from one CRT but then tried to free() it in another, it would crash horribly, because each CRT doesn't know how the underlying data structures work in the other. 如果你有一个程序将两个CRT加载到它中并且你从一个CRT调用malloc()但是然后尝试在另一个CRT中free()它会崩溃,因为每个CRT都不知道底层数据结构是如何工作的在另一个。

So even if you managed to cobble together something here and got everything to compile and link without errors, it would still crash at runtime in "impossible" ways because of this fundamental incompatibility. 因此,即使你设法在这里拼凑了一些东西并且没有错误地编译和链接,它仍然会在运行时以“不可能”的方式崩溃,因为这种基本的不兼容性。

Now, what's the correct way to do things here? 现在,什么是在这里做事情的正确方法? You need to decide which CRT you want to use. 您需要决定要使用哪个CRT。 The Microsoft CRT does not support many POSIX features, so if you don't want to rewrite your code to avoid all of those missing POSIX features, you must use the Cygwin CRT, and you must use it for all code in your project (all source files, all static libraries, all DLLs, etc.). Microsoft CRT不支持许多POSIX功能,因此如果您不想重写代码以避免所有缺少POSIX功能,则必须使用Cygwin CRT,并且必须将它用于项目中的所有代码(所有源文件,所有静态库,所有DLL等)。

Your understanding about Win32 is wrong -- you can make calls to the raw Win32 API from Cygwin programs. 您对Win32的理解是错误的 - 您可以从Cygwin程序调用原始Win32 API。 The Cygwin GCC toolchain even comes with its own <windows.h> header file. Cygwin GCC工具链甚至还带有自己的<windows.h>头文件。 There are no restrictions against calling functions like CreateFile , VirtualAlloc , etc. 对调用CreateFileVirtualAlloc等函数没有任何限制。

For other libraries you're using such as SDL and OpenGL, you need versions of those libraries which are compiled against the same CRT which you're targeting. 对于您正在使用的其他库,例如SDL和OpenGL,您需要针对您所针对的相同CRT编译的那些库的版本。 If you have the source code for the libraries, then you can just compile them yourselves. 如果你有库的源代码,那么你可以自己编译它们。

Here are instructions for compiling SDL for Cygwin. 以下是为Cygwin编译SDL的说明 For OpenGL, there are a bunch of packages you can install via Cygwin setup for getting OpenGL header files and libraries, eg the libEGL-devel , libGL-devel , libGLU-devel , libglut-devel , and libGLw-devel packages. 对于OpenGL,您可以通过Cygwin设置安装一堆软件包来获取OpenGL头文件和库,例如libEGL-devellibGL-devellibGLU-devellibglut-devellibGLw-devel软件包。

I highly recommend against it. 我强烈建议不要这样做。 You will definitely hit binary incompatibilities and many other subtle issues during linking stage and most importantly at runtime. 在链接阶段,最重要的是在运行时,您肯定会遇到二进制不兼容问题和许多其他细微问题。 Every toolchain has its purpose, so use what fits your requirements better. 每个工具链都有其用途,因此请更好地使用符合您要求的工具。

  • Willing to give up platform dependent functionality (direct usage of POSIX in your code)? 是否愿意放弃平台相关功能(在代码中直接使用POSIX)? Then eliminate it and go for MinGW-w64 . 然后消除它并去MinGW-w64
  • No? 没有? You have no choice, but to use Cygwin and the GCC toolchain that comes with it. 您别无选择,只能使用Cygwin及其附带的GCC工具链。 By the way they recently introduced 64-bit (x64) version of Cygwin (and the accompanying GCC toolchain) which works very well. 顺便说一句,他们最近推出了64位(x64)版本的Cygwin(以及随附的GCC工具链),效果非常好。

To me both approaches look fine. 对我来说两种方法看起来都很好 Cygwin's translation overhead is really minimal, and you don't have to distribute the whole Cygwin for your application to work, but just the runtime DLLs. Cygwin的翻译开销实际上是最小的,并且您不必为您的应用程序分发整个Cygwin,而只需要运行时DLL。 Nevertheless, personally, I think that modern cross-platform applications should struggle to be truly cross-platform and not use directly such low-level API as POSIX as this is actually a flaw of the application in the first place which claims to be cross-platform. 不过,就个人而言,我认为现代跨平台应用程序应该很难真正实现跨平台,而不是直接使用像POSIX这样的低级API,因为这实际上是应用程序的一个缺陷,它首先声称是跨越平台。 And thank god, today we have plenty of modern and high-quality libraries to help us with that. 感谢上帝,今天我们有大量现代化和高质量的图书馆来帮助我们。 For instance, in my projects I always stick to the first approach, and so far I have to admit that it's always possible, but sometimes just requires some hassle which you shouldn't be scared of as it will definitely pay off in the future. 例如,在我的项目中,我总是坚持第一种方法,到目前为止我不得不承认它总是可行的,但有时候只需要一些你不应该害怕的麻烦,因为它肯定会在未来得到回报。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM