Title: MinGW Support in Cygwin
Author: Jon Leichter, jon@symas.com
Last Modified: $Date: 2002/01/06 05:25:07 $
NOTE: This document has been written to aid individuals in setting up MinGW
support within the Cygwin environment. This document is based on my personal
experience and is not guaranteed to be correct or the best solution. This
document has not been endorsed by the maintainers of Cygwin or MinGW.
Cygwin Introduction
From
Red Hat's Cygwin Home Page:
Cygwin is a UNIX environment for Windows. It consists of two parts:
- A DLL (cygwin1.dll) which acts as a UNIX emulation layer providing
substantial UNIX API functionality.
- A collection of tools, ported from UNIX, which provide UNIX/Linux
look and feel.
The Cygwin DLL was developed and maintained by a company called Cygnus,
which is now a part of Red Hat. The Cygwin DLL is freely available, but
its use has restrictions imposed by the GNU Public License (GPL).
The Cygwin DLL achieves its UNIX emulation layer by exporting various POSIX
functions and global variables that one would find in various UNIX
libraries, e.g. C, socket, etc. Under the covers, the Cygwin DLL is
implemented with native Win32 API calls. Since the Cygwin DLL provides a
set of POSIX functions, the source of an application could be coded to
call these POSIX functions instead of the functions from the Windows C run-time
library. Typically, one would want to take advantage of this layer if he
were compiling source code that had been written specifically for UNIX.
Cygwin GCC is a complete compiler suite capable of producing binaries that
depend on the Cygwin DLL. Cygwin GCC is packaged with POSIX header files
and various libraries. One of the libraries, libcygwin.a, is (mostly) an
import library, whose symbols are implemented by the Cygwin DLL. As of
this writing, the Cygwin DLL does not have stable support for multi-threaded
binaries.
Sometimes, one might need support for functions found only in the Win32 API.
Cygwin GCC also supports the Win32 API and comes with Win32 API header files
and import libraries.
With the existence of Cygwin GCC, it's easy to generate various UNIX-like
tools and packages as "cygwin" binaries, e.g. bash, cvs, diff, gdb, grep,
make, nm, perl, sed, sh, tcsh, vi, etc. Fortunately, people in the OpenSource
community have already gone through the trouble to create these "cygwin"
binaries. The Cygwin DLL, Cygwin GCC, and a collection of "cygwin" UNIX-like
tools and packages all constitute the Cygwin Environment. The Cygwin
Environment is distributed as a complete package that one can install for
free from
Red Hat's Cygwin web site.
Because the Cygwin DLL is a substitute for the Windows C run-time library,
it is able to provide special features specific to Windows:
- CR-LF to LF translation, and vice versa
- Path separator translation, i.e. forward slash (/) to backslash (\),
and vice versa
- Disk drive translation, e.g. c: -> /cygdrive/c
- Symbolic link support
Cygwin binaries can be executed from any shell, as long as the Cygwin DLL
is in the current directory or is accessible via the environment's PATH
variable. Typically, one uses the "cygwin" bash shell and executes
other "cygwin" binaries from there. The "cygwin" bash shell gives the
user a UNIX look and feel and provides a flexible development
environment. Furthermore, "cygwin" binaries, like bash, are the only
binaries that take advantage of the special translation features.
MinGW Introduction
MinGW stands for "Minimalistic GNU for Windows". MinGW used to be called
Mingw32. The "32" has been removed to prevent an implication that MinGW
only supports 32-bit architectures. MinGW will move forward to support
64-bit and higher architectures.
MinGW is merely the name of another target recognized by a particular flavor
of GCC: MinGW GCC. There is nothing special about this compiler suite. It
includes Win32 API header files, generates x86 object code, and defers
run-time linking by using Win32 import libraries. Basically, it's a free
compiler suite that builds Win32 binaries, which might be referred to as
"mingw" binaries. The distinction between "mingw" and Win32 is that the
binaries were created by MinGW GCC, as opposed to a commercial compiler
system for Windows. MinGW binaries depend only on the DLLs provided by
the Windows operating system.
While there is no such thing as a MinGW environment, there is a collection
of "mingw" binaries that have been ported. As such, it is possible to
download a MinGW distribution, which includes MinGW GCC and a set of other
useful development tools. The MinGW distribution does not contain shell
binaries, which is why there is no "environment" to speak of. One can execute
"mingw" binaries from any shell. One might want to execute "mingw" binaries
from a "cygwin" bash shell. More about this is discussed in
Generating MinGW Binaries in a Cygwin Environment.
The MinGW distribution can be obtained for free by visiting the
MinGW web site.
Differences between Cygwin and MinGW binaries
It can be very easy to get confused about these two GCC targets. The binaries
for both targets are produced by GCC and execute in the Windows environment.
There are, however, significant differences that are important to understand:
- MinGW binaries depend only on the Windows C run-time DLL and
Win32 DLLs. Cygwin binaries depend on the Cygwin DLL and sometimes
Win32 DLLs. The Cygwin DLL acts as a replacement for the Windows C
run-time library.
- Because the Windows C run-time library is substituted, Cygwin
binaries support CR-LF, path separator, disk drive, and symbolic
link translations. MinGW does not.
- Cygwin binaries have access to a POSIX library and Win32 libraries.
MinGW only has access to the Windows C run-time library and Win32
libraries.
One should use Cygwin GCC when he:
- wants to develop or port a UNIX tool or application to the Windows
environment without altering too much UNIX-specific source.
- wants to utilize the benefits of CR-LF, path separator, disk drive,
and symbolic link translations.
- accepts that multi-threaded binaries are not completely stable.
- accepts that he must distribute his source code since he is required
to do so by the GPL.
One should use MinGW GCC when he:
- wants to develop Windows software with a free compiler suite.
- wants to port a UNIX tool or application to the Windows environment,
recognizing that he will have to alter UNIX-specific source code into
Windows-compatible source code.
- wants to produce stable multi-threaded binaries.
- does not want to be restricted by the GPL.
Generating MinGW Binaries in a Cygwin Environment
Many times, a UNIX-based source distribution comes with 'sh' shell scripts
that are essential to the build process. The MinGW distribution does not
provide an 'sh' binary, nor does it provide various other binaries that are
likely to be called by a shell script. The Cygwin Environment does provide
the 'sh' binary as well as just about any other binary a shell script is
likely to invoke. For this reason, it is often useful to have Cygwin binaries
accessible via the PATH environment variable.
A shell script can execute in a Windows command shell as long as the
"cygwin" shell binary is explicitly invoked and the Cygwin DLL is in the
current directory or is accessible via the PATH environment variable. Of
course, if the shell script calls any other "cygwin" binaries, those binaries
must also be accessible via the PATH environment variable. The easiest way
to ensure that "cygwin" binaries are accessible is to operate from the Cygwin
bash shell. The Cygwin bash shell ensures that "cygwin" binaries are
accessible by setting the PATH environment variable appropriately. When a
command is typed in the Cygwin bash shell, the shell will check to see if
the command is a binary file or a shell script and execute it accordingly.
This advantage is not available with a Windows command shell.
When one wants to generate binaries with GCC, he can do so from any
command shell. The Cygwin bash shell is the preferred choice because of
the advantages that it brings. The Cygwin bash shell can be used to
generate both "cygwin" and "mingw" binaries. When one wants to generate
"mingw" binaries from the Cygwin bash shell, he can do so using one of
these methods:
- Run MinGW GCC from the Cygwin bash shell.
- Run Cygwin GCC from the Cygwin bash shell, and supply the
-mno-cygwin switch.
The second method is possible because the original developers of Cygwin
recognized the need to produce MinGW binaries from a Cygwin Environment.
Cygwin GCC recognizes both "cygwin" and "mingw" targets. Cygwin binaries
are generated by default. MinGW binaries are generated by passing the
-mno-cygwin flag to GCC.
The second method is more useful than the first. The tools in Cygwin GCC are,
themselves, "cygwin" binaries. The tools in MinGW GCC are, themselves,
"mingw" binaries. As such, only the Cygwin GCC tools receive the special
translations support provided by the Cygwin DLL.
To better understand the Cygwin DLL advantage, consider the following
example: many times, shell scripts create symbolic links to files and
specify those symbolic links to compiler tools as parameters, e.g.
GNU Libtool. If a shell script were to provide a symbolic link to any tool
in MinGW GCC, the tool would fail. As a "mingw" binary, the tool would be
unable to resolve the symbolic link. A symbolic link is a special file that
only the Cygwin DLL is capable of creating and interpreting. Thus, if a
symbolic link were specified to a "cygwin" binary, it would be able to
interpret the link and follow it to open the correct real file.
Using the -mno-cygwin switch with Cygwin GCC in a Cygwin bash shell is the
best way to generate "mingw" binaries. The rest of this document focuses
on this method.
Cygwin GCC and the MinGW Target
The modes of Cygwin GCC are controlled by its specs file.
NOTE: The following information is based on the latest net release version
of Cygwin at the time of this writing, v1.3.6, which includes Cygwin
GCC 2.95.3-5.
Without any switches, Cygwin GCC operates in default mode, in which case it
will generate "cygwin" binaries. In this mode, GCC does the following:
- The preprocessor defines default GCC-specific macros.
- The preprocessor defines default Cygwin-specific macros:
- __CYGWIN32__
- __CYGWIN__
- unix
- __unix__
- __unix
- The preprocessor searches default directories for header files
in the following order:
- /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5/include
(the GCC-specific include directory)
- /usr/include (the Cygwin-specific include directory)
- /usr/include/w32api (the Win32-specific include directory)
- The compiler generates x86 object code.
- The linker searches default directories for libraries, in the
following order:
- /usr/lib (the Cygwin-specific lib directory)
- /usr/lib/w32api (the Win32-specific lib directory)
- /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5
(the GCC-specific lib directory)
- /usr/lib, /lib (the default hard-coded lib directories of GCC)
- When the linker searches for DLLs to link with, the prefix "cyg"
is applied to a library's basename.
- The linker links with default libraries, in the following order:
- gcc (the default GCC-specific library)
- cygwin (the default Cygwin-specific library)
- user32, kernel32, advapi32, shell32
(default Win32-specific libraries)
- gcc (second pass of the default GCC-specific library)
- The linker includes a default startup file:
- /usr/lib/crt0.o (for console binaries)
- The linker specifies a default entry point:
- _mainCRTStartup (for console binaries)
- __cygwin_dll_entry@12 (for DLLs)
When the -mno-cygwin switch is specified, Cygwin GCC will generate "mingw"
binaries. In this mode GCC does the following:
- The preprocessor defines default GCC-specific macros.
- The preprocessor defines default MinGW-specific macros:
- __MSVCRT__
- __MINGW32__
- WIN32
- WINNT
- _WIN32
- __WIN32
- __WIN32__
- The preprocessor searches default directories for header files
in the following order:
- /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5/include
(the GCC-specific include directory)
- /usr/include/mingw (the Mingw-specific include directory)
- /usr/include/w32api (the Win32-specific include directory)
- The compiler generates x86 object code.
- The linker searches default directories for libraries, in the
following order:
- /usr/lib/mingw (the MinGW-specific lib directory)
- /usr/lib/w32api (the Win32-specific lib directory)
- /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5
(the GCC-specific lib directory)
- /usr/lib, /lib (the default hard-coded lib directories of GCC)
- When the linker searches for DLLs to link with, the prefix "cyg" is
applied to a library's basename.
- The linker links with default libraries, in the following order:
- mingw32 (the default MinGW-specific library)
- gcc (the default GCC-specific library)
- moldname (the default library that supports old symbol names)
- msvcrt (the default import library for Windows C run-time
library)
- mingw32 (second pass of default MinGW-specific library)
- user32, kernel32, advapi32, shell32
(default Win32-specific libraries)
- mingw32 (third pass of default MinGW-specific library)
- gcc (second pass of the default GCC-specific library)
- moldname (second pass)
- msvcrt (second pass)
- The linker includes a default startup file:
- /usr/lib/mingw/crt2.o (for console or windows binaries)
- /usr/lib/mingw/dllcrt2.o (for DLLs)
- The linker specifies a default entry point:
- _mainCRTStartup (for console binaries)
- _WinMainCRTStartup (for windows binaries)
- _DllMainCRTStartup@12 (for DLLs)
At first glance, it may look like Cygwin GCC does all of the right things.
As a matter of fact, it does MOST of the right things. Unfortunately, it
does some things wrong:
- Generic GCC is hard-coded to always look in /usr/lib and /lib when
searching for libraries. This is a problem when using "mingw" mode
because Cygwin libraries are installed in /usr/lib. The linker
should never search in the Cygwin-specific lib directory when
linking "mingw" binaries. However, since the Cygwin-specific
lib directory is the same directory as one of GCC's hard-coded
directories, this has the potential to happen and cause problems.
- Whether in "cygwin" or "mingw" mode, Cygwin GCC's linker adds the
"cyg" prefix to DLL basenames during its library search phase.
This should not happen in "mingw" mode.
The solution to the first problem involves moving files around and fixing
GCC's specs file. The solution to the second problem is a simple fix to
the specs file.
Installing and Configuring Cygwin
Red Hat's Cygwin web site
contains complete details for installing and configuring Cygwin. Here are
some useful tips:
- The latest version of Cygwin's setup.exe program, v2.125.2.10,
forces the user to pick and choose the set of packages to install.
This is a problem because if the user takes too much time to make
this selection, the setup.exe program will lose its connection to
the FTP server that it had previously opened. The default package
set is not suitable for a full development environment. One easy way
to avoid these problems is to merely install all packages. There is
no easy way to do this either. The user must quickly select every
package before the FTP connection times out. If the user can manage
to pick and choose, the following packages are required and/or
recommended for a complete development environment: ash, autoconf,
automake, bash, binutils, bison, byacc, bzip2, clear, cpio, crypt,
ctags, cvs, cygutils, cygwin, diff, file, fileutils, findutils,
flex, gawk, gcc, gdb, grep, groff, gzip, indent, less, libintl,
libintl1, libncurses5, libncurses6, login, m4, make, man,
mingw-runtime, mktemp, ncurses, newlib-man, openssh, openssl, patch,
perl, readline, regex, sed, sh-utils, sharutils, tar, tcsh, termcap,
terminfo, texinfo, textutils, time, unzip, vim, w32api, which, zip,
zlib.
- When setup.exe gives you the option for DOS or UNIX mount points,
you should select DOS mount points. DOS (i.e. textmode) mount
points provide the most usable development environment.
- Using the Windows interface to set environment variables, create an
environment variable called CYGWIN and set its value to "nobinmode".
Make sure that you set this in the Windows environment so that this
variable is set whenever a new shell is spawned. This value tells
Cygwin to use textmode in system pipes.
- Do not use Cygwin's default shortcut icon to start Cygwin's bash
shell. It's use can generate an annoying message in Windows 2000.
Instead, create your own shortcut icon with the following
parameters:
- Set the 'Target:' field to
"<cygdir>\bin\bash.exe --login -i", where <cygdir>
is the fully qualified DOS path where Cygwin is installed.
- Set the 'Start in:' field to "<cygdir>\bin", where
<cygdir> is the fully qualified DOS path where Cygwin
is installed.
- When Cygwin installs, it will try to run mkpasswd.exe to generate
an /etc/passwd file. If this worked successfully, your home
directory should be appropriately specified in this file. When
you start the Cygwin bash shell, it will cd to your $HOME
directory. Make sure this is working right.
- In your $HOME directory, create a .vimrc file, and set the first
line to "se ffs=dos,unix". This setting will ensure that the
correct end-of-line sequence is used when you edit text files
with vi.
- Take the time to create a .bashrc file in your $HOME directory to
make the shell fit your needs. If you need to, you can get a man
page on bash by executing "man bash".
Fixing MinGW Support
NOTE: The following information is based on the latest net release version
of Cygwin at the time of this writing, v1.3.6, which includes
Cygwin GCC 2.95.3-5.
NOTE: The following will fix MinGW support for GCC's C compiler. It will
not necessarily fix MinGW support for the C++ compiler, (but it might).
Fixing Cygwin GCC's MinGW support means:
- relocating Cygwin-specific libraries
- fixing GCC's specs file to find the relocated Cygwin-specific
libraries
- fixing GCC's specs file to not use the "cyg" prefix when searching
for DLLs in "mingw" mode
To relocate Cygwin-specific libraries, start the Cygwin bash shell, and
execute the following commands:
$ cd /usr/lib
$ mkdir cygwin
$ mv lib* cygwin
$ mv *.dll *.o cygwin
Save these GCC specs patches to a file,
e.g. /tmp/patches-gcc-specs.txt, and execute the following:
$ cd /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5
$ mkdir save
$ cp specs save
$ patch -i /tmp/patches-gcc-specs.txt
Cygwin's GCC support for MinGW should now be fixed. There is one task
remaining. You should create a wrapper script for starting GCC with the
-mno-cygwin switch. The reason for this is because some build scripts "try"
to be intelligent and strip off compiler switches that are "not essential"
to the build, e.g. GNU Libtool. If libtool is invoked in link mode with
the -mno-cygwin switch, it will strip this switch, and the final link step
will not be what you expected. A wrapper script will avoid this problem.
To create the wrapper script, start the Cygwin bash shell, and execute
the following:
$ cd /usr/bin
$ cat > mgcc
#!/bin/sh
gcc -mno-cygwin $*
^D
Now you can invoke Cygwin GCC in "mingw" mode by merely using the mgcc
command. Remember that if you want to use "mingw" mode when you build source
distributions, you will likely have to set the CC environment variable
to "mgcc".
hyc@highlandsun.com, jon@symas.com |