7

わかりました、ここに初心者の質問があります。

Ubuntuでgfortranを使用してsimple_xy_wr.f90 (netCDFサンプルプログラム)をコンパイルしようとしていますが、かなりばかげたことをしているに違いありません。私は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. netcdfライブラリを使用した未定義の参照

  2. gfortranとNETCDFの問題のコンパイル

  3. Fortranプログラムのコンパイルと実行-基本ガイド

)。

4

2 に答える 2

10

リンカコマンドラインでのオブジェクトファイルとアーカイブの順序は、Unixシステムでは非常に重要です。デフォルトのリンカの動作は、オブジェクトファイルまたはアーカイブに続くアーカイブでのみシンボル定義を検索することであり、未解決の参照が見つかった場合は、シングルパスを参照します。リンク。

つまり、コードがを参照している場合、__netcdf_MOD_nf90_strerrorこのシンボル()の定義を含むアーカイブは、プログラムのオブジェクトファイルのリストのlibnetcdff.aに表示される必要があります。それ自体がCライブラリのシンボルを参照するため、の後にリンクする必要があります。したがって、正しいリンク順序は次のとおりです。libnetcdff.alibnetcdf.alibnetcdff.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.2Ubuntu)。この場合、実行可能ファイルのロード中に欠落しているシンボル参照がRTLDによって解決されるため、両方のライブラリがそれらを参照するコードの前に配置されているにもかかわらず、質問と同じコマンドラインが実際にリンクエラーなしで成功します。ファイル。

于 2012-12-19T13:20:13.693 に答える
6

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! 
于 2012-12-19T10:44:58.387 に答える