Using NetCDF with FPM

Hi folks,

I have a model that I want to fpm-ify. It depends on this OO interface to NetCDF Fortran: GitHub - schaefed/mo_netcdf: Modern fortran netcdf wrapper. I tried to write an fpm.toml file for that repo, which at the moment looks like this:

name = "mo_netcdf"
version = "1.0.0"
license = ""
author = "David Schaefer"
maintainer = ""
copyright = ""

external-modules = ["netcdf"]
link = ["netcdf", "netcdff"]

[[ example ]]
name = "write"
source-dir = "examples"
main = "write.f90"

[[ example ]]
name = "read"
source-dir = "examples"
main = "read.f90"

[[ test ]]
name = "test"
source-dir = "tests"
main = "test_setdata.f90"

library = true

This works fine except I need to explicitly specify the include directory where netcdf.mod is, which in my case is /usr/include. I can get this by running the command line utiltiy nf-config --fflags. So, instead of just running fpm build, I have to run…

$ fpm build --flag $(nf-config --fflags)

…or set the FPM_FFLAGS env var. My question is, is there any better way of doing this that I’m missing? Any thoughts from anyone else using NetCDF with FPM greatly welcome!


Second somewhat unrelated question whilst I’m here: Is there a way to exclude source files from the build in FPM? I couldn’t find anything in the docs.

I put together a netcdf interface package for fpm to avoid needing to rely on compiler-dependent .mod files:

More info here: Experimental netcdf4 interface package · fortran-lang/fpm · Discussion #458 · GitHub

Unfortunately, I don’t think this is possible currently.

Probably not intended features, but the include directory can be a link, or the files in it which will be used for the build, and the link directive just takes the strings and prefixes them with the compiler flag for specifying a library (typically “-l”) so if that is the only include directory you need and you are on Unix/BSD or GNU/Lin onx “ln -s /usr/include /include” will satisfy the build, and you can add additional loader flags on the link directive., like 'link = [netcdf -L/somedir -J/somedir -I/somdir …"] to handle loader issues. I have seen several uses of this, but it is probably not an intentional feature as this is really what profiles are for. Maybe those “features” should actually be blocked, as they allow for very compiler-specific options to appear in the fpm.toml file.

You can use files of options as described with the M_CLI2 documentation in response files so you can just enter things like “build @myopts” instead of specifying long lists of flags; and of course use environment variables and aliases or wrapper scripts but what you really want requires user-specified profiles and/or conditional preprocessing of the fpm.toml file which is currently not supported; although with the caveat that it is not a good idea for anything you are distributing to anyone else the features/gaps above work for now.

Thanks both, useful info.

This looks great and I like avoiding relying on compiler dependent .mod files, this has always been a struggle with NetCDF for me.

This might be getting off topic a bit, but when I try and use netcdf-interfaces I get an error that nf_def_var_szip_ is undefined at the linking stage:

/usr/bin/ld: build/gfortran_2A42023B310FA28D/fpm-test/libfpm-test.a(build_dependencies_netcdf-interfaces_src_netcdf4.f90.o): in function `__netcdf_MOD_nf90_def_var_szip':
/home/sharrison/code/fpm-test/build/dependencies/netcdf-interfaces/src/netcdf4.f90:5298: undefined reference to `nf_def_var_szip_'

I create a simple test program that just tried to run this test: Any ideas what might be causing this?

Hmm, do you know what versions of netcdf-fortran and netcdf-c you have installed?

Ah that will be the problem! netcdf-fortran 4.5.2 and netcdf-c 4.6.2, but this page says nf90_def_var_szip was added in netcdf-fortran 4.5.3. I’ll give updating them a go tomorrow and see if that clears up the issue.

1 Like