Właśnie uderzyło mnie (raczej nie) w głowę jakieś nietrywialne ostrzeżenie ze strony Visual Studio 2010 (C ++).
Kompilacja dała następujący wynik:
1 Debug \ is.obj: ostrzeżenie LNK4042: obiekt określony więcej niż raz; dodatki ignorowane
1 Debugowanie \ make.obj: ostrzeżenie LNK4042: obiekt określony więcej niż raz; dodatki ignorowane
1 Debugowanie \ view.obj: ostrzeżenie LNK4042: obiekt określony więcej niż raz; dodatki zignorowane
1 identity.obj: błąd LNK2019: nierozwiązany symbol zewnętrznyvoid __cdecl test::identity::view(void)
(? view @ identity @ test @@ YAXXZ), do którego odwołuje się funkcjavoid __cdecl test::identity::identity(void)
(? identity @ 0test @@ YAXXZ)
1 identity.obj: błąd LNK2019: nierozwiązany symbol zewnętrznyvoid __cdecl test::identity::make(void)
(? make @ identity @ test @@ YAXXZ), do którego odwołuje się funkcjavoid __cdecl test::identity::identity(void)
(? identity @ 0test @@ YAXXZ)
1 zakres.obj: błąd LNK2019: nierozwiązany symbol zewnętrznyvoid __cdecl test::range::is(void)
(? is @ zakres @ test @@ YAXXZ), do którego odwołuje się funkcjavoid __cdecl test::range::range(void)
(? zakres @ 0test @@ YAXXZ)
Błędy konsolidatora są zawsze trudne do debugowania ... ale były nierozwiązane odniesienia, więc sprawdziłem ... ale źródło jest dobrze sformułowane ... iw końcu dotarło do mnie:
Moja hierarchia folderów wygląda następująco:
src/
identity/
is.cpp
make.cpp
view.cpp
range/
is.cpp
make.cpp
view.cpp
tak samo jak hierarchia w rozwiązaniu (zawsze konfiguruję ją tak, aby naśladowała „prawdziwą” strukturę folderów).
Oraz wyjścia diagnostyczne:
Debug\is.obj
Debug\make.obj
Debug\view.obj
Wraz z ostrzeżeniem, które mówi, że .obj
został przekazany dwukrotnie do konsolidatora i ten zostanie zignorowany.
Nie szukaj więcej: Visual porządnie spłaszczył moją hierarchię folderów i dlatego nie jest w stanie starannie skompilować źródła.
W tej chwili myślę po prostu o zmianie nazw plików, które powinno rozwiązać problem ...
... ale czy istnieje sposób, aby program Visual Studio NIE spłaszczył hierarchii plików?
źródło
Odpowiedzi:
Chciałem tylko zamieścić coś, co uważam za odpowiedź, jeśli otworzysz właściwości dla całego projektu i zmienisz wartość poniżej
C/C++ -> Output Files -> "Object File Name"
na następującą:$ (IntDir) /% (RelativeDir) /
Uważam, że w VS 2010 ujednoznaczni to wszystkie pliki obiektowe (uważam, że Windows w żadnych szalonych okolicznościach nie pozwoli ci mieć dwóch plików o tych samych nazwach w tym samym katalogu). Sprawdź również szczegóły tutaj .
źródło
cl.exe
w CLI?Miałem podobny problem z ostrzeżeniem konsolidatora LNK4042: obiekt określony więcej niż raz; dodatki ignorowane . W moim przypadku program Visual Studio próbował skompilować zarówno pliki nagłówkowe, jak i pliki źródłowe o tej samej nazwie -
MyClass.h
iMyClass.cpp
. Stało się tak, ponieważ zmieniłem nazwę.cpp
pliku na.h
i program Visual Studio się pomylił. Zauważyłem problem, patrząc na dzienniki kompilatora wDebug
katalogu. Aby rozwiązać problem, po prostu usuń.h
plik z projektu, a następnie dodaj go ponownie.źródło
foo.h
plik w eksploratorze rozwiązań i ustawić „Typ elementu” na „Nagłówek C / C ++” zamiast „Kompilator C / C ++”.CLInclude
wpisKliknij prawym przyciskiem myszy plik .cpp w oknie Eksplorator rozwiązań, właściwości, C / C ++, pliki wyjściowe, ustawienie nazwy pliku obiektu. Domyślnie to
$(IntDir)\
właśnie powoduje spłaszczanie. Cały plik .obj trafi do $ (IntDir), katalogu „Debug” w konfiguracji debugowania.Na przykład możesz zmienić to ustawienie
$(IntDir)\is2.obj
. Lub wybierz wszystkie pliki z jednej grupy (użyj Shift + kliknięcie) i zmień ustawienie na, powiedzmy,$(IntDir)\identity\
Możesz też zmienić nazwę pliku .cpp, aby pliki .obj nie nadpisywały się nawzajem. Posiadanie plików o dokładnie tej samej nazwie w dwóch katalogach jest trochę dziwne.
Lub możesz tworzyć wiele projektów, tworząc, powiedzmy, projekty .lib dla plików w tożsamości i zakresie. Często jest to wykonywane na przykład w projektach makefile. To jednak sprawia, że zarządzanie ustawieniami kompilacji i łączenia jest bardziej kłopotliwe, chyba że używasz arkuszy właściwości projektu.
źródło
$(IntDir)
poszczególne pliki w arkuszu właściwości? Wiem, że możesz ustawić to dla całego projektu w arkuszu właściwości, ale nie wiem, czy możesz to ustawić na podstawie ścieżki kompilowanego pliku. (Domyślam się, że nie, ale jestem kompletnym noobem MSBuild)Kliknij prawym przyciskiem myszy plik nagłówkowy -> Właściwość -> ItemType (wybierz nagłówek C / C ++ ). Zrób to samo z plikiem Cpp, ale wybierz kompilator C / C ++ (to działa dla mnie)
źródło
Używam $ (IntDir) \% (Directory) \ w C / C ++ -> Output Files -> "Object File Name".
źródło
Alternatywnie do usunięcia i utworzenia nowego pliku możesz zmienić ustawienia kompilacji / dołączania.
Przejdź do pliku project.vcxproj , otwórz go w edytorze, znajdź linię podobną do html
<ItemGroup>
.Powinien wyglądać mniej więcej tak:
<ItemGroup> <ClCompile Include="implementation.cpp" /> </ItemGroup>
i
<ItemGroup> <ClInclude Include="declaration.hpp" /> </ItemGroup>`
Zakładając, że pliki implementacji to .cpp, a deklaracje to .hpp. Upewnij się, że wszystkie pliki implementacji są wymienione między pierwszą sekcją, jeśli masz więcej niż jedną, a także drugą sekcją dla wielu plików deklaracji.
źródło
Miałem ten problem z stdafx.cpp. W jakiś sposób stdafx.cpp został zduplikowany, więc był drugi StdAfx.cpp (pamiętaj o innym przypadku).
Po usunięciu StdAfx.cpp wszystko działało dobrze!
Korzystanie z VS 2010.
źródło
Kiedyś miałem w tym samym projekcie pliki .c i .cpp z tymi samymi nazwami plików . Pliki były w folderach wszędzie, a rozwiązania dostarczone przez innych stworzyły bałagan i folder piekło (w moim przypadku). Nawet kompilacje wydania nadpisałyby kompilacje debugowania !
Dobrym (nie idealnym) rozwiązaniem byłoby użycie $ (ParentName), ale z jakiegoś niezrozumiałego powodu zostało ono usunięte z późniejszych wersji programu Visual Studio (2015+).
Teraz z powodzeniem używam: $ (IntDir)% (Filename)% (Extension) .obj
co przynajmniej oddziela skompilowane pliki obiektów .c od .cpp .
źródło