GNU LDのライブラリ・リンクの順番

GNU LDのライブラリをリンクする順番で半日もがきつづけていました。

以下はLD呼び出し時のスクリーンショットですが、黄色で示した二つのライブラリ指定オプションの順序をひっくり返すと、リンクに失敗します。

image

そのときのエラーメッセージが以下の通り。

`vhdl::local_numeric_tools::sra_round(int, int)’ に対する定義されていない参照です

これはわあからない。C++の関数の引数の型指定が甘くて多重定義された別の関数を探しているのかと思って、無駄にプログラムを精査しましたよ。

この点について、LDのマニュアルには以下のように記されています。

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

つまり、「(リンカーが注目している)ライブラリの中で定義されているシンボルが、そのライブラリより先に現れたファイルの中で未定義シンボルとして参照されている」ならば、(注目している)ライブラリのその定義を取り出して、出力する。というわけです。

最初のスクリーンショットに関して見てみると、確かにlibcordic_sincos_model.aのなかで、sra_round(int, int)が未定義シンボルとして参照されています。そして、そのシンボルはlibpackage_model.aで定義されています。

このような順番の制限は1パス・リンカ故のものです。

GNU LDともなるとリンク対象はGCC C++コンパイラやLinuxカーネルのような巨大なものまでが対象になります。それゆえ2パスのような時間のかかることを避けたかったのだと思いますが、コマンドライン・オプションとてユーザー・インターフェースなのですから、もう少し富豪的に2パスでもいいやん、と思うところです。

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください