views:

190

answers:

3

After going through a lengthy process to rename a project, my DLL project will not build in Debug mode (Release builds work):

MSVCRTD.lib(msvcr90d.dll) : error LNK2005: _CrtDbgReportW already defined in LIBCMTD.lib(dbgrpt.obj)

This project, and the five static libraries it depends on, are set to use "Multi-threaded Debug (/MTd)" (under C/C++|Code Generation|Runtime Library). I believe LIBCMTD.lib is the one for multi-threaded debug, but what is MSVCRTD.lib, and what could be causing this error?

If it makes a difference, this DLL is for Windows CE.

+2  A: 

LIBCMT is what you need for /MT, MSVCRT is what you need for /MD. You are linking .obj and .lib files that were mixed, some compiled with /MT some with /MD. That's not good.

Usually it is the .lib files that cause the problem. Review their build settings and make sure their /M option is the same as your DLL project.

Also, beware of the trouble you can get into if the DLL was compiled with /MT. You'll have major problems when the DLL returns pointers to objects that the client needs to release. It can't, it doesn't use the same memory allocator.

Hans Passant
You may also find information about the runtime library used for compilation and linking under the C++/Code Generation node of the project properties for any of your projects in the IDE.
ReWrite
You are probably right. I forgot about a sixth library that I got from another developer. It seems that the Release build worked because Visual Studio randomly decided to use dynamic linking for it (despite my request for static linking), while the Debug build tried to use static linking (causing a linker error when linking to the library).
Qwertie
Thanks for mentioning memory management as a potential problem, but it shouldn't be a problem in my case because my DLL is a COM DLL. In fact, my app replaces global operators new and delete with a custom memory manager, but this is not a problem for clients since COM isolates memory management.
Qwertie
It doesn't, actually, it centralizes it. CoTaskMemAlloc and the IMalloc interface.
Hans Passant
A: 

What is release set too? Setting a DLL to multithreaded debug can cause problems if you allocate memory that something accesing the DLL tries to free (they will be allocated in different heaps, for example). Try setting multi-threaded debug DLL.

Your link problem probably arises because a library you are linking to is expecting multithreaded debug DLL so the linker tries to link both and your link fails ...

Goz
+1  A: 

The MSDN article on LNK4098 has a very useful table: it tells you which libraries to manually add to the "Ignore specific library" list, depending on which CRT you're using. In your case, you should ignore all of these:

libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib

Observe that the reported library is in this list too. The problem is described in more detail in KB154753 ... libraries that a program will link with when built by using Visual C++

My interpretation of this is that in certain situations the algorithm that automatically picks which CRT libraries to link your code with will pick several conflicting libraries.

romkyns