C++ runtime required? - c++

Why do some C++ projects require a runtime package to be installed, while others do not?
EDIT:How to make a project to work without the runtime?

Some will have been statically linked, while others will depend on a dynamic library, loaded at run-time. To link your own project statically, you need to change your project configuration - how you do this depends on the compiler/linker and/or IDE you are using.

Some applications are built linking with the system libraries this are the dynamic linked programs.
Other programs contains the code of the libraries into the executable file this are the static linked programs.
Pros of dynamic linked:
Smaller size of the program executable.
Less memory consumption if the dynamically linked library is shared.
Better performance.
Cons of dynamic linked:
Dependency on the library.
Deployment is more dificult.
Pros of static linked:
No dependencies.
Easier deployment of the application.
Cons of static linked:
The executable file is bigger.
To get a static project you need to set up the option in the project properties.

I think this refers to the VS2005 service pack 1 runtime. For some reason MS added some non-backward compatible features to it, so any app built with VS2005sp1 requires the runtime to go with it.

You need to have runtime package installed in case you are working with standard C/C++ library linked as DLL, and not as static library. So one way to avoid it is to link standard C/C++ library statically (C++ project settings). It may, or may not be possible in your case.
If not, you can use dependency walker tool from Visual Studio distribution to identify the DLLs needed by your application and just put them near your executable.
What you should be aware in Visual Studio 2005 and later is that there are the manifests for binaries can (and probably will :) make your life harder. Specially since SP1 for Visual Studio 2005 changes the version of C++ library, and the manifests as well.

Related

CRT library type

