pynetcdf and libnetcdf

Here is what I had to do to compile pynetcdf and libnetcdf to get an egg file.  It was really annoying.

cd $HOME/devextern # my directory for external codes

# get netcdf
wget "http://www.unidata.ucar.edu/downloads/netcdf/ftp/netcdf-4.1.2.tar.gz"
tar xzvf netcdf-4.1.2.tar.gz
cd netcdf-4.1.2 

# configure/compile netcdf 
./configure --prefix=$HOME --with-pic 
make
make install # this puts stuff in $HOME/lib $HOME/share $HOME/bin $HOME/include

# make sure it works
make check

# get pynetcdf
cd $HOME/devextern
wget "http://downloads.sourceforge.net/project/pylab/PyNetCDF/0.7/pynetcdf-0.7.tar.gz"
tar xzvf pynetcdf-0.7.tar.gz
cd pynetcdf-0.7
export NETCDF_PREFIX=$HOME

Now it gets really annoying.  The pynetcdf file is really quite old, and so I had to update it.  But first, we need to get the linking command for netcdf.

$HOME/bin/nc-config --libs

For me this was

-L/home/dfgleic/lib/lib -lnetcdf -lz -L/usr/kerberos/lib64 \
 -lcurl -ldl -lgssapi_krb5 -lkrb5 -lk5crypto \
 -lcom_err -lidn -lssl -lcrypto -lz

We want to compile pynetcdf with netcdf linked statically.  There is a bug in pynetcdf’s configure script with detecting the library.  Change the first “if” statement to:

if netcdf_prefix is None:
    test_prefix = []
    try:
        netcdf_prefix = os.environ['NETCDF_PREFIX']
        test_prefix.append(netcdf_prefix)
    except KeyError:
      
        pass
    test_prefix.extend(['/usr/local','/usr','/sw'])
    for netcdf_prefix in test_prefix:
        netcdf_include = os.path.join(netcdf_prefix, 'include')
        netcdf_lib = os.path.join(netcdf_prefix, 'lib')
        if os.path.exists(os.path.join(netcdf_include, 'netcdf.h')):
            break
        else:
            netcdf_prefix = None

Modify the add_extension line in setup.py of pynetcdf-0.7 as follows:

    config = Configuration('pynetcdf',parent_package,top_path)
# change starts here
    config.add_extension('_netcdf',
                         sources = ['_netcdf.c'],
                         include_dirs=[netcdf_include],
                         library_dirs=[netcdf_lib],
                         extra_link_args=[
                            os.path.join(netcdf_lib,'libnetcdf.a'),
                            '-L/usr/kerberos/lib64 -lcurl -ldl -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lidn -lssl -lcrypto -lz']
                        )
# change ends here.

Note that the -L/usr/kerberos/lib64 string comes from the linking line above.  We have removed -lnetcdf and -L because they are added by the other commands.

We are almost done.  At this point, the following build command should work.

python setup.py build

PAUSE HERE if you want an egg.  The next step is typically “python setup.py install” but we want to use setuptools to install so that we get an egg instead of a python directory.  If you don’t want an egg, go ahead and run python setup.py install.  Otherwise, edit setup.py again and change:

if __name__ == "__main__":
    #from numpy.setuptools import setup
    from setuptools import setup

After this edit, run

python setup.py install

This will place an pynetcdf-0.7.*.egg file in your site-packages directory.  This is what you want, right?  You should be able to use the library now with

import pynetcdf
This entry was posted in Uncategorized. Bookmark the permalink.

One Response to pynetcdf and libnetcdf

  1. Camille M. says:

    Thanks a lot for the tutorial. It works for me!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s