LNK4098の解決:defaultlib 'MSVCRT'が競合します


216

この警告:

LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts
  with use of other libs; use /NODEFAULTLIB:library

Visual Studioでかなり一般的な警告です。その正確な理由とそれを処理する正しい方法(あるとしても)を理解したいと思います。

これは、でコンパイルされたデバッグビルドで表示され/MDdます。プロジェクトは、ウィンドウVersion.dllなどpdh.dllにリンクされており、それ自体がとリンクしていMSVCRT.dllます。明らかに、これらのデバッグバージョンがなく、コンパイルできません。

だから私/NODEFAULTLIB:MSVCRTはリンカのコマンドラインに追加し、実際には警告を削除しました。しかし、これは実際に何をするのでしょうか?そして、なぜそれが必要なのですか?

回答:


273

vc \ libには、4つのバージョンのCRTリンクライブラリがあります。

  • libcmt.lib:リリースビルド(/ MT)の静的CRTリンクライブラリ
  • libcmtd.lib:デバッグビルド用の静的CRTリンクライブラリ(/ MTd)
  • msvcrt.lib:CRT(/ MD)のリリースDLLバージョンのインポートライブラリ
  • msvcrtd.lib:CRTのデバッグDLLバージョンのインポートライブラリ(/ MDd)

リンカーオプション、プロジェクト+プロパティ、リンカー、コマンドラインを確認します。これらのライブラリがここで言及されていないことに注意してください。リンカは、コンパイラによって使用された/ Mスイッチと、#pragmaコメントディレクティブを介してリンクされる.libを自動的に判断します。重要なことですが、/ Mオプションとリンクする.libの間に不一致があると、恐ろしいリンクエラーが発生し、ランタイムエラーを診断するのが難しくなります。

リンカーがmsvcrt.lib libcmt.libの両方にリンクするように指示されたときに、引用したエラーメッセージが表示されます。これは、/ MTでコンパイルされたコードと/ MDでリンクされたコードをリンクすると発生します。CRTのバージョンは1つだけです。

/ NODEFAULTLIBは、/ MTコンパイル済みコードから生成された#pragmaコメントディレクティブを無視するようにリンカーに指示します。これはうまくいくかもしれませんが、他の多くのリンカエラーは珍しいことではありません。errnoのようなもので、静的CRTバージョンではextern intですが、DLLバージョンでは関数にマクロ変換されます。他の多くの人もそうです。

さて、この問題を正しい方法で修正し、リンクしている.objまたは.libファイルを、間違った/ Mオプションを使用してコンパイルしたものを見つけます。手がかりがない場合は、「/ MT」の.obj / .libファイルをgrepすることで見つけることができます。

ところで:Windows実行可能ファイル(version.dllなど)には、仕事を完了するための独自のCRTバージョンがあります。これはc:\ windows \ system32にあり、独自のプログラムで確実に使用することはできません。CRTヘッダーはどこでも使用できません。プログラムで使用されるCRT DLLの名前が異なります(msvcrt90.dllなど)。


2
この投稿のおかげで、私はまだ/ MDdを使用している.libを探し続けましたが、最終的に1つ見つかりました!ありがとう、+ 1
ceztko

64
間違ったCRTライブラリを取り込むライブラリを追跡するために私が学んだばかりのトリックは/verbose:lib、追加のリンカーオプションに追加することです。それは間違ったものがで引っ張った場所を見ることができるよう、.libファイルがにロードされる順序を示しています。
obmarg

1
ハンス、それはどれほど危険ですか?修正できない場合(ベンダーからコンパイル済みのlibを取得します)、どのような結果が生じる可能性がありますか?
Ivan Nikitin 2013

3
@obmarg 'コメントは役に立ったと思いますが、詳細出力が表示されるというmsdn.microsoft.com/en-us/library/aa267384(v=vs.60).aspxが見つかるまで、詳細出力の使用方法がわかりませんでしたリンクの問題に関係するすべてのランタイムライブラリのみを伝えます。その後、競合するランタイムライブラリを使用してコンパイルされたリンク入力を特定する必要があります。
buzz3791 2015年

