2

Fortran コードをコンパイルしようとしていますが、わかりにくいリンク エラーが発生します。コンパイルして静的ライブラリに配置するコードがいくつかあります。

>gfortran -c -I../../inc -o bdout.o bdout.F
>ar rv libgeo.a bdout.o

次に、いくつかの簡単なテスト コードを使用してそのライブラリに対してコンパイルを試み、次の結果を取得します。

>gfortran -o mytest -L -lgeo mytest.F
/tmp/cc4uvcsj.o: In function `MAIN__':
mytest.F:(.text+0xb0): undefined reference to `ncwrite1_'
collect2: ld returned 1 exit status

すべてが問題ないように見えるため、オブジェクトの命名には含まれていません。

>nm -u libgeo.a

bdout.o:
     U _gfortran_exit_i4
     U _gfortran_st_write
     U _gfortran_st_write_done
     U _gfortran_transfer_character
     U _gfortran_transfer_integer
     U ncobjcl_
     U ncobjwrp_
     U ncopencr_
     U ncopenshcr_
     U ncopenwr_
     U ncwrite1_
     U ncwrite2_
     U ncwrite3_
     U ncwrite4_
     U ncwritev_

元のオブジェクト ファイルも確認できます。

>nm -u bdout.o

     U _gfortran_exit_i4
     U _gfortran_st_write
     U _gfortran_st_write_done
     U _gfortran_transfer_character
     U _gfortran_transfer_integer
     U ncobjcl_
     U ncobjwrp_
     U ncopencr_
     U ncopenshcr_
     U ncopenwr_
     U ncwrite1_
     U ncwrite2_
     U ncwrite3_
     U ncwrite4_
     U ncwritev_

テスト コードには、bdout.o で定義された関数への呼び出しが 1 つだけ含まれています。

program hello
        print *,"Hello World!"
        call ncwrite1( istat, f, ix2, ix3, ix4, ix5, ih )
end program hello

何が問題なのかわかりません。誰か提案はありますか?問題を追跡するための単なる方法でさえありますか?

乾杯。

4

4 に答える 4

1

これがこの特定の問題に役立つかどうかはわかりませんが、通常、リンカー コマンドは常にオブジェクト ファイルの後に配置します。次に、libgeo.a が現在のディレクトリにある場合は、それを明示的に追加する必要があります。空の -L AFAIK は何もしません。いえ

gfortran -o mytest mytest.F -L. -lgeo

編集: nm 出力の「U」は、シンボルが未定義であることを意味することにも注意してください。つまり、.o ファイルはそのシンボルを参照していますが、そのシンボルは実際には別のファイルにあります。つまり、ncwrite1_ シンボルを定義するライブラリに明示的にリンクする必要がある場合があります。

于 2010-04-01T20:39:28.547 に答える
1

問題は、その関数を含むライブラリに対してリンクしていないことです。これには 2 つの理由が考えられます。

  1. ncwrite1関数は、リンクしているライブラリで定義されていません。nmこれが該当する (または該当しない) ことを確認するために使用します。
  2. ライブラリは、コマンド ラインのオブジェクト/ソース コード ファイルの前に配置されます (!) リンカは、これまでで最も馬鹿げたものであり、他のすべてに対してすべてを解決しようとはしません (これは、高度な手法で役立つ場合があります)。ライブラリを他のすべての後に配置する必要があります。ライブラリが多数ある場合は、それらの間の依存関係に対してトポロジカル ソートを使用して、それらをリンカにリストする正しい順序を決定する必要があります。

geo ライブラリに目的の関数があると仮定した場合 (確認してください!)、次のようにビルドしてリンクする必要があります。

gfortran -o mytest -L. mytest.F -lgeo
于 2010-04-02T07:54:58.003 に答える
0

まず、答えてくれた皆さんに感謝します。このスレッドを公式に終了するために投稿しています。ライブラリ(libgeo.a)を作成した人が、コンパイラフラグマクロ-D(macro)を使用してオンにしたコードにいくつかの#ifdefステートメントを配置したことがわかりました。これらの#ifdefは、特定のパラメーターで関数名を展開するために使用されます。コンパイラに適切なマクロを提供しないと、関数名は展開されないままになり、シンボルは未定義になりました。Grrrr..。

于 2010-04-07T14:56:52.660 に答える
0

問題は、ncwrite1 の呼び出しがサブルーチンのライブラリ定義の署名と一致しないことであり、エラー メッセージが実際に伝えようとしているのは、呼び出しに一致する署名を持つ ncwrite1 のバージョンが見つからないことです。 . あなたのプログラムは ncwrite1 への明示的なインターフェイスを使用していないようです。そのため、このような型エラーはコンパイル時にキャッチされません。

于 2010-04-02T06:51:19.150 に答える