Compiling Fortran netCDF programs on Ubuntu

Well, the newb question is here.

I am trying to compile simple_xy_wr.f90 - an example of a netCDF program - using gfortran on Ubuntu, and I have to do something pretty stupid; I don't have much experience compiling Fortran.

Firstly, I have installed the libnetcdf-dev package, which includes files such as

/usr/lib/libnetcdf.a /usr/lib/libnetcdff.a /usr/include/netcdf.mod 

So, I tried to compile the code with (e.g. command)

 f95 -o xy -I/usr/include/ -L/usr/lib/ -lnetcdff -lnetcdf simple_xy_wr.f90 

and I get the following output

 /tmp/ccE6g7sr.o: In function `check.1847': simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror' /tmp/ccE6g7sr.o: In function `MAIN__': simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create' simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim' simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim' simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims' simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef' simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint' simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close' collect2: error: ld returned 1 exit status 

I think I am including the correct libraries. For instance. it seems that __netcdf_MOD_nf90_strerror should be there:

 $ nm /usr/lib/libnetcdff.a | grep __netcdf_MOD_nf90_strerror 000000000004a100 T __netcdf_MOD_nf90_strerror 

What am I doing wrong?

(FWIW, a few relevant links that I looked at are below.

)

+4
source share
2 answers

Ordering object files and archives on the linker command line is very important on Unix systems, since the default behavior of the linker is to search for symbol definitions only in archives following the object file or archive where an unresolved link related to a single-pass link was found.

This means that if your code refers to __netcdf_MOD_nf90_strerror , then the archive containing the definition of this symbol ( libnetcdff.a ) should appear after the list of object files from your program. libnetcdff.a itself refers to characters from the C library libnetcdf.a , so it must be linked after libnetcdff.a . Therefore, the correct order of links:

 /tmp/ccE6g7sr.o libnetcdff.a libnetcdf.a 

where /tmp/ccE6g7sr.o is the temporary file of the object that the assembler creates from the compiled source file. The correct command line to compile your code:

 f95 -o xy -I/usr/include/ simple_xy_wr.f90 -lnetcdff -lnetcdf 

In this case, the linker is not called directly, but rather the compiler does it. GCC compilers pass all the binding-related things in the same order to an intermediate utility called collect2 , which then calls the actual linker ld .

Please note that if there are public versions of netCDF library libraries (i.e. there are libnetcdff.so and libnetcdf.so ), then the linker will prefer them to static archives (if static linking is not enabled using -static ), and the final link phase will be processed Runtime Link Editor (RTLD) ( /lib64/ld-linux-x86-64.so.2 on Ubuntu). In this case, the same command line as in your question will be really successful without link errors, despite the fact that both libraries are located in front of the code that refers to them, since missing links to characters will be resolved by RTLD when loading the executable file file.

+6
source

In Ubuntu 12.10, the order of the libraries is a trick (as suggested by Hristo):

 angelv@palas :~$ gfortran -o xy -I/usr/include/ -L/usr/lib/ -lnetcdf -lnetcdff simple_xy_wr.f90 /tmp/ccj95anF.o: In function `check.1847': simple_xy_wr.f90:(.text+0x72): undefined reference to `__netcdf_MOD_nf90_strerror' /tmp/ccj95anF.o: In function `MAIN__': simple_xy_wr.f90:(.text+0x284): undefined reference to `__netcdf_MOD_nf90_create' simple_xy_wr.f90:(.text+0x2b6): undefined reference to `__netcdf_MOD_nf90_def_dim' simple_xy_wr.f90:(.text+0x2e8): undefined reference to `__netcdf_MOD_nf90_def_dim' simple_xy_wr.f90:(.text+0x432): undefined reference to `__netcdf_MOD_nf90_def_var_manydims' simple_xy_wr.f90:(.text+0x468): undefined reference to `__netcdf_MOD_nf90_enddef' simple_xy_wr.f90:(.text+0x4aa): undefined reference to `__netcdf_MOD_nf90_put_var_2d_fourbyteint' simple_xy_wr.f90:(.text+0x4cb): undefined reference to `__netcdf_MOD_nf90_close' collect2: error: ld returned 1 exit status angelv@palas :~$ gfortran -o xy -I/usr/include/ simple_xy_wr.f90 -L/usr/lib/ -lnetcdf -lnetcdff angelv@palas :~$ ./xy 0 12 24 36 *** SUCCESS writing example file simple_xy.nc! 
+5
source

All Articles