在Ubuntu上编译Fortran netCDF程序 [英] Compiling Fortran netCDF programs on Ubuntu

查看:713
本文介绍了在Ubuntu上编译Fortran netCDF程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,新问题在这里。



我正在编译 simple_xy_wr.f90 - 一个netCDF示例程序 - 在Ubuntu上使用gfortran,我必须做一些非常愚蠢的事情;我没有太多经验编译Fortran。



首先,我得到了 libnetcdf-dev 软件包,其中包含如下文件:

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

所以,我试着用(各种命令)编译代码

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

,并得到以下输出:

pre $ /tmp/ccE6g7sr.o:在函数check.1847中:$ b $ ; b simple_xy_wr.f90 :(文本+ 0x72):未定义参考`__netcdf_MOD_nf90_strerror '
/tmp/ccE6g7sr.o:在功能`MAIN__':
simple_xy_wr.f90 :(文本+量0x284):未定义的引用'__netcdf_MOD_nf90_create'
simple_xy_wr.f90 :(。text + 0x2b6):未定义的引用'__netcdf_MOD_nf90_def_dim'
simple_xy_wr。 。F90 :(文字+了0x2e8):未定义的引用`__netcdf_MOD_nf90_def_dim
simple_xy_wr.f90 :(文字+ 0x432):未定义的引用`__netcdf_MOD_nf90_def_var_manydims'
simple_xy_wr.f90 :(文字+ 0x468)。 :对__netcdf_MOD_nf90_enddef的未定义引用
simple_xy_wr.f90 :( .text + 0x4aa):未定义对`__netcdf_MOD_nf90_put_var_2d_fourbyteint'的引用
simple_xy_wr.f90 :( .text + 0x4cb):未定义对`_cnetcdf_MOD_nf90_close'的引用
collect2:error:ld返回1退出状态

我认为我包括正确的库。例如。看起来__netcdf_MOD_nf90_strerror应该在那里:

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

我做错了什么?



(FWIW,我看过的几个相关参考文献如下。
$ b


  1. < a href =http://www.unidata.ucar.edu/mailing_lists/archives/netcdfgroup/2007/msg00050.html =nofollow>使用netcdf库的未定义引用


  2. 使用gfortran和NETCDF编译问题

    a>


  3. 编译和运行Fortran程序 - 基本指南


  4. 解决方案

    在Unix系统上,链接器命令行上的对象文件和存档的排序非常重要,因为默认链接器行为是搜索符号定义如果存档的是跟随的目标文件或存档,其中找到了未解析的引用,称为单通链接。



    这意味着如果您的代码引用 __ netcdf_MOD_nf90_strerror ,那么包含此符号定义的存档( libnetcdff.a )必须显示为在你的程序中的目标文件列表之后。 libnetcdff.a 自身引用C库中的符号 libnetcdf.a ,因此它必须链接到 libnetcdff.a 。所以正确的链接顺序是:

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

    其中 /tmp/ccE6g7sr.o 是汇编程序的临时目标文件从编译的源文件生成。正确的命令行来编译你的代码然后:

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

    在这种情况下,链接器不是直接调用,而是编译器执行它。 GCC编译器将所有与链接有关的东西以相同的顺序传递给一个称为 collect2 的中间实用程序,然后调用实际的链接程序 ld



    请注意,如果netCDF库存档的共享对象版本也存在(即存在 libnetcdff.so libnetcdf.so ),那么链接程序会更喜欢它们到静态存档(除非静态链接使用 -static 选项),最后的链接阶段将被处理到运行时链接编辑器(RTLD)( /lib64/ld-linux-x86-64.so.2 在Ubuntu上)。在这种情况下,与您的问题中相同的命令行实际上可以成功,而不会出现链接错误,尽管两个库位于引用它们的代码之前,因为RTLD在加载可执行文件时将解决丢失的符号引用文件。


    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; I don't have much experince compiling Fortran.

    First, I've got the libnetcdf-dev package installed, which includes files like

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

    So, I've tried to compile the code with (various command like)

    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 that I'm including the right libraries. E.g. 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 references I've looked at are below.

    1. undefined reference using netcdf library

    2. Compiling problems with gfortran and NETCDF

    3. Compiling and Running Fortran Programs - a basic guide

    )

    解决方案

    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.

    这篇关于在Ubuntu上编译Fortran netCDF程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