A big reason, possibly the main one, to prefer Cygnal to MinGW is that the
C library used by MinGW, a library called MSVCRT.DLL
, is
actually an Windows internal component that is off-limits for application
use, according to Microsoft. This is covered in the next question.
Other reasons to prefer Cygnal to MinGW have to do with the quality
and scope of Cygnal as a C library. The aforementioned
MSVCRT.DLL
library contains a poor implementation of a small
subset of POSIX. Many functions are missing, such as fork
or
tcsetattr
. Some are just stubs, like stat
which
returns a struct stat
filled mostly with of dummy zero values,
instead of actual information like under Cygnal. Cygnal also provides
full bi-directional VT100/ANSI emulation over the console: programs
which use escape sequences to control the display will Just Work, right
out of cmd.exe
, without having to use the Console API.
Cygnal applications also enjoy real, POSIX-like signal handling.
Here is a kicker: large file support. Cygnal handles files larger than 2GB, even in the 32 bit version.
This is a harmful misconception. Firstly, all development suites for
Windows have run-time support, including Microsoft's Visual C and C++,
referred to here as MSVC. When you make an application with MSVC
(which is indisputably the canonical example of a 100% native Windows
application) and wish to distribute it, you must package it with the
matching MSVC redistributable run-time libraries: either in the
.dll
form or else statically linked into the executable(s)
using the /MT
linking option.
So what is this MSVCRT.DLL
in the Windows system folder?
Once upon a time, in the early 1990's, Windows engineers were developing
utilities for Windows itself using MSVC. Those utilities required
a run-time, so they took the MSVC run-time DLL, MSVCRT.DLL
,
and stuck it into Windows. Problem solved, right? Oops, wrong:
the run-time library in Visual C was a bit of a moving target and so
applications shipped with their own copies of it. Applications which
neglected to ship their own copy would accidentally link to the one in the
system, causing problems.
Visual Studio addressed the problem by essentially forking the library.
The redistributable run-time libraries were given different names, so that
programs built with MSVC will not accidentally link to the
system MSVCRT.DLL
. If they are shipped without the
right version of the redistributable run-time libs, they just won't
run.
The "straight dope" about it is found in this MSDN article.
So the current situation now, and for many years now, is that the
system MSVCRT.DLL
is undocumented and
off limits
to applications.
It is an internal Windows library for use by the
programs that ship as a part of Microsoft Windows, versioned separately
from the MSVC redistributable run-time.
MinGW programs wrongly rely on this library. Not shipping
with a library is not the right thing, not a good thing,
and isn't making MinGW programs "more native", since even
Windows programs developed using Microsoft tools
require run-time libs.
MinGW uses this library for one reason only: MinGW is used for
porting to Windows open-source programs which use the GPL license.
The GPL forbids linking against proprietary libraries (such as the
MSVC redistributable run-time) but has a special system library
exception. That exception in the GPL allows GPL-ed programs
to be linked against the MSVCRT.DLL
in the system
folder, exactly as it allows them to be linked aginst the
libc
in proprietary Unixes. But MSVCRT.DLL
is not like the libc
in Unixes: the libc
in Unixes is open for application linking and properly versioned
for that purpose. Microsoft can change MSVCRT.DLL
in any given update of Windows, and break programs that rely on it.
MinGW-W64 is a newer project different from the original MinGW, sharing the name only. It fixes the above disadvantages of MinGW in its own way. Unlike the original MinGW, it does have its own run-time support library. It is actively developed and has many features, but it is complicated. It provides a whole separate environment that has to be used as a porting target, and still a fork of Cygwin.
Cygnal is cleverly simple: just a small number of patches against
Cygwin, producing a modified DLL. Cygnal doesn't fork and mutate the
entire Cygwin environment. Cygwin's own native toolchain is used
directly to build a program as a Cygwin executable, which can then be
deployed with the
cygwin1.dll
from Cygnal.
Whether to use MinGW-W64 or Cygnal isn't a simple decision. The focus in MinGW-W64 seems to be to provide support for a large number of Windows API's, by providing header files for them. Some of the purported advantages of MinGW-W64 over the original MinGW are also advantages of Cygnal. For instance, 64 bit support.
Some developers like myself don't require a large number of Windows API's; I want to have a native Windows version of my cross-platform program that runs on Unixes. I want the POSIX interfaces which that program is using to take on a Windows flavor, where it makes sense, while having the option to use Windows interfaces.
The need for more Windows header files is not a good reason to fork off an entire project like MinGW-W64, in my opinion; such headers could be provided as a package under Cygwin. Cygwin has some coverage of the Windows API; that could be extended.
My program, for the sake of which I started Cygnal, is a dynamic
language which has a FFI (foreign function interface). With FFI,
I can use the language to attach to any Windows DLL and use
its functions without compiling any C code. That doesn't involve the use
of a C language header file, so I don't care whether or not I have a
header file for that particular API. For example, the language
executable doesn't link to user32.dll
at all.
Yet, from within the language, we can open user32.dll
and call MessageBox
, like this:
C:\Users\kaz>txr This is the TXR Lisp interactive listener of TXR 176. Use the :quit command or type Ctrl-D on empty line to exit. 1> (with-dyn-lib "user32.dll" (deffi messagebox "MessageBoxW" int (cptr wstr wstr uint))) #:lib-0172 2> (messagebox cptr-null "Hello" "World" 0) ;; 0 is MB_OKLo and behold, the message box appears, with the text "Hello", and the window title "World".
Cygnal is offered without a warranty or support. If you have an issue with Cygnal, please start a discussion in the mailing list. If the issue affects an application under Cygwin without the use of Cygnal, please contact the Cygwin project. That said, Cygnal doesn't keep up with every latest development in the Cygwin stream: users affected by a Cygwin issue that has been fixed upstream and not yet backported into Cygnal should contact the Cygnal mailing list.
Like Cygwin, Cygnal is open source, of course, and has a public Git repository. Patches are welcome—or, at least, good and reasonable patches; please post such to the mailing list.
Keep in mind that Patches which interfere with drop-in compatibility
between the Cygwin's cygwin1.dll
and the equivalent DLL in
Cygnal conflict with the scope and purpose of the Cygnal project, and
will almost certainly not be accepted.