Compiling Fortran netCDF programs on Ubuntu

前端 未结 2 2012
鱼传尺愫
鱼传尺愫 2021-01-02 18:13

Ok, newb question here.

I\'m trying to compile simple_xy_wr.f90 -- a netCDF example program -- using gfortran on Ubuntu, and I must be doing something pretty silly;

相关标签:
2条回答
  • 2021-01-02 18:30

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

    
    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! 
    
    0 讨论(0)
  • 2021-01-02 18:48

    Ordering of object files and archives on the linker command line is very important on Unix systems since the default linker behaviour is to search for symbol definitions only in archives that follow the object file or archive, where an unresolved reference was found, referred to single pass linking.

    This means that if your code references __netcdf_MOD_nf90_strerror, then the archive that contains the definition of this symbol (libnetcdff.a) must appear after the list of object files from your program. libnetcdff.a itself references symbols from the C library libnetcdf.a, hence it must be linked after libnetcdff.a. So the correct link order is:

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

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

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

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

    Note that if shared object versions of the netCDF library archives are also present (i.e. there are libnetcdff.so and libnetcdf.so), then the linker would prefer them to the static archives (unless static linking is enabled with the -static option) and the final link phase would be handled to the run-time link editor (RTLD) (/lib64/ld-linux-x86-64.so.2 on Ubuntu). In this case the same command line as in your question would actually succeed without link errors, despite the fact that both libraries are positioned before the code that references them, as the missing symbol references would be resolved by the RTLD while it is loading the executable file.

    0 讨论(0)
提交回复
热议问题