views:

155

answers:

4

I'm having some strange issues building and running a project on another computer. It's a side-by-side error. Usually the cause is that c++ redistributable is not installed on the machine etc. However in this case the project is compiled on that machine. MSVC++ 2005 is installed, the runtimes should be there (I installed the runtime again for good measure anyway). Why is the linker referencing a runtime library that isn't available on the machine?

I'm dynamically linking to runtime library.

Any ideas on how to debug this issue?

Thanks.

EDIT

I didn't want to start another post because it's related. Because of this DLL version mess, is this a good reason to statically link to runtime? Will I avoid all these problems? I don't see any advantages to dynamically link to runtime any more. I was under the impression that with DLL runtime you get the benefit of updates/bug fixes with new DLLs. However because of the SxS and manifests it ensures that it loads the specific version (old version) of the DLL anyway? So what's the point of dynamic runtime at all? Maybe a few kb of space saved because you're not embedding the re-used functions in all the dependent libraries. But compare this to the cost of your app won't run because some ancient runtime version is removed from the machine, isn't it worth it?

Thanks again. Still tracing the original problems and will probably have to recompile every single library I'm using.

+1  A: 

Not an answer to the problem, but an answer to this question:

Why is the linker referencing a runtime library that isn't available on the machine?

The linker doesn't need the actual runtime library to link. It just needs (typically), the .lib file at link time. The .lib file tells the linker what the runtime library will provide (as in exported symbols) when the OS locates the dll at runtime.

Dependency Walker can be helpful in cases like this to help debug the problem.

EDIT: followup to the new question. Static linking does resolve these issues, however it also introduces some new issues. You can share dynamically allocated objects between dlls - however, whichever dll allocated the object must be the one to deallocate it. Any methods on the object that allocate/reallocate/deallocate member data/objects similarly must be governed in order to avoid heap corruption. Non-inline refcounting/shared pointers will be helpful. Alternatively, shared mem allocators can be helpful too.

sean e
I see. I'm not even sure if it's the linker that decides to use name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" or the "manifest generator" and the linker embeds the manifest... Very confusing.
Budric
The debug versions of the VC runtime are not distributable. Does the problem occur if you do a release build?
sean e
Yes, both in release and debug. As I mentioned I have the full MSVC installed, so I'm clean/building the project.The project statically links to other libraries (e.g. Poco). Those libraries dynamically link to runtime. Is this the problem? If it is, I don't see how it's possible to do development on more than 1 machine without rebuilding every single piece of code.
Budric
Thanks, I've used DependancyWalker before. It tells me that it relies on MSVC80RT.DLL however that doesn't tell me which one. According to this picture: http://msdn.microsoft.com/en-us/library/aa376307%28VS.85%29.aspx The DLL Loader asks the SxS to load the DLL which looks in the manifest. So the error is occurring at SxS, not at the level of the DLL Loader which is what DependancyWalker is used for...I think...
Budric
If those other libraries have manifest dependencies on specific versions of the runtime, that could be a problem. If for example, they were built using VC2008, and your dev machine doesn't have the VC2008 runtime installed, then that might explain what you are seeing.
sean e
+1  A: 

It may happen when you compile along a third party library, or object files, that you compiled on another machine and the copied on the machine where the issue occurs.

Try to find such binary files on your machine, and recompile them on that machine.

yves Baumes
+3  A: 

sxstrace will tell you exactly what is going on with respect to SxS. It will show what dlls are searched and how they are mapped to actual versions.

Now, which runtime is loaded is coming from the manifest file that gets included in your project. Looking at the one you mention, it looks like the one from Visual2005, with no service pack. SP1 changed the crt to 8.0.50727.762

Some details on sxstrace on vista and XP

Well, since you added a question to your question, let me add an answer to my answer: SxS will not necessarily load the version you specify inside your manifest. The SxS system keeps track of security fixes made to specific versions, e.g. and will change which version it loads even when you ask for a specific version.

That said, if your program uses DLLs, and you want to share C objects (e.g. malloc'ed memory) between them, then your only option is the CRT DLL. It really depends what your constraints are.

Bahbar
8.0.50608.0 is the one that I can't find in c:\windows\WinSxS folder. Thanks, didn't know about sxstrace.
Budric
Have you installed the SP1?
Bahbar
A: 

Here's a possibly related forum post. Not sure if this is the problem, but it seems worth checking.

The summary is that MS updated the ATL, CRT, MFC, and a few other libraries on VS 2005 developer machines via an automatic update.

On machines without VS2005 installed, they only updated the ATL via an automatic update, causing SxS errors.

You can either uninstall the update on the dev machine, or upgrade the runtimes manually on the machine you're trying to run on. Details on the post.

tfinniga