4
@ buzz3791は/ verbose:libの代わりに/ verboseを使用します。表示される情報には、ライブラリ検索プロセスが含まれ、各ライブラリとオブジェクト名(フルパスを含む)、ライブラリから解決されるシンボル、およびシンボルを参照するオブジェクトのリストが一覧表示されます。/ verboseは、競合の原因となる悪者を見つけるために必要なすべての情報を表示できます。
Yang Kui

46

これは、依存するDLLの1つが別のランタイムライブラリでコンパイルされていることを意味します

プロジェクト->プロパティ-> C / C ++->コード生成->ランタイムライブラリ

すべてのライブラリーを調べて、同じようにコンパイルされていることを確認してください。

このリンクのこのエラーの詳細:

警告LNK4098:defaultlib "LIBCD"は他のライブラリの使用と競合します


それがエラーの理由でした!先端をありがとう。
rkachach

1
これは経験の浅いプログラマにとって最良の答えです。
meolic

32

IMOのYochai Timmerからのこのリンクは非常に優れており、関連性はありましたが、読むのは大変でした。概要を書きました。

ヨチャイ、これを読んだことがある人は最後の注意書きを見てください。


元の投稿の読み取り:警告LNK4098:defaultlib "LIBCD"が他のライブラリの使用と競合します

エラー

リンク:警告LNK4098:defaultlib "LIBCD"は他のライブラリの使用と競合します。/ NODEFAULTLIB:libraryを使用します

意味

システムの一部は、静的にリンクされたデバッグ情報(libcd)を含むシングルスレッド標準(libc)ライブラリを使用するようにコンパイルされました

システムの別の部分は、DLLに常駐して動的リンクを使用するデバッグ情報なしでマルチスレッド標準ライブラリを使用するようにコンパイルされています

解決する方法

  • 警告は無視してください。結局それは単なる警告です。ただし、プログラムには同じ関数の複数のインスタンスが含まれています。

  • リンカーオプション/ NODEFAULTLIB:libを使用します。これは完全な解決策ではありませんが、この方法でプログラムをリンクして警告サインを無視しても、コードは異なる環境用にコンパイルされているため、一部のコードはシングルスレッドモデル用にコンパイルされている一方で、他のコードはマルチスレッド。

  • [...]すべてのライブラリをトロールし、正しいリンク設定があることを確認します

後者では、元の投稿で述べたように、2つの一般的な問題が発生する可能性があります。

  • アプリケーションに異なる方法でリンクされたサードパーティライブラリがあります。

  • 他のディレクティブがコードに埋め込まれています。通常、これはMFCです。システム内のモジュールがMFCにリンクする場合、すべてのモジュールは名目上同じバージョンのMFCにリンクする必要があります。

このような場合は、問題を理解し、解決策を決定してください。


注:私はYochai Timmerのリンクの要約を彼自身の回答に含めたかったのですが、一部の人々は編集を適切にレビューするのに苦労しているため、別の回答にそれを書かなければなりませんでした。ごめんなさい


7

VC ++でアプリケーションを作成するたびに、これが発生します。

プロジェクトを右クリックし、[プロパティ]を選択して、[構成プロパティ]の下の[プロパティ]をクリックします。C / C ++ | コード生成」で、デバッグ構成に「マルチスレッドデバッグ(/ MTd)」を選択します。

これはリリース構成の設定を変更しないことに注意してください。同じ場所に移動し、リリースに「マルチスレッド(/ MT)」を選択する必要があります。


4

プロジェクトを右クリックし、[プロパティ]を選択して、[構成プロパティ]の下の[プロパティ]をクリックします。リンカー| 入力| 特定のライブラリを無視してmsvcrtd.libを書き込みます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.