L’étrange “avertissement LNK4042” de Visual Studio 2010

Je viens juste d’être battu (plutôt difficilement) par un avertissement non sortingvial de Visual Studio 2010 (C ++).

La compilation a donné le résultat suivant:

1 Debug \ is.obj: warning LNK4042: object spécifié plus d’une fois; extras ignorés
1 Debug \ make.obj: warning LNK4042: object spécifié plus d’une fois; extras ignorés
1 Debug \ view.obj: warning LNK4042: object spécifié plus d’une fois; extras ignorés
1 identity.obj: error LNK2019: symbole externe non résolu void __cdecl test::identity::view(void) (? View @ identity @ test @@ YAXXZ) référencé dans la fonction void __cdecl test::identity::identity(void) ( ? identité @ test @ YAXXZ)
1 identity.obj: error LNK2019: symbole externe non résolu void __cdecl test::identity::make(void) (? Make @ identity @ test @@ YAXXZ) référencé dans la fonction void __cdecl test::identity::identity(void) ( ? identité @ test @ YAXXZ)
1 range.obj: error LNK2019: symbole externe non résolu void __cdecl test::range::is(void) (? Is @ range @ test @@ YAXXZ) référencé dans la fonction void __cdecl test::range::range(void) ( ? range @ 0test @@ YAXXZ)

Les erreurs de linker sont toujours difficiles à déboguer … mais il y avait des références non résolues, et j’ai donc vérifié … mais la source est bien formée … et enfin ça m’a frappé:

Ma hiérarchie de dossiers ressemble à ceci:

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

tout comme la hiérarchie de la solution (je la configure toujours de manière à reproduire la structure de dossiers “réelle”).

Et les sorties de diagnostic:

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

Avec un avertissement indiquant que le .obj a été transmis deux fois à l’éditeur de liens, celui-ci sera ignoré.

Ne cherchez plus: Visual a bien aplati la hiérarchie de vos dossiers et ne peut donc pas comstackr soigneusement le source.

Pour le moment, je pense simplement à renommer les fichiers, cela devrait couvrir le problème …

… mais existe-t-il un moyen pour Visual Studio de ne pas aplatir la hiérarchie des fichiers?

Je voulais juste publier ce que j’estime être la solution, si vous ouvrez les propriétés de l’ensemble du projet et modifiez la valeur sous C/C++ -> Output Files -> "Object File Name" comme suit:

$ (IntDir) /% (RelativeDir) /

Sous VS 2010, je pense que cela va désambiguïser tous les fichiers objects (car je pense que Windows ne vous laissera pas faire deux fichiers avec les mêmes noms dans le même répertoire). S’il vous plaît vérifier également les détails ici .

J’ai eu un problème similaire avec l’avertissement de l’éditeur de liens LNK4042: object spécifié plus d’une fois; extras ignorés . Dans mon cas, Visual Studio essayait de comstackr les fichiers en-tête et source avec le même nom – MyClass.h et MyClass.cpp . Cela s’est produit parce que j’ai renommé le fichier .cpp en .h et que Visual Studio a été confondu. J’ai remarqué le problème en consultant les journaux du compilateur dans le répertoire Debug . Pour résoudre, supprimez simplement le fichier .h du projet, puis rajoutez-le.

Cliquez avec le bouton droit sur le fichier .cpp dans la fenêtre Explorateur de solutions, Propriétés, Paramètres C / C ++, Fichiers de sortie, Nom du fichier object. La valeur par défaut est $(IntDir)\ , c’est ce qui fait l’aplatissement. Tout le fichier .obj ira dans $ (IntDir), le répertoire “Debug” dans la configuration de débogage.

Vous pouvez modifier le paramètre, par exemple $(IntDir)\is2.obj . Ou sélectionnez tous les fichiers d’un groupe (utilisez Maj + Clic) et changez le paramètre pour dire $(IntDir)\identity\

Ou vous pouvez changer le nom de fichier .cpp pour que les fichiers .obj ne s’écrasent pas. Avoir des fichiers avec exactement le même nom dans deux répertoires est un peu bizarre.

Vous pouvez également créer plusieurs projets en créant, par exemple, des projets .lib pour les fichiers d’identité et de scope. Généralement réalisé dans des projets de makefile par exemple. Cela rend toutefois la gestion des parameters de compilation et de liaison plus compliquée à moins que vous n’utilisiez les feuilles de propriétés du projet.

Faites un clic droit sur le fichier d’en-tête -> Propriété -> ItemType (sélectionnez en-tête C / C ++). Faites la même chose avec le fichier Cpp mais sélectionnez C / C ++ COmstackr (ça marche pour moi)

J’ai eu ce problème avec stdafx.cpp. En quelque sorte, stdafx.cpp a été dupliqué, il y avait donc un second StdAfx.cpp (attention aux différents cas).

Après avoir enlevé le StdAfx.cpp, tout fonctionnait bien!

Utilisation de VS 2010.

J’utilise $ (IntDir) \% (Directory) \ sous C / C ++ -> Fichiers de sortie -> “Nom du fichier object”.

Sinon, vous pouvez supprimer et créer un nouveau fichier en modifiant les parameters de compilation / inclusion.

Accédez à votre fichier project.vcxproj , ouvrez-le avec un éditeur, recherchez le fichier HTML comme la ligne .

Il devrait ressembler à quelque chose comme:

    

et

   ` 

En supposant que vos fichiers d’implémentation sont .cpp et que vos déclarations sont .hpp. Assurez-vous que tous vos fichiers d’implémentation sont listés entre la première section si vous en avez plus d’une et de même pour la deuxième section pour plusieurs fichiers de déclaration.

J’avais l’habitude d’avoir dans le même projet des fichiers .c et .cpp avec les mêmes noms de fichiers . Les fichiers étaient dans des dossiers partout et les solutions fournies par d’autres créaient un désordre, et un enfer de dossier (dans mon cas). Même les versions Release écraseraient les builds Debug !

Une bonne solution (non parfaite) consisterait à utiliser $ (ParentName), mais pour une raison quelconque, hors de scope de la main, elle a été supprimée des versions ultérieures de Visual Studio (2015+).

Ce que j’utilise avec succès maintenant est: $ (IntDir)% (Nom de fichier)% (Extension) .obj

qui sépare au moins les fichiers d’object .c construits de .cpp .