I'm trying to get a better grasp on the CRT library options in Visual Studio 2013 (C++ -> Code Generation -> Runtime Libary) and how to know which option to select (and when to change the default).
From MSDN:
A reusable library and all of its users should use the same CRT library types and therefore the same compiler switch.
So, my understanding is that if you are linking with a third party library, you should use the same CRT version that was used to build the library. Whoever built the library should specify what CRT option was used in the build.
Is there a way to determine which CRT version was used just by looking at the .lib file?
More importantly, how would you decide which option to use if you aren't linking with any third-party libraries? When would you consider changing the default?
Short answer:
So, my understanding is that if you are linking with a third party
library, you should use the same CRT version that was used to build
the library. Whoever built the library should specify what CRT option
was used in the build.
That is the least error-prone option. It is possible to mix runtimes, but you can run into unexpected bugs if you do so.
Is there a way to determine which CRT version was used just by looking
at the .lib file?
I don't know about the .lib on its own, but if the third party code has a DLL or EXE, you can see what CRT DLL(s) it depends on using the Windows Dependency Walker tool.
If it's a static library, and your code's CRT choice is mismatched, you'll see warnings when you build.
More importantly, how would you decide which option to use if you
aren't linking with any third-party libraries? When would you consider
changing the default?
For the simplest possible deployment, statically linking is best; you can just ship the executable on its own and it will run. For larger projects, where you have multiple EXEs and DLLs, your code size will be bigger if you statically-link. It would also be preferable to be sharing the same CRT code if you have multiple modules (EXE plus 1 or more of your own DLLs) in the same process.
More detail (based on blog post I wrote previously):
The Library Variants
There are four variants of C/C++ runtime library you can build your code against:
Multi-threaded Debug DLL
Multi-threaded DLL
Multi-threaded Debug
Multi-threaded
You can select which library you’re using by right-clicking on your project in Visual Studio and selecting Properties, clicking the Code Generation option under C/C++ on the dialog that pops up, and going to the Runtime Library property.
Remember that this setting is per-configuration, as you’ll want to choose a Debug runtime library for a Debug configuration, and Release runtime library for a Release configuration.
What’s the difference?
The DLL runtime library options mean that you link dynamically against the C/C++ runtime, and for your program to run, that DLL will need to be somewhere your program can find it (more on that later).
The options not mentioning DLL (Multi-threaded Debug and Multi-threaded Release) cause your program to be statically-linked against the runtime. This means that you don’t need an external DLL for the program to be run, but your program will be bigger because of the extra code, and there are other reasons why you might not want to choose it.
By default, when you create a new project in Visual Studio, it will use the DLL runtime.
The multi-threaded in the runtime names is a legacy of when there used to be both non-thread-safe and multi-threaded C/C++ runtimes. You’ll always be using a multi-threaded runtime with modern Visual Studio, even if your own application is single-threaded.
Deploying DLL Runtimes
If you’re linking against the DLL runtimes, then you’ll have to think about how to deploy them when releasing your program (to Test, and to your customers).
If you deliver Debug builds to your Test team, make sure you provide the Debug variant of the DLL runtimes too.
Also, don’t forget to get the right architecture (e.g. x86 vs x64).
Redistributable Installers
Microsoft provide redistributable packages that install the Release (but not the Debug) DLLs. These can be found easily enough by searching for something like Visual C++ Redistributable 2013 (substituting the Visual Studio version for what you need). You can also go straight to Latest Supported Visual C++ Downloads on Microsoft’s website.
These redistributables packages are executables, and you can call them from your program’s installer (or you could run them manually for setting up a test environment). Note that there are separate redistributables for x86 and x64.
Merge Modules
If you’re building an MSI installer, you can merge the Merge Module for the C/C++ runtime you’re using into your installer package. These merge modules are typically found in C:\Program Files (x86)\Common Files\Merge Modules. For example, the x86 C/C++ runtime’s merge module for Visual Studio 2013 is called Microsoft_VC120_CRT_x86.msm.
Note that the version numbers in these merge module names are not the year-based product versions, but the internal version numbers. This table on Wikipedia shows the mapping between the version numbers for avoidance of confusion.
Unlike the stand-alone executable redistributable installers above, the merge modules also come in Debug variants.
Some versions of Visual Studio have support for a Visual Studio Installer project type (under the Setup and Deployment category in Other Project Types), and if you include the output from your program’s projects in one of these installers, the merge modules for the runtime will be included automatically. You can also use this as a trick to get an installer that will install the Debug runtimes for internal testing purposes (any dummy C/C++ project will do, it doesn’t have to actually install your program).
Copy From Redist Folder
You can also just copy the DLLs from the redist folder in your Visual C++ installation into where your program is installed. For example, for Visual Studio 2013, you’ll find the x64 C/C++ runtime libraries somewhere like C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x64\Microsoft.VC120.CRT\.
The debug variants can be found somewhere like C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\Debug_NonRedist.
(Adjust paths as appropriate for your Visual Studio version and installation location).
Mixing C/C++ Runtimes
In an ideal world, you would use the same C/C++ runtime library variant (Debug vs Release, DLL vs statically-linked), and all from the same version of Visual Studio, for all libraries being linked into your program.
If you do mix runtimes, you may get linker errors, your program may simply fail to run at all, or worse still, it may seem to be working but crash or give the wrong result only in some cases.
Ignoring Default Libraries
A common scenario is that you only have the Release version of some third-party library, but you still want to be able to build the Debug variant of your own code using this library. Another scenario is that you have a library that uses the static C/C++ runtime and you want the DLL version in your program, or the reverse.
If the third-party library is C code then you’ll probably be able to get away with this and have it actually work, using the /NODEFAULTLIB linker option.
If the library is C++ code, you are probably out of luck as too much of the generated code is tied to symbols in a particular runtime.
These are the different library names:
LIBCMT.LIB: Statically-linked Release runtime (a.k.a. Multi-threaded)
LIBCMTD.LIB: Statically-linked Debug runtime (a.k.a. Multi-threaded Debug)
MSVCRT.LIB: Dynamically-linked Release runtime (a.k.a. Multi-threaded DLL)
MSVCRTD.LIB: Dynamically-linked Debug runtime (a.k.a. Multi-threaded Debug DLL)
Remember, the runtime libraries you want to ignore are the ones that the third-party code is using, i.e. it will be different from the library that your own program is using. If you look at your build output you will be prompted to choose the right one anyway, e.g.:
LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
You can specify the library to ignore by right-clicking on your project, selecting Properties, clicking the Input entry under Linker and adding the runtime library name into the entry.
Crossing Module Boundaries
You can also run into C/C++ runtime mismatch problems in more subtle ways across module boundaries (between an EXE and a DLL it loads for example).
For example, data structures in the C library may be defined differently by different runtimes. I’ve seen this cause crashes in programs that used a DLL that made use of a FILE* in its API. A file is opened in one module using one C runtime, and interacted with by another module which has a different, incompatible implementation. Safer options would include passing Windows API HANDLE objects for things like this, or else wrapping up the file interactions in a way that is runtime-agnostic.
Different runtimes also use their own memory heap for allocations. If an object is allocated in one module on one heap, but deallocated in another module, a crash is likely to occur if the C/C++ runtimes are mismatched. This only applies of course to allocations using the C or C++ runtime such as malloc or new. If the default Windows process heap is being used everywhere, for example, everything is fine.
Note that if the modules statically link against the C/C++ runtime, they will have this problem even if it was the same variant of the runtime they linked against, because there will still be two different runtimes with their own memory heaps in play. Therefore, you will want to use the DLL C/C++ runtime in such circumstances.
It would also be wise to use the (same version of) DLL runtimes in each module if runtime-implemented functionality like exceptions or classes with vtables cross the module boundaries, though some combinations of mismatch may work in practice.

