tags:

views:

2141

answers:

4

I have read arguments on both sides about whether one should link to the C runtime library statically or dynamically in Visual Studio projects, and I'm still not entirely sure what to think.

My project pulls in some third-party libraries (Python, HDF5, Trilinos, and Microsoft MPI), each of which has to be built with the same runtime library as my final executable (otherwise they cannot be linked together). When linking statically, each of these libraries will contain a copy of the C runtime. I read that this is liable to cause issues because the final executable will contain multiple copies of the runtime, none of which can interact with each other. But wouldn't the linker complain if the same symbols were multiply defined?

I would like to avoid "DLL Hell" but am worried about insidious errors that could arise from statically linking in multiple copies of the runtime. Am I reading things wrong?

Also, I'm using Visual Studio 2005 and I read that the Service Pack 1 runtime is not backwards-compatible. Does this mean that an app built without SP1 will not run on a machine that has the SP1 dlls, even if they have the same name (e.g. msvcr80.dll)?

A: 

Static libraries don´t need to be statically linked to other static libraries. You only need to link all static libraries in your main project. That way the compiler will not complain about multiple symbols.

fbinder
To clarify: I do not link the libraries to each other, and I do not get multiply-defined symbols when I link my main executable. But I'm unsure about whether there a multiple copies of the C runtime in my executable, which is what happens when you link to it statically (according to my interpretation of what I've read, which may be wrong).
+1  A: 

... Do it statically... attempts to fix DLL Hell haven't worked out that well... just add an extra 200k to your installation with the static linkage.

CookieOfFortune
Any thoughts on the multiple copies of the runtime? That's my real question.
There will be multiple copies of a runtime floating around anyways. That's what the WinSxS folder is for (and that is an attempt to fix DLL Hell). It's confusing though, so packaging your own runtime will just avoid such issues.
CookieOfFortune
+6  A: 

Linking statically will bloat all your EXEs and DLLs, and can cause crashes (eg. if code in one DLL calls free() with a pointer allocated by malloc() in a different DLL).

You can get the best of both worlds by linking dynamically and deploying the runtime DLLs as private assemblies. This simply means putting a copy of a specially-named directory containing the runtime DLLs and their manifests next to your executable.

See the section "Deploying Visual C++ library DLLs as private assemblies" at http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx for details, but basically your application looks like this:

c:\Program Files\My App\MyApp.exe
c:\Program Files\My App\MyLibrary.dll
c:\Program Files\My App\Microsoft.VC80.CRT\Microsoft.VC80.CRT.manifest
c:\Program Files\My App\Microsoft.VC80.CRT\msvcr80.dll

As to your last question, yes, the target machine needs the correct versions of the runtime DLLs to work, but by deploying them as private assemblies, you guarantee that.

Another benefit is that non-admin users can install your app (not into Program Files, but elsewhere) - they don't need permission to write files into the WinSxS area.

RichieHindle
This is the answer I was looking for. Seems like private assemblies are the safest solution to my problem. Sort of remind me of Mac bundles in that an app is distributed in a fixed directory structure. Thanks!
But private assemblies will not be patched by Windows Update, correct? So you'll have to keep your copy of the runtime library up to date on your own. See also http://blogs.msdn.com/larryosterman/archive/2004/04/29/123090.aspx
David Citron
I never got those private assemblies working if my 'application' (My App) folder contains a mix of 32-bit and 64-bit applications. You can't simply add something like x32 or x64 to the assembly folder name, which means that you can only use the private assemblies if you have only 32-bit or only 64-bit applications.
Patrick
+1  A: 

The only time you'll get multiple copies of the runtime is when you statically link a library into a DLL - each DLL will get a copy, and so will the exe. If they're all static libraries and not DLLs, they'll all link together and all of your libraries will share the same runtime.

That's the linker's job.

Mark Ransom