NetCDF Port using MinGW: Native Windows 64 bit (and 32 bit) DLL

Introduction

There is a demand for using NetCDF library as a native Windows DLL. Here, here, and here are some recent user requests for that. However, the current support of the Windows platform is very limited: basically the only reliable options are to use CygWin that unfortunately does not support 64 bit applications, or to use Java that is not always an optimal solution. Therefore, an ability to read and write netcdf files under Windows 64 bit using a C compiler is an important issue for the users of the NetCDF library. This is a documentation of the work making it possible with some reasonable limitations under MinGW/MinGW-w64.

What is achieved at the moment

The NetCDF library version 4.1.3 does compile under both 32 and 64 bit Windows using MinGW and MinGW-w64 and does successfully pass all standard tests included in the source code distribution. Here are the links to the ‘make check’ output of both 32 and 64 bit versions.

Current limitations

The library is configured for the compilation in a rather minimalistic way that does not include: Fortran and C++ interfaces (just only C), hdf5 (aka netcdf-4), old version 2 of the API, and DAP. Both the NetCDF classic format that is the default format for all versions of NetCDF and the 64-bit offset format are fully supported. There is hope that the porting approach suggested below can be used to compile a full-fledged version.

Known Issues

The MinGW library build seems to be a bit slower than the CygWin one. Just for an indication, reading the same big file (about 4GB) on the same machine under Cygwin takes 27.31 sec whereas using MinGW build it takes 33.55 sec. The problem might be due to the I/O buffer size definition that becomes active when compiling under MinGW in posixio.c file: POSIXIO_DEFAULT_PAGESIZE 4096 (I have noticed that CygWin is using 64K page size). Using explicit buffer size specification in nc__open() instead of nc_open() helped a bit, but did not fix the problem entirely. I did not investigate the problem further and did not try to recompile the library redefining POSIXIO_DEFAULT_PAGESIZE (I am not sure if it will help).

Precompiled Binaries and Source Code

As it is always easier to try and test the precompiled binary before going into building from the source, here are the links to the 32 and 64 bit compiled versions (zip files along with the source code). The compiled 64 bit DLL and static link libraries are located in “liblib\.libs\”, and the compiled standard tests are in “nc_test\”. The compiled 32 bit DLL and static link libraries are located in “netcdf-4.1.3-mingw-nik-out”, the compiled standard tests are not included to reduce the zip size. When compiling your application, you need to include before netcdf.h the nik-long64bit.h file (for compiling under 64 bit) or nik-long32bit.h file (for compiling under 32 bit); both files are already included in the source code zip files. Here are also the links to the MinGW and MinGW-w64 web sites. In order to be able to use the configure script you need to install MSYS accessible though MinGW web site (the 32 bit version of MSYS is fine to build 32 and 64 bit versions of the library). Here is an export command and configure settings needed to compile the library (to be issued in bash) change paths to fit your setup:

1)      Include one additional header to any netcdf source file being compiled:
$ export CFLAGS='-include g:/tmp/netcdf-4.1.3-mingw-nik/nik-long64bit.h'

2)      Configure the library, for now in a minimalistic way:
$ ./configure --prefix=g:/tmp/netcdf-4.1.3-mingw-nik-out --enable-dll --disable-fortran --disable-cxx --disable-netcdf-4 --disable-fsync --disable-cdmremote --disable-dap --disable-v2 --enable-largefile --enable-large-file-tests --with-temp-large=d:/temp --with-gnu-ld

For further details on how to build the library please refer to the official NetCDF documentation.

Changes in the Original Source

The following changes have been made to the original NetCDF version 4.1.3 source code in a semi-automatic mode, the order does matter:

1)      replaced "long long" to "niklonglongmy" in all netcdf source files

2)      replaced "long" to "niklongmy" in all netcdf source files

3)      replaced "off_t" to "nikoff_tmy" in all netcdf source files

4)      replaced "lseek" to "niklseekmy" in all netcdf source files

5)      replaced "fstat" to "nikfstatmy" in all netcdf source files

6)      replaced "struct stat" to "struct nikstatmy" in all netcdf source files

7)      replaced “signed char vals[DIM2]” with “static signed char vals[DIM2]” in the file tst_large.c

Here are the comments on why these changes were necessary. Items 1-2 are to resolve the problem of “long” type being 64 bit on Unix and still 32 bit on any Windows (both 32 and 64 bit). For more details, please see this and that. Items 3-6 are to resolve the problem of correct positioning in large files as in MinGW/MinGW-w64 all of off_t, lseek, etc., assume 32 bit offset/file size. Item 7 is a trivial fix of an array being too big to fit into the stack – just made it static.

Nikolay Khabarov
2012-04-12