Cygnal Frequently Asked Questions

1. Why not just use MinGW? Isn't that what everyone uses for making native Windows executables with GCC?

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.

2. Isn't MinGW more native because it doesn't require a DLL?

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.

3. How about the newer MinGW-W64?

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_OK
    
Lo and behold, the message box appears, with the text "Hello", and the window title "World".

4. What support is there for Cygnal?

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.