好的,这里有新问题.
我正在尝试编译simple_xy_wr.f90 - 一个netCDF示例程序 - 在Ubuntu上使用gfortran,我必须做一些非常愚蠢的事情; 我没有太多编译Fortran的经验.
首先,我安装了libnetcdf-dev软件包,其中包含类似的文件
/usr/lib/libnetcdf.a
/usr/lib/libnetcdff.a
/usr/include/netcdf.mod
Run Code Online (Sandbox Code Playgroud)
所以,我试图用(各种命令)编译代码
f95 -o xy -I/usr/include/ -L/usr/lib/ -lnetcdff -lnetcdf simple_xy_wr.f90
Run Code Online (Sandbox Code Playgroud)
我得到以下输出
/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
Run Code Online (Sandbox Code Playgroud)
我认为我包括了正确的库.例如,似乎__netcdf_MOD_nf90_strerror应该在那里:
$ nm /usr/lib/libnetcdff.a | grep __netcdf_MOD_nf90_strerror
000000000004a100 T __netcdf_MOD_nf90_strerror
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
(FWIW,我看过的一些相关参考文献如下.
)
Hri*_*iev 10
链接器命令行上的目标文件和存档的排序在Unix系统上非常重要,因为默认链接器行为是仅在跟踪目标文件或存档的存档中搜索符号定义,其中找到未解析的引用,称为单通道链接.
这意味着如果您的代码引用__netcdf_MOD_nf90_strerror,则包含此符号(libnetcdff.a)定义的存档必须出现在程序中的目标文件列表之后.libnetcdff.a它本身引用了C库中的符号libnetcdf.a,因此必须在之后链接libnetcdff.a.所以正确的链接顺序是:
/tmp/ccE6g7sr.o libnetcdff.a libnetcdf.a
Run Code Online (Sandbox Code Playgroud)
/tmp/ccE6g7sr.o汇编程序从编译的源文件生成的临时目标文件在哪里.然后,编译代码的正确命令行是:
f95 -o xy -I/usr/include/ simple_xy_wr.f90 -lnetcdff -lnetcdf
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不直接调用链接器,而是编译器执行它.GCC编译器以相同的顺序将所有与链接相关的东西传递给一个中间实用程序collect2,然后调用实际的链接器ld.
请注意,如果netCDF库归档的共享对象版本也存在(即有libnetcdff.so和libnetcdf.so),则链接器会更喜欢静态归档(除非使用该-static选项启用静态链接),并且最终链接阶段将被处理为运行时链接编辑器(RTLD)(/lib64/ld-linux-x86-64.so.2在Ubuntu上).在这种情况下,与问题中相同的命令行实际上会成功而没有链接错误,尽管两个库都位于引用它们的代码之前,因为RTLD在加载可执行文件时将解析缺少的符号引用文件.
在Ubuntu 12.10中,库的顺序是诀窍(正如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!
Run Code Online (Sandbox Code Playgroud)