web-dev-qa-db-ja.com

LNK4098の解決:defaultlib 'MSVCRT'との競合

この警告:

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

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

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

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

192
shoosh

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

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

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

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

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

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

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

247
Hans Passant

これは、依存するdllの1つが異なる 実行時ライブラリ でコンパイルされることを意味します。

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

すべてのライブラリを調べて、同じ方法でコンパイルされていることを確認します。

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

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

42
Yochai Timmer

IMO このリンク from Yochai Timmer は非常に優れていて関連性はありましたが、読むのは苦痛でした。要約を書きました。

Yochai、これを読んだことがあるなら、最後の注意書きをご覧ください。


元の投稿を読むには: 警告LNK4098:defaultlib "LIBCD"は他のライブラリの使用と競合します

エラー

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

意味

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

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

解決方法

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

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

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

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

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

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

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


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

29
ForceMagic

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

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

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

7
user1016736

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

3
raehee