This question has been brought up numerous times, but Visual Studio never ceases to challenge me.
We have an application that should be self-sufficient, i.e. not depend on any 3rd party libraries. This is why we build everything statically using the MT(d) code generation flags.
The app depends on Qt, zlib, OpenSSL and DCMTK. All of these libraries were built as static libs with MT(d). The app also uses some MFC-related code, so we also have to link against it.
MFC is included via
#include <afxwin.h>
I read somewhere that this should be the first include in every file, but I'm not sure if it is true. Anyway, the line is not included in every file, only one file includes it.
Here are the link-related errors:
Error 24 error LNK2005: "void __cdecl operator delete[](void *)" (??_V#YAXPAX#Z) already defined in LIBCMTD.lib(delete2.obj) uafxcwd.lib
Error 22 error LNK2005: "void __cdecl operator delete(void *)" (??3#YAXPAX#Z) already defined in LIBCMTD.lib(dbgdel.obj) uafxcwd.lib
Error 23 error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U#YAPAXI#Z) already defined in libcpmtd.lib(newaop.obj) uafxcwd.lib
Error 21 error LNK2005: "void * __cdecl operator new(unsigned int)" (??2#YAPAXI#Z) already defined in LIBCMTD.lib(new.obj) uafxcwd.lib
Here is the linker output.
I read many threads on many sites as well as this article from MSDN's KB. But they don't help me, as all of them keep saying that MFC libs should be linked before CRT, but I cannot find a way to alter the linking order.
Any help is greatly appreciated.
Edit 1:
Using the trick from this thread actually solves the problem, but I still want to know what's wrong here.
Edit 2:
Using Visual Studio 2008 SP1, on Windows 7 and Qt 4.6.3
The problem is clear: you are compiling CRT and MFC code together.
When you use the MFC libraries, you
must make sure that they are linked
before the CRT library is linked. You
can do this by making sure that every
file in your project includes
Msdev\Mfc\Include\Afx.h first, either
directly (#include ) or
indirectly (#include ). The
Afx.h include file forces the correct
order of the libraries, by using the directive:
#pragma comment (lib,"<libname>")
Microsoft has an article (link now gone, but check here) describing this problem and suggests 2 solutions step-by-step (the following steps are based on Visual C++ 6.0):
Solution One: Force Linker to Link Libraries in Correct Order
On the Project menu, click Settings.
In the Settings For view of the Project Settings dialog box, click to select the project configuration that is getting the link errors.
On the Link tab, click to select Input in the Category combo box.
In the Ignore libraries box, insert the library names (for example, Nafxcwd.lib;Libcmtd.lib).
Note: The linker command-line equivalent in /NOD:<library name>.
In the Object/library modules (VS2008: Properties->Configuration Properties->Linker->Input->Additional Dependencies)box, insert the library names. You must make sure that these are listed in order and as the first two libraries in the line (for example, Nafxcwd.lib Libcmtd.lib).
Solution Two: Locate and Correct the Problem Module
To view the current library link order, follow these steps:
On the Project menu, click Settings.
In the Settings For view of the Project Settings dialog box, click to select the project configuration that is getting the link errors.
On the Link tab, type /verbose:lib in the Project Options box.
Rebuild your project. The libraries will be listed in the output window during the linking process.
This was clarified to me on the MSDN Forumns:
http://social.msdn.microsoft.com/Forums/en/vcgeneral/thread/4e331cb3-e566-4ca6-b7d4-118c3bebd31a
Related
PLATFORM
Visual Studio 2010 Proffesional
MY PROBLEM
I have a solution called solution A. I have projects 'a' (static library containing internal and external header and source files) and 'b' (executable to see if 'a' functions can be used).
I intend to use static library 'a' functionality in another executable project 'c' which is in a different Solution C. What I have done is the following:
1) Added the static library folder (relative path) to the Include Directories section in my 'c' project properties (both debug and release configurations).
2) Checked the intellisense messenger to see whether or not the imports were successful.
Before I build solution C, everything was fine. However, as soon as I build it popped LNK2019 error because there is a function foo()that seemed to be unresolved. The (reported) function signatures are:
extern void foo(params);
extern void bar(void);
Just to remind the readers, foo(params) function is in static library 'a' in Solution A.
The error message I got was:
error LNK2001: unresolved external symbol _foo
error LNK2001: unresolved external symbol _bar
MY digagnosis so far
The obvious diagnosis would be that:
1) the function signature reported seem to have a mismatch with my orignal one (I checked using real man's find and replace tool in visual studio; there is no mismatch).
2) Check for any include guards that is blocking it (I have checked once again, but it doesn't have any that will cause this problem).
The one things that I need to mention is that exec. project b in Solution 'C' can use foo and bar in static library a easily. That may be because they are in the same solution and by simply adding the project directory to Include Directories in the project b properties will do the job. But when I try to use it in a different solution, it is breaking down. I did a full clean and rebuild of the solution, but no luck.
I am starting to think that it cannot find the definition in the same header file and gets confused. Although the definition is in the identically-named source file, it may still get confused.
I am struggling to find a solution to this without having a full modification. Does anyone know what to do?
I think I solved this problem by simply using "Add Reference" by right-clicking on the executable project where I was using it. However, I still had to manually import the static library project 'a' into the foreign solution C so that the referencing can be made.
I know it is not probably a good way of doing things, but it is definitely safer and I am pretty sure that it is going to work - one way or the other.
I have an old project that I need to revisit. It was built in some version of Visual C++ (prolly 2005) looking at the .sln file. The sln file wont get converted to a VS 2008 solution due to some corruption (dubug point -1). I imported the folder in VS as a new project and tried compiling.
It gave compilation errors for "lang/Typedefs.h/Assertions.h" not there. Removing the declarations I had errors for Uint8/16/32/64 not declared. So I added the typedefs and other macros (TOOLS_UNUSED_PARAMETERS(x) / TOOLS_FORBID_COPY()).
That being ironed out, I got errors for Gui/FileDlg.h and Gui/FolderDlg.h(debug point - 2).
I didnt find any of those header files from any resources online or in my current VS installation and so I am assuming that code is missing and I will have to redo it.
Even these could probably have been custom implemented by the earlier programmer. The current MFC uses CFileDialog and the code uses Gui::FileDlg.
I commented out the code for the time being to see where can I get to since gui is not that big a part of the application. Later I see linker errors corresponding to RegKeyOpenEx calls and outputstream calls(dubug point -3). Winreg.h was not included but windows.h was.
sample :
Error 2 error LNK2019: unresolved external symbol __imp__MessageBoxA#16
referenced in function "public: class std::basic_ostream<char,struct
std::char_traits<char> > * __thiscall FileManager::getOutputStream(class Interface
*,class LogPoint *)" (?getOutputStream#FileManager##QAEPAV?$basic_ostream#DU?
$char_traits#D#std###std##PAVInterface##PAVLogPoint###Z) filemanager.obj
PCAPGenerator
I am not a .Net programmer so can you please suggest what would be the right course of action here ?
which debug points should i be focussing on.
RegKeyOpenEx is a Winapi function defined in Advapi32.dll. To link that into a Visual C++ project:
If your project is a static library (right-click project->Properties->Configuration Properties->Configuration Type->Static Library (.lib), go to Configuration Properties->Librarian->General->Additional Dependencies and add Advapi32.lib.
If your project is a dll (same place, says Dynamic Library (.dll) instead), you'll have the Linker section instead of Librarian. Go to its Input subsection, and add Advapi32.lib to Additional Dependencies.
For your remaining linker errors, proceed in the same way: go to the MSDN doc for the function, check which dll/lib it belongs to and have your project link it in as described above.
Recently we did some big architectural changes (i.e. mutlithreading support) to our cloud print module. Now I have to run a PreFast check on it, but because the current edition of Visual Studio 2008 that we are using does not have integrated PreFast check support, I have to do it through Windows DDK.
I am trying to build the source with WDK, but I am getting this error.
error LNK2005: "void _cdecl operator delete(void *)" (?3#YAXPAX#Z)
already defined in libcmt.lib (delete.obj)
I believe that the linker used libcpmt.lib at a prior stage and it had the same definition for delete method. The source also has c files and cpp files mixed at different module levels. Could this be the real reason why it is using both libcmp.lib and libcpmt.lib in the first place?
Is there anyway i can fix this? I don't really need a "right" way. All i want is to build the source, so that i can run PreFast check (not really concerned about link related warnings). If it gives any PreFast warning regarding this, i can skip it for the time being.
Sorry to bother anyone with this question, but I've been researching this for hours, with no resolution yet:
I am porting a rather massive application to the 10.0 CRT (compiler) in Visual Studio 2010. The app is managed C++/CLI that uses /clr. Most of the code is native (95%), with a few managed portions here and there in it.
So my job is to make the switch in the .vcxproj to target the newer 10.0 CRT (i.e. compiler). We were previously using v90, or using the VC compiler that came with VS 2008 SP1.
Ok, so breaking changes? Seems like a bunch actually. I fixed a few iterator issues dealing with sets, which all was all pretty easy.
But these linker errors are killing me. Any help would be appreciated:
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0001c0).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2022: metadata operation failed (80131195) : Custom attributes are not consistent: (0x0c0001c5).
...
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??0?$allocator#D#std##$$FQAE#ABV01##Z' (06000141) has inconsistent metadata with (0A000F75) in identity.obj
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??0?$allocator#D#std##$$FQAE#ABV01##Z' (06000141) has inconsistent metadata with (0A000F76) in ICustAttribCollapseManagerImp.obj
... (repeated hundreds of times)
I went ahead and undecorated the symbol:
??0?$allocator#D#std##$$FQAE#ABV01##Z
and got:
public: __thiscall std::allocator<char>::allocator<char>(class std::allocator<char> const &)
So, as I understand it, the msvcmrtd.lib file has this std::allocator compiled one way, and something else in my project settings (#pragma managed ??) is compiled another, different way. But if so, what do I look for? This has been compiling fine for years using the old compilers.
Note:
We currently the 3.5 .NET framework (Not sure if that helps or not... I doubt it)
Thanks
This is a hard to diagnose problem, the linker errors stink and are poorly documented. There's a post from Stephan Lavavej, the STL maintainer at Microsoft about it in this thread, bottom of the page. I have to say I don't see much of any advice in it, beyond trying to disable iterator debugging in your project settings (_HAS_ITERATOR_DEBUGGING = 0 in the preprocessor definitons).
You do need to consider a code review. It sure looks like you are compiling STL code into managed code. That works in general (minus the linker hassle) but it is really the wrong thing to do. Leave the STL collection classes to your native code, use the BCL collection classes (List<> etc) in your managed code.
for anyone like me that this answer did not ring helpful, a second option is to go to:
Project Properties->Configuration Properties->General->Project Defaults->.NET Target Framework Version and set it to v4.0
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/806238/unwarranted-linker-errors-using-stl-filestream-class-in-managed-classes-in-c-11-cli has an obscure answer from Microsoft team that fixed my issue.
In my case what helped was changing the TargetFramework in the .VCXPROJ to :
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
But as you've mentioned you need to compile against 3.5 I am not sure what you can do in that case.
I recently migrated a VS2008 project to VS2012 that included a C++/cli project and experienced these errors. I'm pretty anal retentive when it comes to my project/build files so I setup some custom .props msbuild files that the projects all import from (to avoid all the repeated and Condition riddled elements in the msbuild XML).
So pretend the project was Example.vcxproj. and near the start I had this:
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110_xp</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
<CLRSupport>true</CLRSupport>
<-- Including this here fixed my linker problems -->
<!--<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>-->
</PropertyGroup>
...
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
...
<Import Project="$(SolutionDir)..\shared\config\msbuild\FileWithCommonSettings.props" />
I had my FileWithCommonSettings.props file (where I have -TargetFrameworkVersion- defined) being included -after- Microsoft.Cpp.props. I instead opted to try setting -TargetFrameworkVersion- before Cpp.props, as you can see in the commented out XML. Doing this fixed all the linker issues I was getting. My guess is that Cpp.Default.props defaults to v4.0 in VS2010 and later.
Hope this helps
edit: Refering to this social.msdn thread, it would appear you need to use VS2010 (ie, toolset v100) in order to actually target v3.5. I didn't realize I was silently targeting 4.0 still with vc110...but it was only after I added that -TargetFrameworkVersion- element did I get rid of the linker errors. After switching to vc100 toolset the linker errors came back.
Although my solution to this issue does not address why it happens, I'm noting my observations in case anyone else comes across my same scenario.
I too received similar errors compiling my clr project. My goal was to upgrade my version to 11.0, but retain .NET framework 2.0 as the target. In my case, I saw Lnk2034 and lnk2020 errors (different from the lnk2022 noted above).
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2034: metadata inconsistent with COFF symbol table: symbol '?_Facet_Register_m#std##$$FYAXPAV_Facet_base#1##Z' (06000068) has inconsistent metadata with (0A000C23) in DirectSystemAccessProxy.obj
1>LINK : error LNK2034: metadata inconsistent with COFF symbol table: symbol '??3#$$FYAXPAX#Z' (060003CB) has inconsistent metadata with (0A00009D) in MSVCMRTD.lib(locale0_implib.obj)
...
1>myProject.obj : error LNK2020: unresolved token (0A000C23) "void __cdecl std::_Facet_Register_m(class std::_Facet_base *)" (?_Facet_Register_m#std##$$FYAXPAV_Facet_base#1##Z)
1>MSVCMRTD.lib(locale0_implib.obj) : error LNK2020: unresolved token (0A0000C4) "extern "C" void __cdecl free(void *)" (?free##$$J0YAXPAX#Z)
...
Initially, I was following Hans Passat's advice by correcting the use of the native containers in this project. I commented out all instances of those containers to verify that they were indeed the cause of failure.
During the investigation, I discovered that the following line caused my error:
std::wstringstream wstream;
wstream << " Failed to to do something \'" << var << "\'.";
The moment I corrected it to the following, those errors went away.
std::wstringstream wstream;
wstream << L" Failed to to do something \'" << var << L"\'."; // Added wide string literal.
No idea why such a line would cause this behaviour, but it did.
Side Note:
Targeting a higher .NET framework (4.0) also worked, but I wanted to stick to target the original .NET framework of 2.0.
My project did not have the preprecossor definition: _HAS_ITERATOR_DEBUGGING = 0. To my understanding, compiling _HAS_ITERATOR_DEBUGGING in /clr is no longer supported (See link in Hans Passat's answer)
I want to build a DLL to use it as an IIS/ISAPI application. So far so good. It works. However, I have to drag arround the runtime dll and other dependencies (like some boost libraries).
I would like to make a single DLL (in order to ease the deployment on multiple servers).
So I changed the switch from /MD to /MT. However, now I get errors of duplicate symbols during link. For example :
msvcprtd.lib(MSVCP100D.dll) : error LNK2005: "public: void __thiscall std::basic_ostream<char,struct std::char_traits<char> >::`vbase destructor'(void)" (??_D?$basic_ostream#DU?$char_traits#D#std###std##QAEXXZ) already defined in gateway.obj
I'm puzzled that /MD or /MT are compiler flags and not linkers flags. And it could in some way explain why I get duplicated symbols (as the will be included in each .obj).
So the question is: how do I configure visual studio 10 in order to get a dll that includes all its dependencies.
The /MD and /MT switches only apply to the Microsoft C runtime library and not 3rd party libraries. This documentation gives some information on why it is a compiler switch (they cause different defines to be created during the compilation).
Pulling 3rd party DLLs directly into your own DLL as static libraries is probably not a simple process unless static libraries already exist. I don't know of any standard method for turning a DLL into a static library. A quick Internet search indicates that there exist tools that claim to do that process (my quick search did not turn up any free ones). But I think the most robust solution would be to use existing static libraries if you can. I believe you can build static versions of the Bools libraries, which you could then specify in your link statement in Visual Studio (as opposed to naming the libraries for the DLLs).