Подтвердить что ты не робот

Visual Studio 2010 странное предупреждение LNK4042 "

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

В результате компиляции был получен следующий результат:

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 НЕ сгладила иерархию файлов?

4b9b3361

Ответ 1

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

$(IntDir)/% (RelativeDir)/

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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

Ответ 5

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

Перейдите в файл project.vcxproj, откройте его с помощью редактора, найдите html как строка <ItemGroup>.

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

<ItemGroup>

<ClCompile Include="implementation.cpp" />

</ItemGroup>

и

<ItemGroup>

<ClInclude Include="declaration.hpp" />

</ItemGroup>

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

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

То, что я использую сейчас, является следующим: $ (IntDir)% (Имя файла)% (расширение).obj

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