Removing msvcp90d.dll dependancy from Windows binary

I have a dll that I distribute that will not run on some windows OS. Using dependancy walker I discover msvcp90d.dll missing on these systems. I DO NOT want any run time dependancies that require the C++ redistributable, and since the application that calls the DLL is not written in C++, it does not have any dependancy on the C++ redistributable.
I am guessing the I left the DEBUG option in the linker preferences on when I compiled the dll which is why it needs msvcp90d.dll?
ADDED:
Appologies, I pasted the wrong dll name in my original question.... too many hours in front of the monitor...
THe dll is a third party dll that I did not write compiled by me in VS2008.
MSVCP90 is nothing to do with debug (that'd be msvcp90d). You can remove your dependency by switching the compiler to /MT (instead of /MD). You also need to ensure that every static library you link to was also compiled /MT.
I recommend against building apps /MT because it has a significant negative effect on system performance and makes servicing take longer in the event of a security issue with the CRT.
Finally, note that /MT means that your CRT is private. So you must ensure that CRT/STL types don't pass across your DLL boundary.
Martyn
Your options as I see them:
Compile the DLL with the /MT option to use static linking to the C runtime.
Continue with dynamic linking to the runtime, but distribute the C runtime with your app.
It needs MSVCP90.dll because the dll was compiled with Visual Studio 2008 most likely. That is the release runtime. The short answer is if you don't want C++ runtime dependencies don't use C++ libraries or applications.
However you can do any of the following to solve your problem:
Install the redistributable to the target system to satisfy the dependency
Remove the dependency on that dll from your application
Recompile the dll against the version of VC you prefer that is already present on the target system

How do I remove dependency on mfc80.dll and msvcr80.dll?

My code does not use MFC. However, when I built my static lib the party that is trying to use it is stating that they are having a hard time because my code lib has the following dependencies in it:
mfc80.dll and msvcr80.dll
Is there a way to remove those and rebuild? I am using vs2008.
A static library by default links to the dynamic runtime, which is why your code has a dependency on msvcr80.dll. Visual C++ programs must link to a runtime. You can change your static library to use a static runtime to remove the dependency. This is done in the Configuration Properties | C/C++ | Code Generation | Runtime Library setting. However, the chosen runtime library must match what is used in the project that links your static library.
Your code probably depends on mfc80.dll because you have Configuration Properties | General | Use of MFC set to one of the MFC options.
In my opinion, Visual C++ (and Windows in general) was made for dynamic libraries and dynamic runtimes. Static libraries seem like more of a hack, in that they have a surprising number of limitations, pitfalls and idiosyncratic behavior. Better become familiar with producing and consuming dynamic libraries -- it's better in the long run.
mscvr80.dll is the release CRT. You can remove this dependency by setting the compiler to statically link. Most likely, you're trying to load MFC because the project is set to use MFC, even though you're not using it. You can remove this in the project settings.
Although, gotta question why VS2008 would produce mfc80.dll and mscvr80.dll dependencies, instead of mfc90.dll and mscvr90.dll.

Alternatives to including MS C runtime distro?

I use MSVS 2010 and MSVC++E 2010 to build my applications in C++ and I've notice a lot of my friends (who test my apps on their PCs) don't have the Microsoft C++ runtime library installed on their computers. I've started including the Microsoft C++ redistributable package with my apps, but this seems unnecessary. Would I be able to instead include the libraries in my executable directory? I know that one of the libraries used is msvcr100.dll, but are there also others I need to include? Or is the redistro my best option?
in your project options, for code generation, you can choose the STATICally linked libraries instead of the DLL versions. That eliminates the need for an external dependency like this, at the cost of a larger EXE.
You don't necessarily need to HAVE to have the runtime library within your executable directory, you may use a Manifest File that has a relative path which points to runtime if you wish. But yes, you can include the libraries within the install of your application.
I think we lug around the msvcr as well as the msvcrt and the msvcp DLLs which now that I'm writing that out, might be a bit overkill.
When you build your application to a static runtime, you don't need to distribute the runtime dlls.
Otherwise you have to include the Microsoft runtime.
Links to runtime installers for Visual Studio 2010
Compiling your project with /MT solves the distribution problem. Be careful though, it can get you in trouble when you use DLLs. They will have their own memory allocator. If they export a function that exposes a pointer or a C++ object that needs to be released by the client code then you'll have a very hard to diagnose memory leak on your hands. Very easy to do, just return an std::string for example.
Anyhoo, the setting is found by right-clicking the project in the Solution Explorer window, Properties, C/C++, Code generation, Runtime Library setting.
Also note that VS2010 supports local deployment. Just put the msvcr100.dll file in the same directory as your EXE. You also need msvcp100.dll if you use STL or iostreams.

C Runtime Library Version Compatibility: updates require rebuilds?

How do you construct a library (static lib or a dll/so) so that it isn't sensitive to future updates to the system's C runtime librarires?
At the end of July, Microsoft updated a bunch of libraries, including the C runtime libraries. Our app is written with a mix of MFC/C++/VB and some third party libraries, including some that are closed source.
I've been busy recompiling all of the libraries we have source to, but I am wondering if it is really necessary? What will happen if we link in or load a library built against an earlier version of the C runtime?
When recompiling this stuff, what compiler and linker settings must be the same between the main application and the supporting libraries? I've discovered that the runtime library setting needs to be the same (we use the multi-threaded version /MD and /MDd) but I'm worried about other settings. I've actually pulled all the settings out into Visual Studio property sheets and I'm using the same sheets for all our different projects, but this doesn't work for 3rd party libraries and I'm thinking it is overkill.
I have noticed that the linker will spit out a warning about conflicting libraries, but it suggests to just ignore the default libraries. Is it safe to do so? It seems like a very ugly solution to the problem.
If you are loading the 3rd party libraries as DLLs, they may depend on different runtime versions than your executable as long as
you are not handing over parameters of types, that depend on the runtime libs (like STL types)
the 3rd party lib is able to load the version of the runtime, that it has been built with or is statically linked to the runtime
So, you don't have to recompile the DLLs.
If you are statically
linking to the libs or if you are handing over types defined in the runtime DLLs, you may get some problems with symbols, that are already imported in your lib, so most likely you will have to recompile it.
If you or your third-party components are statically linking against out-of-date C libraries, you are fine; upgrades to those libraries will not affect your program. Of course, you won't benefit from any bug fixes or performance upgrades or what-have-you either. If you do recompile your code to take advantage of your new settings, all runtime switches must be the same. This is always the case, regardless of when or why your libraries are compiled. It is probably safe to ignore the default libraries (I've been doing so for years without difficulty).
Dynamically-linked libraries are another story. If you rely on the target system having a particular version of a given dll, and it has some other incompatible version instead, then you are screwed. The traditional solution to this problem is to bundle all the dlls you need with your executable. Microsoft's new side-by-side assembly thing might also be able to help, but it's always been a little too hard to set up for me to bother with it. You might have better luck.