好的,这里是新手问题。
我正在尝试编译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,下面是我看过的一些相关参考文献。
使用 netcdf 库的未定义引用
gfortran和NETCDF的编译问题
编译和运行 Fortran 程序 - 基本指南
)
链接器命令行上目标文件和档案的顺序是很重要在 Unix 系统上,因为默认链接器行为是仅在符合以下条件的档案中搜索符号定义:follow发现未解析引用的目标文件或存档称为单通道链接。
这意味着如果您的代码引用__netcdf_MOD_nf90_strerror
,然后包含该符号定义的存档(libnetcdff.a
) 必须出现after程序中的目标文件列表。libnetcdff.a
本身引用 C 库中的符号libnetcdf.a
,因此必须在之后链接libnetcdff.a
。所以正确的链接顺序是:
/tmp/ccE6g7sr.o libnetcdff.a libnetcdf.a
where /tmp/ccE6g7sr.o
是汇编器从编译的源文件生成的临时目标文件。编译代码的正确命令行是:
f95 -o xy -I/usr/include/ simple_xy_wr.f90 -lnetcdff -lnetcdf
在这种情况下,不会直接调用链接器,而是由编译器调用。 GCC 编译器将所有与链接相关的内容以相同的顺序传递给名为的中间实用程序collect2
然后调用实际的链接器ld
.
请注意,如果 netCDF 库档案的共享对象版本也存在(即有libnetcdff.so
and libnetcdf.so
),那么链接器会更喜欢它们而不是静态档案(除非使用-static
选项),最终链接阶段将由运行时链接编辑器(RTLD)处理(/lib64/ld-linux-x86-64.so.2
在 Ubuntu 上)。在这种情况下,与您的问题中相同的命令行实际上会成功而不会出现链接错误,尽管两个库都位于引用它们的代码之前,因为 RTLD 在加载可执行文件时将解析缺少的符号引用文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)