Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linking with cygwin1.dll while building with mingw32?

I wish to port a Linux C++ application to Windows with the minimum possible effort (i.e. no code modifications at all, and no entirely new build system).

The application is mainly doing API calls to SDL and OpenGL, which both are available on Windows. However, it also uses POSIX functionality such as ptys, which are preventing me from using the mingw32 toolchain.

Cygwin, or, more precisely, cygwin1.dll, implements the whole POSIX API and internally translates it to 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).

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. 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.

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)?

Licensing is not an issue.

like image 496
mic_e Avatar asked Feb 14 '23 10:02

mic_e


1 Answers

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. The MinGW toolchain uses the Microsoft CRT, while the Cygwin GCC toolchain uses the Cygwin CRT.

Each of these two CRTs is implemented differently. Take the malloc() function, for example. 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. 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.

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. 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.).

Your understanding about Win32 is wrong -- you can make calls to the raw Win32 API from Cygwin programs. The Cygwin GCC toolchain even comes with its own <windows.h> header file. There are no restrictions against calling functions like CreateFile, VirtualAlloc, etc.

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. If you have the source code for the libraries, then you can just compile them yourselves.

Here are instructions for compiling SDL for Cygwin. For OpenGL, there are a bunch of packages you can install via Cygwin setup for getting OpenGL header files and libraries, e.g. the libEGL-devel, libGL-devel, libGLU-devel, libglut-devel, and libGLw-devel packages.

like image 188
Adam Rosenfield Avatar answered Feb 17 '23 00:02

Adam Rosenfield