fortran - 在 Ubuntu 上编译 Fortran netCDF 程序

标签 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

我得到以下输出

/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

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

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

我做错了什么?

(FWIW,下面是我看过的一些相关引用文献。

  1. undefined reference using netcdf library

  2. Compiling problems with gfortran and NETCDF

  3. Compiling and Running Fortran Programs - a basic guide

)

最佳答案

在 Unix 系统上,链接器命令行上的目标文件和文件的排序非常重要,因为默认链接器行为是仅在跟随的文件中搜索符号定义发现未解析引用的目标文件或存档称为单 channel 链接。

这意味着,如果您的代码引用 __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.solibnetcdf.so),那么链接器会更喜欢它们到静态文件(除非使用 -static 选项启用静态链接),最终链接阶段将由运行时链接编辑器 (RTLD) (/lib64/ld- Ubuntu 上的 linux-x86-64.so.2)。在这种情况下,与您的问题中相同的命令行实际上会成功而不会出现链接错误,尽管两个库都位于引用它们的代码之前,因为 RTLD 在加载可执行文件时将解析缺少的符号引用文件。

关于fortran - 在 Ubuntu 上编译 Fortran netCDF 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13941549/

相关文章:

matrix - 求解受约束的线性方程组

fortran - 包装函数中的语句标签

fortran - 在Fortran中,设置提前="no",但得到换行符

python - 在 python 中计算 netcdf 文件几年的年度异常

fortran - 在 Fortran 中读取行数已知但每行条目数未知的数据文件

c++ - Eigen 在使用显式循环的矩阵乘法中比 Fortran 慢得多

netcdf - 使用 nco 连接具有不同变量的 netcdf 文件

xslt - 如何获取当前节点的父节点名称?

netcdf 文件的 axarray 中的 IO 后端错误