Visual Studio 2010 странное "предупреждение LNK4042"
Меня только что избили (довольно тяжело) по голове каким-то нетривиальным предупреждением из 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)
(? Тождественное @0test@@YAXXZ)
1 identity.obj: ошибка LNK2019: неразрешенный внешний символvoid __cdecl test::identity::make(void)
(?make@identity@test@@YAXXZ) упоминается в функцииvoid __cdecl test::identity::identity(void)
(? Тождественное @0test@@YAXXZ)
1 range.obj: ошибка LNK2019: неразрешенный внешний символvoid __cdecl test::range::is(void)
(?is@range@test@@YAXXZ) ссылка на функциюvoid __cdecl test::range::range(void)
(? Диапазон @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 НЕ сгладить иерархию файлов?
11 ответов
Просто хотел опубликовать то, что я считаю ответом, если вы откроете свойства для всего проекта и измените значение в C/C++ -> Output Files -> "Object File Name"
быть следующим:
$ (IntDir) /% (RelativeDir) /
Я полагаю, что в VS 2010 это устранит неоднозначность всех объектных файлов (так как я полагаю, что windows не позволит вам ни при каких сумасшедших обстоятельствах иметь два файла с одинаковыми именами в одном каталоге). Пожалуйста, также проверьте детали здесь.
У меня была похожая проблема с предупреждением компоновщика LNK4042: объект указан более одного раза; Экстры игнорируются. В моем случае Visual Studio пыталась скомпилировать заголовочные и исходные файлы с одинаковыми именами. MyClass.h
а также MyClass.cpp
, Это произошло потому, что я переименовал .cpp
подать в .h
и Visual Studio запутался. Я заметил проблему, посмотрев журналы компилятора в Debug
каталог. Чтобы решить просто удалить .h
файл из проекта, затем добавьте его снова.
Щелкните правой кнопкой мыши файл.cpp в окне обозревателя решений, выберите Свойства, C/C++, Выходные файлы, Имя файла объекта. По умолчанию $(IntDir)\
Вот что делает уплощение. Весь файл.obj будет помещен в $(IntDir), каталог "Debug" в конфигурации отладки.
Вы можете изменить настройку, скажем, $(IntDir)\is2.obj
, Или выберите все файлы из одной группы (используйте Shift+ клик) и измените настройку, скажем, $(IntDir)\identity\
Или вы можете изменить имя файла.cpp, чтобы файлы.obj не перезаписывали друг друга. Наличие файлов с одинаковым именем в двух каталогах немного странно.
Или вы можете создавать несколько проектов, например, проекты.lib для файлов в идентичности и диапазоне. Обычно делается в проектах makefile, например. Это, однако, делает управление настройками компиляции и ссылки более сложным, если вы не используете листы свойств проекта.
Щелкните правой кнопкой мыши файл заголовка -> Свойство -> ItemType (выберите заголовок C/C++). Сделайте то же самое с файлом Cpp, но выберите C/C++ COmpiler (это работает для меня)
В качестве альтернативы удалению и созданию нового файла вы можете изменить параметры компиляции / включения.
Перейдите к файлу project.vcxproj, откройте его в редакторе, найдите строку, похожую на HTML <ItemGroup>
,
Это должно выглядеть примерно так:
<ItemGroup>
<ClCompile Include="implementation.cpp" />
</ItemGroup>
а также
<ItemGroup>
<ClInclude Include="declaration.hpp" />
</ItemGroup>`
Предполагая, что ваши файлы реализации -.cpp, а ваши объявления -.hpp. Убедитесь, что все ваши файлы реализации перечислены между первым разделом, если у вас их больше одного, а также для второго раздела для нескольких файлов объявлений.
Я использую $(IntDir)\%(Directory)\ в C/C++ -> Выходные файлы -> "Имя файла объекта".
У меня была эта проблема с stdafx.cpp. Каким-то образом stdafx.cpp был продублирован, поэтому появился второй StdAfx.cpp (обратите внимание на другой случай).
После того как я удалил StdAfx.cpp все работало нормально!
Использование VS 2010.
Я имел обыкновение иметь в одном проекте файлы .c и .cpp с одинаковыми именами файлов. Файлы были в папках повсюду, и решения, предоставленные другими, создали беспорядок и ад папки (в моем случае). Даже сборки Release перезаписывают сборки Debug!
Хорошим (не идеальным) решением было бы использование $ (ParentName), но по какой-то непонятной причине он был удален из более поздних версий Visual Studio (2015+).
Теперь я успешно использую: $(IntDir)%(Filename)%(Extension).obj
который по крайней мере отделяет встроенные объектные файлы .c от .cpp.
Я хотел бы указать на одну возможную причину, по которой
ItemType
из
.h file
изменится с
C/C++ header
к
C/C++ compiler
:
- в
Solution Explorer
окно VS (2019 здесь), щелкните правой кнопкой мыши имя проекта, выберитеAdd -> New Item
; - Выберите
C++ File (.cpp)
шаблон, но введите в поле ввода имени и щелкнитеOK
добавить его; - Тогда вы столкнетесь с
LNK4042
предупреждение, еслиsomething.h
файл должен быть включен более чем в один.cpp
файлы.
Я только что преодолел похожее сообщение об ошибке и многое другое с помощью описанной ниже процедуры. Симптом: одна ошибка компоновщика при каждом вызове каждой функции, определенной в определенном заголовке, плюс одна ошибка в конце вывода для каждой функции, определенной в заголовке.
Затем я вспомнил, что когда я изначально создавал этот заголовок, я случайно выбрал «add->new item->c++ file», и хотя я назвал его «something.h», похоже, Visual Studio посчитала их оба одинаковыми типами файлов. из-за неправильного действия я добавил его. Это стало очевидным при изучении журналов вывода сборки.
РЕШЕНИЕ (с использованием VS Community 2019)
- Сначала сделайте резервную копию проекта (на всякий случай).
- Щелкните правой кнопкой мыши файл заголовка с нарушением и выберите «Исключить из проекта» (это не удалит их; проект VS просто проигнорирует их).
- Сделайте то же самое для соответствующего файла .c или .cpp.
- Сделайте сборку-> Очистить проект
- Сделайте Build-> Rebuild on project - конечно будут ошибки ---
- Щелкните правой кнопкой мыши заголовочные файлы-> Добавить-> Существующий элемент, затем выберите файл .h
- Щелкните правой кнопкой мыши Исходные файлы-> Добавить-> Существующий элемент, выберите файл .c или .cpp.
- Сделайте Build-> Rebuild on project.
Это полностью очистило его для меня, избавив меня от многих раздражающих ошибок компоновщика, включая LNK4042 из заголовка этого вопроса.
Я разрешил это, изменив имена файлов в моем проекте. Было два файла с именами main.c и main.cpp. Я поменял один из них и заработал.