NetCDF is a popular data format in the scientific computing community. ParaTools offers pre-compiled binary packages for Windows and instructions for compiling NetCDF 4.1.3 with the PToolsWin development environment.

Download

Cross-compile with PToolsWin

The following instructions assume that you are working from the command line in HPC Linux.

  1. ParaTools developed the PToolsWin development environment specifically for porting Linux applications to Windows. PToolsWin is distributed as part of HPC Linux. Download and install HPC Linux, either in a virtual machine or natively.

  2. Open a command line in your HPC Linux distro and load the PToolsWin module:

     

    module load ptoolswin
    module list
    

     

  3. Create your NetCDF folder:
    setenv NETCDFDIR ${HOME}/windows
    mkdir -p $NETCDFDIR
    cd $NETCDFDIR
    

     

  4. Download and extract the NetCDF 4.1.3 source code from Unidata to $NETCDFDIR:

    wget ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-4.1.3.tar.gz
    tar xvzf netcdf-4.1.3.tar.gz
    

     

  5. There’s a bug in NetCDF that prevents it from cross compiling. Fortunately, we’ve developed a patch. Download and apply  netcdf patch to the NetCDF source:

     

    wget https://www.paratools.com/Azure/NetCDF/paratools-netcdf-4.1.3.patch -O paratools-netcdf-4.1.3.patch
    cd netcdf-4.1.3
    patch -p1 < ../paratools-netcdf-4.1.3.patch
    

     

  6. Move the NetCDF source code to a sub-folder:
    mkdir src
    mv * src
    cd src
    

     

  7. NetCDF includes a configuration script that will automatically generate the makefiles we need. Configure NetCDF as follows. Be sure to type the whole command as one line:
    ./configure --prefix=${NETCDFDIR}/netcdf-4.1.3 --host=x86_64-w64-mingw32 --enable-dll --enable-shared --disable-netcdf-4 LDFLAGS="-Wl,--export-all-symbols,--enable-auto-import" CPPFLAGS=-DgFortran
    

     

    Let’s take a closer look at this command. We are executing the configure script according to the standard GNU build process. The –prefix flag tells the configure script where to install files after they are compiled. –host=x86_64-w64-mingw32 is very important because it tells the configure script to use the MinGW compiler instead of the default GNU compiler. Without this flag, NetCDF would build for Linux, not Windows. –enable-dll and –enable-shared tell configure that we want shared libraries and that those libraries should be Windows DLL files. We use the –disable-netcdf-4 flag to disable obsolete functionality. By setting the LDFLAGSenvironment variable we are passing flags directly to the program linker. -Wl,–export-all-symbols,–enable-auto-import tells the linker to automatically make all NetCDF functions and subroutines accessible to programs that link against the NetCDF DLLs. Without these flags, the DLL files will be created but your programs will not be able to link with them. Adding “-DgFortran” to CPPFLAGS is required when building with gfortran on Linux.

  8. Once the configure script is finished, build and install NetCDF. (!) If you have multiple cores in your machine, you can reduce compilation time by passing the ‘-j<ncpus>’ flag to make (e.g. ‘make -j4’).

    make
    make install
    

     

  9. Some versions of GNU Libtool insert invalid -l flags on the linker command line. If your build fails with something like this:

    ... cannot find -l-L/usr/local/pkgs/mingw-w64-bin_x86_64-linux_20110831/...
    collect2: error: ld returned 1 exit status

    then you will need to fix the postdeps line in libtool.

    1. Open ${NETCDFDIR}/netcdf-4.1.3/src/libtool in a text editor.

    2. Scroll to the very bottom of the file and locate the line that begins with “postdeps=”
    3. Remove any invalid -l flags from that line. For example, if you see -l -L/usr/local/..., change it to -L/usr/local/...

    4. Once you’re satisfied, save the file and run ‘make’ and ‘make install’ again.
  10. If everything went well you should see the following message:
    +-------------------------------------------------------------+
    | Congratulations! You have successfully installed netCDF!    |
    |                                                             |
    | You can use script "nc-config" to find out the relevant     |
    | compiler options to build your application. Enter           |
    |                                                             |
    |     nc-config --help                                        |
    |                                                             |
    | for additional information.                                 |
    |                                                             |
    | CAUTION:                                                    |
    |                                                             |
    | If you have not already run "make check", then we strongly  |
    | recommend you do so. It does not take very long.            |
    |                                                             |
    | Before using netCDF to store important data, test your      |
    | build with "make check".                                    |
    |                                                             |
    | NetCDF is tested nightly on many platforms at Unidata       |
    | but your platform is probably different in some ways.       |
    |                                                             |
    | If any tests fail, please see the netCDF web site:          |
    | http://www.unidata.ucar.edu/software/netcdf/                |
    |                                                             |
    | NetCDF is developed and maintained at the Unidata Program   |
    | Center. Unidata provides a broad array of data and software |
    | tools for use in geoscience education and research.         |
    | http://www.unidata.ucar.edu                                 |
    +-------------------------------------------------------------+

    If you do not see this message, review your commands for errors and try again.

  11. The final step is to link the DLL files from the bin directory to the lib directory:
    cd $NETCDFDIR/netcdf-4.1.3/lib
    ln -s ../bin/*.dll .
    

    This is necessary because Linux makefiles and build scripts expect program libraries to be in the lib directory, but Windows expects them to be in the same path as the program executables. Making the files accessible at both locations keeps both ends of the cross-compilation process happy.

  12. Here is what the NetCDF bin and lib folders look like after a successful compilation ($NETCDFDIR is /home/livetau/windows):

    [paratools07] 579 > ls
    bin  include  lib  share  src
    [paratools07] 580 > pwd
    /home/livetau/windows/netcdf-4.1.3
    [paratools07] 581 > ls
    bin  include  lib  share  src
    [paratools07] 582 > ls -l bin lib
    bin:
    total 5600
    -rwxr-xr-x. 1 livetau livetau 1823052 Mar 23 13:53 libnetcdf-7.dll
    -rwxr-xr-x. 1 livetau livetau  668674 Mar 23 13:53 libnetcdf_c++-4.dll
    -rwxr-xr-x. 1 livetau livetau 1239191 Mar 23 13:53 libnetcdff-5.dll
    -rwxr-xr-x. 1 livetau livetau    4334 Mar 23 13:53 nc-config
    -rwxr-xr-x. 1 livetau livetau  243830 Mar 23 13:53 nccopy.exe
    -rwxr-xr-x. 1 livetau livetau  381728 Mar 23 13:53 ncdump.exe
    -rwxr-xr-x. 1 livetau livetau  464561 Mar 23 13:53 ncgen3.exe
    -rwxr-xr-x. 1 livetau livetau  885521 Mar 23 13:53 ncgen.exe
    
    lib:
    total 4984
    lrwxrwxrwx. 1 livetau livetau      22 Mar 23 13:56 libnetcdf-7.dll -> ../bin/libnetcdf-7.dll
    -rw-r--r--. 1 livetau livetau 1996680 Mar 23 13:53 libnetcdf.a
    lrwxrwxrwx. 1 livetau livetau      26 Mar 23 13:56 libnetcdf_c++-4.dll -> ../bin/libnetcdf_c++-4.dll
    -rw-r--r--. 1 livetau livetau  806660 Mar 23 13:53 libnetcdf_c++.a
    -rwxr-xr-x. 1 livetau livetau  315174 Mar 23 13:53 libnetcdf_c++.dll.a
    -rwxr-xr-x. 1 livetau livetau    1090 Mar 23 13:53 libnetcdf_c++.la
    -rwxr-xr-x. 1 livetau livetau  411564 Mar 23 13:53 libnetcdf.dll.a
    lrwxrwxrwx. 1 livetau livetau      23 Mar 23 13:56 libnetcdff-5.dll -> ../bin/libnetcdff-5.dll
    -rw-r--r--. 1 livetau livetau 1262872 Mar 23 13:53 libnetcdff.a
    -rwxr-xr-x. 1 livetau livetau  233966 Mar 23 13:53 libnetcdff.dll.a
    -rwxr-xr-x. 1 livetau livetau    1308 Mar 23 13:53 libnetcdff.la
    -rwxr-xr-x. 1 livetau livetau     930 Mar 23 13:53 libnetcdf.la
    -rw-rw-r--. 1 livetau livetau   16212 Mar 23 13:53 netcdf_c++dll.def
    -rw-rw-r--. 1 livetau livetau   16952 Mar 23 13:53 netcdfdll.def
    -rw-rw-r--. 1 livetau livetau   11907 Mar 23 13:53 netcdffdll.def
    drwxrwxr-x. 2 livetau livetau    4096 Mar 23 13:53 pkgconfig
    [paratools07] 583 >

The NetCDF Windows DLL functions in exactly the same way as a Linux shared object library. Call NetCDF functions from your C, C++, or Fortran code just as before, and link against the DLL when you compile. Make sure that$NETCDFDIR/netcdf-4.1.3/include is in your compiler’s include search path (e.g. use the -I flag) and that$NETCDFDIR/netcdf-4.1.3/lib is in the linker path (e.g. use the -L flag). For example, you could modify your Makefile or set these environment variables before you compile:

setenv CPPFLAGS -I${NETCDFDIR}/netcdf-4.1.3/include
setenv LDFLAGS -L${NETCDFDIR}/netcdf-4.1.3/lib

msdevelLogo