ページ 1 / 1
リンクに関する警告が出ます。
Posted: 2008年9月02日(火) 21:38
by fumi
初めまして!
日ごろここで勉強させてもらっている、fumiと申します。
C言語歴は1年弱程度の初心者です。
早速質問なのですが、龍神録の館のプログラムをビルドしますと、何回かに1回リンクに関する下記のような警告がでてしまいます。
LINK : warning LNK4098: defaultlib 'LIBCMT' は他のライブラリの使用と競合していま す。/NODEFAULTLIB:library を使用してください。
この警告を解決するにはどのようにしたらいいのでしょうか?
環境は、
Windows XP
Visual C++ 2005 ExpressEdition
です。
プログラム自体は実行しますとちゃんと動くのですが、ちょっと気になっていたので投稿させていただきました。
どうかご教授お願いします。
Re:リンクに関する警告が出ます。
Posted: 2008年9月03日(水) 00:37
by Justy
>この警告を解決するにはどのようにしたらいいのでしょうか?
37章のプロジェクトで見てみました。
あー、なるほど。たしかに。
とりあえず、修正手順を下に書いてみました。
うちは VS2008なのでひょっとしたらうまくいかないかもしれません。
一応念のため、プロジェクト一式のバックアップをとった上でお試し下さい。
1 ソリューションエクスプローラのリソースファイルのフォルダから
*.libを全て消します(選択して DELキーを押して、確認ダイアログで「はい」を選択」)。
2 プロジェクトのプロパティを開きます。(プロジェクトメニューのプロパティ)
プロジェクトメニューのプロパティを選択するか、ソリューションエキスプローラ上の
Ryujinと書かれているところを右クリックして、プロパティを選択して下さい。
3 プロパティページの上部にある構成を 「アクティブ(Debug)」から「すべての構成」に切り替えます。
4 「構成プロパティ」の「リンカ」の「全般」の中に「追加のライブラリディレクトリ」というのが
あるので、そこに記述されている文字列を消して "..\include"と記述します。
5 プロパティ上部にある構成を Relaseに切り替えます。
6 構成プロパティ」の「C/C++」の「コード生成」の中に「ランタイムライブラリ」というのが
あるので、そこをマルチスレッドデバッグ(MTd)から マルチスレッド (MT)に
切り替えます。
これで、出なくなるかと思います。
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 03:27
by fumi
Justyさん、ありがとうございます。
教えてくださった修正手順のようにしてみたら、警告がでなくなりました。
この警告は、いったい何だったのでしょうか?
また、1~4はライブラリのリンクの仕方を変えたのだと理解できたのですが、5、6でReaseのマルチスレッドデバッグからマルチスレッドに切り替えを行ったのは何故なのでしょうか?
お手数ですが、もう一歩理解を深めたいので教えてくれたら幸いです。
(当初の問題は解決したので、マークを「解決!」にしておきました。)
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 10:08
by toyo
5,6について
LIBCMTはマルチスレッド(MT)用のCランタイムライブラリ(LIBC)です。
VC++にはデバッグモード用のLIBCとしてLIBCMTDというライブラリもあります。
これらはコンパイルオプションの /MT でLIBCMTが /MTd でLIBCMTDがリンクされます。
普通にプロジェクトを作るとデバッグモードでは /MTd に、リリースモードでは /MT に設定されます。
最初のエラーについて
最初の状態ではリソースファイルの部分にDXLibのライブラリファイルがすべて入っています。
よく見ると同じ名前で_dのついたファイルとペアになっているのがわかると思います(DxLib.libとDxLib_d.lib)。
_dのないライブラリはLIBCMTを_dのついたライブラリはLIBCMTDを使っているものと考えられます。
プロジェクトにリソースファイルとして追加されているためこれらを同時にリンクしようとするのですがプログラムにリンクできるのはLIBCMTかLIBCMTDのどちらか1つだけですのでエラーが出たわけです。
ひとつの解決法としてデバッグモードしか使わないというのであれば_d.libだけ残して他の.libファイルをリソースファイルから削除すればデバッグモードでのエラーは出なくなるはずです。
でもせっかくDxLib.hで
#ifdef _DEBUG
#pragma comment( lib, "DxLib_d.lib" ) // DXライブラリ使用指定
#pragma comment( lib, "DxUseCLib_d.lib" ) // 標準Cライブラリを使用する部分の lib ファイルの使用指定
#else
#pragma comment( lib, "DxLib.lib" ) // DXライブラリ使用指定
#pragma comment( lib, "DxUseCLib.lib" ) // 標準Cライブラリを使用する部分の lib ファイルの使用指定
#endif
と設定してあるのでライブラリのリンクはDxLib.hにまかせてプロジェクトファイルからは削除するのが正常なやり方でしょう。
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 12:38
by fumi
toyoさん、回答ありがとうございます。
丁寧かつわかりやすい内容で理解を深めることができました。
>リンクはDxLib.hにまかせてプロジェクトファイルからは削除するのが正常なやり方でしょう。
文の前後関係から、プロジェクトファイルからは削除しない、と捉えてよろしいのでしょうか?
また、DxLib.hにまかせる、ということは、DxLib.h内で"_DBUG"を自分で定義するということなのでしょうか?
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 13:08
by at
_DEBUG はVC++でデバッグビルドすると勝手に宣言されます。リリースビルドだと宣言されないはずです。
>LIBCMT
VC++ではいわゆるLIBC問題というものがあり、デバッグ+シングル、デバッグ+マルチ、リリース+シングル、リリース+マルチで使われるライブラリが微妙に異なるので、「外部スタティックライブラリを使用する際は、競合するどれかのライブラリを手動で解除しなければならない」ことになっています。話せば長くなるのでその辺は各自お調べください。
これは以前からバグだといわれてきた問題ですが、今のところ決定的な対応策はありません。
ライブラリが競合してるといわれたら、そのつどリンクを解除するしかないと思います。
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 14:07
by toyo
>リンクはDxLib.hにまかせてプロジェクトファイルからは削除するのが正常なやり方でしょう。
プロジェクトファイルRyuJin.vcprojから削除するという意味です
元のRyuJin.vcprojでは
<File
RelativePath="..\include\DxLib.lib"
>
</File>
のように記述されていますが
1 ソリューションエクスプローラのリソースファイルのフォルダから
*.libを全て消します(選択して DELキーを押して、確認ダイアログで「はい」を選択」)。
とすることでプロジェクトファイルの記述も削除されます。
"_DEBUG"はプロパティで定義されています。
メニューの「プロジェクト」「プロパティ」を開くと「構成プロパティ」「C/C++」「プリプロセッサ」のところの「プリプロセッサの定義」で
デバッグモードなら"WIN32;_DEBUG;_WINDOWS"が
リリースモードなら"WIN32;NDEBUG;_WINDOWS"が定義されています。
Re:リンクに関する警告が出ます。
Posted: 2008年9月04日(木) 15:17
by fumi
atさん、回答ありがとうございます。
>VC++ではいわゆるLIBC問題というものがあり
そのような問題があるのですか…
ライブラリを使用する際のリンク等のシステム的なエラーは私のような初心者には何だか敷居が高いように思えます。
>ライブラリが競合してるといわれたら、そのつどリンクを解除するしかないと思います。
はい。もしまたこのようなエラーが出たらJustyさん、toyoさんから教えて下さった方法を元にリンクを解除致します。
toyoさん、回答ありがとうございます。
>1 ソリューションエクスプローラのリソースファイルのフォルダから
*.libを全て消します(選択して DELキーを押して、確認ダイアログで「はい」を選択」)。
とすることでプロジェクトファイルの記述も削除されます。
早速テキストエディタでvcprojファイルを開いてみたところ、確かにリソースファイルの*.libを消したら
<File
RelativePath="..\include\DxLib.lib"
>
</File>
の部分も消えていました。
というか、リソースファイルや、includeするファイル、またプロジェクトに関する設定は、*.vcprojで管理されていることを初めて知りました…
>"_DEBUG"はプロパティで定義されています。
確認致しました。
なるほど、デバックモードとリリースモードではこのように"_DEBUG"や"NDEBUG"が定義されているかどうかで判断しているのですか…大変勉強になりました。
皆様、本当にありがとうございます!
気になっていた事が無事解決致しました!
最後に皆様の深い知識に敬意を表しますm(_ _)m