Paul Cochrane bio photo

Paul Cochrane

Twitter LinkedIn Github

Recently a PhD student at the institute where I work wanted to use make and gfortran on a Windows box without having to install Cygwin in order to compile a Fortran program she had been given by another scientist. A good (and free) alternative to Cygwin is MinGW, however installing and using it used to be a complicated and relatively painful experience. After I investigated this option again after a having not done so for a while, I found out that this is no longer the case: MinGW now comes with its own package management system! The installation is now relatively pain less. So, if you are restricted to a Windows environment and you need to develop, maintain or just plain compile and use legacy scientific software and you don’t want to have to use Cygwin, it’s definitely worth your while checking out MinGW.

Contents

tl;dr

MinGW (Minimalist GNU for Windows) now comes with a package manager, so it’s easy to install natively running GNU C/C++ and Fortran compilers along with Unix-like software development tools on Windows.

Cygwin vs MinGW

Why not use Cygwin? Well, one big difference is performance: Cygwin emulates a POSIX environment on top of Windows so that Unix-like (i.e. Linux, FreeBSD and their ilk) programs can run in their normal manner. This emulation means that some processing power is used in converting Unix-like operations into Windows-specific operations. With MinGW this isn’t the case, since the Windows-specific operations are called directly (sacrificing some POSIX compatibility) and thus one can achieve more performance.

For more information on this topic, have a look at the comparison of MinGW with Cygwin.

Goal: compile and run a small Fortran simulation program

To see how MinGW can be used to build and run legacy scientific programs, let’s go through the process of installing MinGW with the goal of compiling and running a Fortran code.

The program we’re going to install is from Prof Eli Tziperman’s homepage at the Department of Earth and Planetary Sciences within the School of Engineering and Applied Sciences at Harvard University. Specifically, we’re going to install the “simple barotropic/ reduced gravity 1.5 layers QG model” from Prof Tziperman’s “etc” page. The tar file (which can be extracted using 7zip) can be downloaded directly from: QG200205011455.tar.gz.

Why did I choose this program? Well, it’s small in terms of source lines of code, it’s packaged as a tar file, the package contains a Makefile, the programming language is Fortran (commonly found in legacy scientific programs) and hopefully it’s interesting from a scientific point of view[1]. Thus it’s more likely something that a PhD student, postdoc or researcher is going to find “in the wild”, and brings together multiple aspects of building a project and the associated problems which can be encountered in doing so without encountering too many such problems.

But first, let’s install MinGW.

Installing MinGW

Go to the Getting Started page on the MinGW wiki and download the file mingw-get-setup.exe. As of this writing, this is still the version from late 2013, but still delivers a reasonably recent version of the gcc and gfortran compilers.

After downloading mingw-get-setup.exe, double click on its icon to start the installation process. The following window should appear:

welcome_window

Click on the Install button in order to start the installation process. First you’ll be asked to set some installation preferences.

installation_preferences

Since the defaults are good enough (unless you want to install somewhere other than C:\ or you want to install for all users on your system, in which case be careful to not use any spaces in path names) we’ll simply click on Continue and the download and setup of the MinGW Installation Manager (what I’ll also refer to as “package manager”) starts:

download_setup

After a while (depending upon your internet connection speed) the download and setup will finish:

download_setup_finished

After clicking on Continue; the MinGW Installation Manager appears.

installation_manager

In order to select packages to install, click on the box to the left of the package name, and then choose “Mark for Installation” in the menu which appears. In our case, we need to install the mingw-developer-toolkit, mingw32-gcc-fortran and mingw32-gcc-g++ packages, so mark each of these for installation.

base_packages_selection

Now go to the Installation menu item and select the Apply Changes subitem. A window will appear showing the actions about to be applied (there should be quite a few (over 100)).

pending_actions_schedule

Click on the Apply button to start the installation. First the packages will be downloaded.

package_download_window

After all packages have been downloaded and the changes have been applied, you should see that it is now Ok to close the dialog box.

installation_end_window

Simply click on the Close button to close the window and return to the package manager.

This completes the installation of the required software, however we need to do some configuration before we can use it easily.

Configure the msys shell

The msys shell provides a fairly complete Unix-like command line shell environment in order for you to run command line programs such as make (used to build programs), gcc (the GNU C/C++ compiler) and gfortran (the GNU Fortran compiler). First we need to set a couple of things up so that we can access the msys shell from the Windows Start Menu.

Correcting fstab

Assuming you installed MinGW under C:\, navigate, using Windows Explorer, to the folder C:\MinGW\msys\1.0\etc. Copy the file fstab.sample, and rename the copy to simply fstab (also tell Windows that it can safely do this if it complains). Now open the file in an editor such as Notepad++. Remove the line about ActiveState Perl and change the line

c:/mingw    /mingw

