web-dev-qa-db-ja.com

Visual Studio 2010の奇妙な「警告LNK4042」

私は、Visual Studio 2010(C++)からの重要な警告によって(ほとんど)頭をatherられました。

コンパイルにより、次の出力が得られました。

1 Debug\is.obj:警告LNK4042:オブジェクトが複数回指定されています。余分なものは無視されます
1 Debug\make.obj:警告LNK4042:オブジェクトが複数回指定されています。余分なものは無視されます
1 Debug\view.obj:警告LNK4042:オブジェクトが複数回指定されています。余分なものは無視されます
1 identity.obj:エラーLNK2019:未解決の外部シンボルvoid __cdecl test::identity::view(void)(?view @ identity @ test @@ YAXXZ)は関数void __cdecl test::identity::identity(void)(?identity @ 0test @で参照されています@YAXXZ)
1 identity.obj:エラーLNK2019:未解決の外部シンボルvoid __cdecl test::identity::make(void)(?make @ identity @ test @@ YAXXZ)は関数void __cdecl test::identity::identity(void)(?identity @ 0test @で参照されています@YAXXZ)
1 range.obj:エラーLNK2019:未解決の外部シンボルvoid __cdecl test::range::is(void)(?is @ range @ test @@ YAXXZ)関数void __cdecl test::range::range(void)(?range @ 0test @ @YAXXZ)

リンカーエラーは常にデバッグするのが面倒です...しかし、未解決の参照があったので、チェックしました...しかし、ソースは整形式です...そしてついに私を襲いました:

私のフォルダ階層は次のようになります:

src/
  identity/
    is.cpp
    make.cpp
    view.cpp
  range/
    is.cpp
    make.cpp
    view.cpp

ソリューションの階層も同様です(「実際の」フォルダー構造を模倣するように常に設定します)。

そして診断出力:

Debug\is.obj
Debug\make.obj
Debug\view.obj

.objはリンカに2回渡され、その1つは無視されます。

これ以上検索しない:Visualはフォルダ階層をきちんとフラットにしているため、ソースをきちんとコンパイルできません。

現時点では、私は単にファイルの名前を変更することを考えています、それは問題をカバーするはずです...

...しかし、Visual Studioでファイル階層をフラット化しない方法はありますか?

75
Matthieu M.

プロジェクト全体のプロパティを開き、C/C++ -> Output Files -> "Object File Name"の下の値を次のように変更した場合、答えと思われるものをクロスポストしたかっただけです。

$(IntDir)/%(RelativeDir)/

VS 2010では、これによりすべてのオブジェクトファイルが明確になります(Windowsでは、同じディレクトリに同じ名前のファイルが2つあると、クレイジーな状況に陥ることはないと思われます)。詳細も確認してください こちら

96
M. Tibbits

リンカーの警告で同様の問題が発生しましたLNK4042:オブジェクトが2回以上指定されました;余分なものは無視されました。私の場合、Visual Studioはヘッダーファイルとソースファイルの両方を同じ名前-MyClass.hMyClass.cppでコンパイルしようとしました。 .cppファイルの名前を.hに変更し、Visual Studioが混乱したために発生しました。 Debugディレクトリのコンパイラログを見ると、問題に気付きました。解決するには、プロジェクトから.hファイルを削除してから再度追加します。

129
Andrey Levichev

[ソリューションエクスプローラー]ウィンドウの[プロパティ]、[C/C++]、[出力ファイル]、[オブジェクトファイル名]設定で.cppファイルを右クリックします。デフォルトは$(IntDir)\で、これがフラット化を行っています。すべての.objファイルは、デバッグ構成の「デバッグ」ディレクトリである$(IntDir)に入ります。

$(IntDir)\is2.objなどの設定を変更できます。または、1つのグループからすべてのファイルを選択し(Shift +クリックを使用)、設定をたとえば$(IntDir)\identity\に変更します

または、.objファイルが相互に上書きしないように、.cppファイル名を変更できます。 2つのディレクトリにまったく同じ名前のファイルがあるのは少し奇妙です。

または、複数のプロジェクトを作成して、たとえば、同一性と範囲内のファイルの.libプロジェクトを作成できます。たとえば、メイクファイルプロジェクトでよく行われます。ただし、プロジェクトのプロパティシートを使用しない限り、コンパイルとリンクの設定の管理が面倒になります。

8
Hans Passant

ヘッダーファイルを右クリック->プロパティ-> ItemType(C/C++ヘッダーを選択)。 Cppファイルでも同じことを行いますが、C/C++ COmpilerを選択します(私にとってはうまくいきます)

5
Phạm Mạnh

C/C++-> Output Files-> "Object File Name"で$(IntDir)\%(Directory)\を使用します。

4
Csimbi

Stdafx.cppでこの問題が発生しました。どういうわけかstdafx.cppが複製されたため、2番目のStdAfx.cppがありました(別のケースに注意してください)。

StdAfx.cppを削除すると、すべて正常に機能しました。

VS 2010を使用します。

3
Knasterbax

新しいファイルを削除して作成する代わりに、コンパイル/インクルード設定を変更できます。

project.vcxprojファイルに移動し、エディターでそれを開き、<ItemGroup>

次のようになります。

<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>

そして

<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`

実装ファイルが.cppであり、宣言が.hppであると仮定します。複数の宣言ファイルがある場合、2つ以上のセクションがある場合は、最初のセクションの間にすべての実装ファイルがリストされていることを確認してください。

3
user1222064

以前、同じプロジェクトに。c。cppがあり、同じファイル名のファイルがありました。ファイルはいたるところにあるフォルダにあり、他の人から提供されたソリューションは混乱を引き起こし、フォルダヘル(私の場合)を作成しました。 リリースビルドでも上書きされますデバッグビルド!

優れた(完全ではない)ソリューションは$(ParentName)を使用することですが、何らかの理由で誰もが理解できない範囲で、Visual Studioの以降のバージョン(2015以降)から削除されました。

私が今うまく使っているのは:$(IntDir)%(Filename)%(Extension).obj

少なくとも。cビルドオブジェクトファイルと。cppを分離します。

2
Bill Kotsias