Visual Studio 2010 странное «предупреждение LNK4042» - PullRequest
75 голосов
/ 12 сентября 2010

Меня только что избили (довольно сильно) по голове каким-то нетривиальным предупреждением из Visual Studio 2010 (C ++).

Компиляция дала следующий вывод:

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 был передан компоновщику дважды, и тот будет проигнорирован.

Больше не искать: Visual аккуратно сгладил иерархию папок и поэтому не может аккуратно скомпилировать источник.

В данный момент я просто думаю о переименовании файлов, которые должны решить проблему ...

... но есть ли способ заставить Visual Studio НЕ сгладить иерархию файлов?

Ответы [ 8 ]

129 голосов
/ 13 июня 2011

У меня была похожая проблема с предупреждением компоновщика LNK4042: объект указан более одного раза;дополнения игнорируются .В моем случае Visual Studio пыталась скомпилировать заголовочные и исходные файлы с одинаковыми именами - MyClass.h и MyClass.cpp.Это произошло потому, что я переименовал файл .cpp в .h, и Visual Studio запуталась.Я заметил проблему, посмотрев журналы компилятора в каталоге Debug.Чтобы решить проблему, просто удалите файл .h из проекта и добавьте его снова.

96 голосов
/ 17 сентября 2010

Я просто хотел сделать кросс-пост, который я считаю ответом, если вы откроете свойства для всего проекта и измените значение в C/C++ -> Output Files -> "Object File Name" на следующее:

$ (IntDir)/% (RelativeDir) /

В VS 2010, я полагаю, это устранит неоднозначность всех объектных файлов (так как я считаю, что Windows не позволит вам при любых безумных обстоятельствах иметь два файла с одинаковыми именами в одном и том жекаталог).Пожалуйста, также проверьте детали здесь .

8 голосов
/ 12 сентября 2010

Щелкните правой кнопкой мыши файл .cpp в окне обозревателя решений, выберите Свойства, C / C ++, Выходные файлы, Имя файла объекта.По умолчанию $(IntDir)\, это то, что делает выравнивание.Весь файл .obj будет помещен в $ (IntDir), каталог «Debug» в конфигурации отладки.

Вы можете изменить настройку, скажем, $(IntDir)\is2.obj.Или выберите все файлы из одной группы (используйте Shift + клик) и измените настройку, скажем, $(IntDir)\identity\

. Или вы можете изменить имя файла .cpp, чтобы файлы .obj не перезаписывали друг друга,Наличие файлов с одинаковым именем в двух каталогах немного странно.

Или вы можете создать несколько проектов, например, проекты .lib для файлов в идентичности и диапазоне.Обычно делается в проектах makefile, например.Это, однако, делает управление настройками компиляции и ссылки более сложным, если вы не используете листы свойств проекта.

5 голосов
/ 01 января 2015

Щелкните правой кнопкой мыши файл заголовка -> Свойство -> ItemType (выберите заголовок C / C ++).Сделайте то же самое с файлом Cpp, но выберите C / C ++ COmpiler (это работает для меня)

4 голосов
/ 20 марта 2013

Я использую $ (IntDir) \% (Directory) \ в C / C ++ -> Выходные файлы -> «Имя файла объекта».

3 голосов
/ 06 марта 2013

В качестве альтернативы удалению и созданию нового файла вы можете изменить параметры компиляции / включения.

Перейдите к файлу project.vcxproj , откройте его в редакторе, найдите html-строку <ItemGroup>.

Это должно выглядеть примерно так:

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

и

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

Предполагается, что ваши файлы реализации - .cpp, а ваши объявления - .hpp. Убедитесь, что все ваши файлы реализации перечислены между первым разделом, если у вас их больше одного, а также для второго раздела для нескольких файлов объявлений.

3 голосов
/ 11 января 2013

У меня была эта проблема с stdafx.cpp. Каким-то образом stdafx.cpp дублировался, поэтому появился второй StdAfx.cpp (обратите внимание на другой случай).

После того как я удалил StdAfx.cpp, все заработало нормально!

Использование VS 2010.

2 голосов
/ 16 марта 2017

Раньше у меня в одном проекте были .c и .cpp файлы с одинаковыми именами файлов . Файлы были в папках повсюду, и решения, предоставленные другими, создали беспорядок, и ад папки (в моем случае). Даже Release builds перезаписывают Debug builds!

Хорошим (не идеальным) решением было бы использование $ (ParentName), но по какой-то непонятной причине он был удален из более поздних версий Visual Studio (2015 +).

Теперь я успешно использую: $ (IntDir)% (Filename)% (Extension) .obj

, который по крайней мере отделяет .c встроенные объектные файлы от .cpp .

...