to

c:\MinGW    /mingw

ensuring that there is an empty line at the end of the file (these recommendations are adapted from the “After Installing You Should …” instructions on the MinGW Getting Started wiki page. Save fstab and quit Notepad++.

Creating the Start Menu shortcut for the msys shell

Now go to the folder C:\MinGW\msys\1.0 and select the Windows Batch File named msys.bat (it will appear as merely msys in Windows Explorer, but be of type Windows Batch File). Right click on the file and select Create shortcut from the context menu. Rename the shortcut to msys Shell. Cut the shortcut from the folder by right-clicking on it and selecting Cut from the context menu.

We now want to paste this shortcut into the Start Menu under “Programs”. Click on the Start Menu icon and right-click on the All Programs item. Now select Open from the context menu which appears. You should now be directed to the folder where the Start Menu items for all programs are held. Go into the Programs folder in the window displayed and paste the shortcut into the folder by right-clicking in the folder window and selecting Paste from the context menu. You should now find that an item named msys Shell has appeared under the All Programs section of the Start Menu.

To verify that everything works as expected, start the msys shell by selecting its entry from the Start Menu. A window similar to this should appear:

msys_shell

By running the commands make, gcc, gfortran in the shell, we see that they are available (the give errors since we’ve not given them any input; we only wanted to make sure that our shell can find and run them).

msys_commands_found

Congratulations! You’ve installed and configured MinGW on your computer! Now go and grab yourself your favourite beverage and relax a bit before continuing.

Building the QG program

In order to build and run the QG program, we need to download and extract it. Let’s do that now.

Downloading and extracting the project files

Download the tar file (QG200205011455.tar.gz) containing the program code and copy it into your MinGW home directory, which should be under C:\MinGW\msys\1.0\home\<your username>. This is the directory in which your msys shell session will start (and is the reason we’re copying this file here). If you run the “list directory” (ls) command inside your msys shell you should see the file QG200205011455.tar.gz appear in the output (the $ denotes the shell prompt):

$ ls
QG200205011455.tar.gz

This is a tar-gzipped file which can be extracted by using the tar command:

$ tar -xvzf QG200205011455.tar.gz

The x option means “extract”, the v means print verbose information, z means that the file is gzip compressed (hence the gz file ending) and f tells tar which file to extract.

If you run the ls command again you’ll find that a directory named QG2002 has been created:

$ ls
QG2002 QG200205011455.tar.gz

Go into this directory by using the “change directory” (cd) command:

$ cd QG2002

Here you will see the project files. Run ls again to see them:

$ ls
helmholtz.f  input.data-dimensional  Output        qg.f      README
input.data   Makefile                parameters.h  qgplot.m

The files that are initially important to us are the Fortran source code files (*.f) and the Makefile. It is also a good idea to read the README at this point.

If you’re like me, then you’ll probably just type make at the command line to see if the project builds. Doing so gives the following output:

$ make
f77 -O3  qg.f helmholtz.f -o Output/a.out
make: f77: Command not found
make: ** [Output/a.out] Error 127

which is simply the msys shell trying to tell us that it can’t find the program f77 which was being run within make.

Correcting the Makefile

OK that means we need to fix something up in the Makefile. Coming across such issues is common when trying to build a legacy project such as this, which might not have been tested on many systems and thus might not be very portable. Please consider such issues when writing your own software! Especially if you give your code to other people!

The first correction we need to make in the Makefile is to correct the name of the Fortran compiler, as we obviously don’t have f77 installed, however we do have gfortran installed. Open the Makefile file with Notepad++ and replace f77 (in the FORTRAN variable declaration) with gfortran. Your Makefile should now look like this:

FORTRAN=gfortran
FLAGS= -O3
#FLAGS= -fbounds-check -g -O0 -W -Wuninitialized  # (-Wuninitialized only works with optimization)
SOLVER=helmholtz.f
#SOLVER=poisson.f

all:: Output/a.out

Output/a.out: qg.f ${SOLVER} parameters.h
	${FORTRAN} ${FLAGS} ${LIBS} qg.f ${SOLVER} -o Output/a.out

Please note that it is more common in Makefiles to use the variable FC (for Fortran Compiler) instead of FORTRAN, and thus this is the form you’re more likely to come across in other projects. Now run make again:

$ make
gfortran -O3  qg.f helmholtz.f -o Output/a.out

Since there are no errors in the output, and we see a file called a.out in the Output directory (go have a look!), we can conclude that everything has worked, at least to some degree (yay!).

If you try to double click on the a.out file, you’ll find that it won’t run (even though it theoretically can), so we still have some things to fix in the Makefile.

Please note that in the Unix-world the default program name for C/C++ and Fortran compilers is always a.out, so it wasn’t really necessary to specify the name other than to make sure the file ends up in the Output directory. Thus it could equally have been called something nicer (such as qg, maybe?) and not have repeated an already default name. Note also that the code Output/a.out appears multiple times within the Makefile. This is a violation of the DRY Principle (Don’t repeat yourself). These things are called “code smells” and are things you should be looking to reduce as much as possible in any software projects you are involved in.

Let’s replace the repeated code with a variable, which we’ll call PROG and to which we’ll assign the name of the output program Output/a.out. Note that in Makefiles, one references a variable by prepending a $ to the variable name and wrapping the name in (usually) parentheses, e.g. $(PROG). In the Makefile we have downloaded, variables are enclosed in braces, which isn’t a problem, but again, it’s not standard. Our Makefile should now look like this:

FORTRAN=gfortran
FLAGS= -O3
#FLAGS= -fbounds-check -g -O0 -W -Wuninitialized  # (-Wuninitialized only works with optimization)
SOLVER=helmholtz.f
#SOLVER=poisson.f

PROG = Output/a.out
all: $(PROG)

$(PROG): qg.f ${SOLVER} parameters.h
	${FORTRAN} ${FLAGS} ${LIBS} qg.f ${SOLVER} -o $(PROG)

Remove the file a.out either through the Windows Explorer or by running

$ rm Output/a.out

from the msys shell.

Now we can run make again to ensure everything still works as desired.

Let’s now give the output program a better name, maybe something which better reflects the fact that it involves a quasi-geostrophic model, so change the PROG variable from Output/a.out to simply qg. “But doesn’t that put the program in the wrong place?” I hear you say? Actually no. The program was designed to be run from the main project directory (see the README) and the location of the output files have been hard coded into the program, so everything will still work if we remove the Output part from the program name. In fact, by doing this, we now make it possible for us to start the program simply by double clicking on its icon in Windows Explorer, so this change is even better!

Your PROG line should now read:

PROG = qg

Notice how we made this change in one location? And notice that if we’d not put this name into a variable, that we’d have had to change the Makefile in three places? This is one of the advantages of “not repeating yourself”.

Run make again to build the program and you should find a file called qg.exe (from within the msys shell) or simply qg from within the Windows Explorer.

Running the QG program

You can run the simulation by typing the following command:

$ ./qg

however, you can simply just double click on the icon in Windows Explorer and the program will open its own window and will show you the output of the simulation:

simulation_running

The program takes a while to run, go grab a cup of your favourite hot beverage.

The output data appear in Output/output.dat. As the README states, this can be plotted with qgplot.m, a Matlab script, which you can either run in Matlab or Octave (Windows binaries for MinGW are available at Octave for Windows).

After running the plotting script you should see images similar to this one:

stream_function_and_vorticity

Conclusion

If you got all this way, thanks for hanging in there! You have now successfully installed MinGW and used it to build and run a legacy scientific program after having solved a couple of build configuration issues. Well done!

Yes, but what does the output mean? I don’t know! I just wanted to show you how to build a legacy program on Windows using the new awesome MinGW package manager :-)

