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.
-
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.
- Open a command line in your HPC Linux distro and load the PToolsWin module:
module load ptoolswin module list
- Create your NetCDF folder:
setenv NETCDFDIR ${HOME}/windows mkdir -p $NETCDFDIR cd $NETCDFDIR
-
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
-
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
- Move the NetCDF source code to a sub-folder:
mkdir src mv * src cd src
- 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.
-
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
-
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.
-
Open ${NETCDFDIR}/netcdf-4.1.3/src/libtool in a text editor.
- Scroll to the very bottom of the file and locate the line that begins with “postdeps=”
-
Remove any invalid -l flags from that line. For example, if you see -l -L/usr/local/..., change it to -L/usr/local/...
- Once you’re satisfied, save the file and run ‘make’ and ‘make install’ again.
-
- 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.
- 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.
-
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