Linkerの警告について

一時期,リンカエラーや警告に悩まされたことがありました.以下の文書は,そのとき調べた内容をまとめたものです.余り上手くまとまっていない文章ですが,ここに記録しておきたいと思います.


以降の文章中に表れるkrdclib.libとは,内部でclapack.libを利用するスタティックライブラリのことを指しています.


正しい設定では,利用するアプリ側でclapack.libと(clapack.libをリンクさせずにビルドした)krdclib.libの両方をリンクしなければなりません.krdclib.libにclapack.libをリンクさせ,アプリ側ではkrdclib.libのみをリンクさせるようにすると,環境によっては(VS2003では)warningが発生します.

パブリックシンボル

Visual Studio 2005において,krdclib.libにclapack.libをリンクするように設定し,krdclib.libをビルドすると,以下のようなメッセージが表示されます.

clapack.lib(Version.obj) : warning LNK4221: パブリック シンボルが見つかりませんでした。アーカイブ メンバにアクセスできません。

ビルド自体は成功し,ライブラリの使用上は問題がみられません.CLAPCKのソースを調べてみたところ,Version.cにはstatic charの配列が一つあるだけでした.static属性は,対象をそのファイル内からしか参照できないようにする効果があります.そのため,上記のような(パブリックシンボルが1つもみつからない云々)warningが出てしまったようです.

しかし,static関数の場合は上記warningがでないようです.
どうやら,staticグローバル変数だけがファイルにある場合にのみ発生するwarningのようです.

以下の情報から,今回のケースに限り,無視しても問題がないと思われます.
http://www.intel.com/support/performancetools/c/windows/sb/cs-004737.htm

再定義

Visual Studio 2003において,krdclib.libにclapack.libをリンクするように設定し,krdclib.libをビルドすると,warningが発生します.
Visual Studio 2005では発生しません,その代わり「パブリックシンボル」のwarningが発生します)

clapack.lib(cbdsqr.obj) : warning LNK4006: _cbdsqr_ は clapack.lib(cbdsqr.obj) で定義されています。2 つ目以降の定義は無視されます。

どうやら,static libraryにstatic libraryをリンクさせると発生するようです.
Web Page Under Construction

krdclib.libにclapack.libをリンクさせるのをやめ,アプリケーション側でkrdclibとclapack.libを併せてリンクするように変更すれば,warningがなくなります.

参考:LNK4006について

リンク設定について

Visual Studioでリンク設定を行う場合,リンクするライブラリがRelease/Debugのどちらでビルドされたものなのかを正確に把握しておかなければなりません.例えば,Releaseモードでビルドされたスタティックライブラリ(clapack.lib)をリンクさせ,ライブラリ利用側をDebugビルドすると,以下のwarningが発生します.

LINK : warning LNK4098: defaultlib 'MSVCRT' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
Visual Studio 2003の場合には,加えてLNK4089が出る ※1)

これは,clapack.libにリンクされているmsvcrt.libと,ライブラリ利用側にリンクされているmsvcrtd.libが競合するためです.リンクするライブラリを,Release/Debugモードで分けて設定する必要があります.
ライブラリ利用側の「プロジェクトの設定」で,「追加のライブラリディレクトリ」に,Releaseモードの時は「C:\(folder path)\CLAPACK\Release」を,Debugモードの時は「C:\(folder path)\CLAPACK\Debug」を設定しなければなりません.
(ライブラリ利用側がRelease/Debugモードであれば,リンクするライブラリもRelease/Debugモードのものでなければならないということ)
もしも,リンクしたいライブラリにRelease/Debugモードのどちらかのファイルしか存在しない場合,libc.lib; libcmt.lib; msvcrt.lib; libcd.lib; libcmtd.libを「無視するライブラリ」として指定する必要があります.設定によって,指定するファイルが変わるため,詳しくはMSDNを参照してください.
参考:リンカー ツールの警告 LNK4098

※1:LNK4089について

LINK : warning LNK4089: 'dynamic-link library' へのすべての参照は /OPT:REF によって廃棄されます。

Visual Studio 2003までにしかない番号であり,Visual Studio 2005のヘルプには存在しません./OPT:REFオプションには,参照されない関数とデータを削除する働きがあります.warning LNK4098により,競合したライブラリへの参照が全て削除されているようです.ビルド対象がReleaseモードであるにもかかわらず,DebugモードのDLLをリンクするように設定されている場合などに発生します.