Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VC8 to VC10 - LNK2005 errors

I recently installed Visual Studio 2010 and used CMake to generate the solution files for my project. This process had previously worked fine on VS2005.

The first issue I encountered was because of the new "move constructors", so I had to remove some implicit conversions from my code — fair enough, that works now.

My current situation is as follows: I am compiling DLL 1, which is dependent only on some system libraries (Kernel32, etc) and the CRT, and DLL 2, which links to DLL 1, as well as some third party libraries.

The errors I get are along the lines of:

DLL1.lib(DLL1.dll) : error LNK2005: "public: __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::~basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(void)" (??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ) already defined in objFromDLL2.obj

This appears to be exactly the problem described here.

However, nothing in this thread solves my problem.

  • I have confirmed that both DLL1 and DLL2 are compiled with the /MD Code Generation flag,
  • DLL2 links to squish, glew, and devil — I have manually recompiled all of these and any libraries they depend on for VC10, also with /MD
  • edit As per this article (which is similar to my problem), I have removed any instances of classes deriving from std:: containers
  • edit I have confirmed this is not a 3rd party issue, as I have compiled another project successfully using the same set of libraries, however I still cannot compile my original project
  • edit dllexport is being used in all required places in my code

What am I missing? Please let me know if I need to provide more information and I will edit the question as best I can.

update: It's been a while and I still have no solution. I've been updating the question with responses to comments, and I'm currently working on a different codebase which does work - I'm starting to think that the backwards compatibility for older code has finally started to dry up, and I should just move on.

more update: I've found what's probably a very undesirable linker flag, /FORCE:MULTIPLE, which turns the errors into warnings by ignoring all but the first definition of the symbols. There must be bad side-effects of doing this. A test of this flag highlighted an LNK2001: unresolved std::string::npos, which was buried in all the previous LNK2005 errors. The torment never ends.

like image 611
badgerr Avatar asked Apr 08 '11 10:04

badgerr


1 Answers

I have used /FORCE:MULTIPLE successfully. It is sometimes inevitable when using a mixed bag of libraries. As long as the linker uses the one & same address to consistently resolve the reference, it works. The other definitions are ignored.

like image 191
Pierre Avatar answered Oct 11 '22 01:10

Pierre