I hope that now you have some of the tools necessary to make your work a little bit easier. Good luck!

Appendix

Configure the Windows command shell PATH

The Windows command shell can also be used to build and run programs.

If you start the Windows command shell (cmd.exe; go to the Start Menu and type in cmd in the Search programs and files input field) you’ll find that the programs we want (make: used to build programs; gcc: the GNU C/C++ compiler; gfortran: the GNU Fortran compiler) aren’t available:

commands_not_found

We need to make sure that the MinGW programs we installed are in the command shell’s path, and thus they can be found by the shell and hence be run. If you type the path command at the command line, you’ll find that an entry containing mingw doesn’t appear. Hence we need to extend the command shell’s PATH environment variable.

Go to the Start Menu, and open the Control Panel, select “System and Security” and then “System”. A window should have appeared which shows “basic information about your computer”. Click on the “Advanced system settings” on the left-hand side of the window. The “System Properties” window should appear.

system_properties

In this window click on the Environment Variables button. The “Environment Variables” window should now appear:

environment_variables

Ensure that the PATH entry is highlighted and then click Edit. The “Edit” dialog should now appear:

edit_path_variable_dialog

Assuming you installed MinGW under C:\MinGW you now need to append C:\MinGW\bin;C:\MinGW\msys\1.0\bin to any already present value in the Variable value: field. Note that multiple entries to the PATH variable are separated with a semicolon. Click on OK until all of the windows go away and start the command shell again. This time we see that make, gcc and gfortran are available.

commands_now_found

Now you can extract the project tar file, correct the Makefile, and build and run the program without having to use the msys shell.

Footnote

[1] the quasi-geostrophic equations are solved for an example input data set, generating information about the stream function and vorticity of the flow. Such models are used in oceanography and climatology simulations.