Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to distribute C run-time (CRT) Libraries

I'm building an application after converting VC++ 6 workspace on Visual C++ 2008 express. Build in itself goes successfully but real problem I have is with the generated manifests which looks like this:

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level='asInvoker' uiAccess='false' />
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.30729.1' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC90.CRT' version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
</assembly>

My Question is :

How can I restrict the manifest to list only ONE version , preferably 9.0.21022.8. so that I can bundle the necessary C-Run time dependencies inside my application ?

I know the possible root cause to this problem is dependency on some library which uses 9.0.21022.8 and my VC++ Express 2008 might be using 9.0.30729.1. that's why both are listed as dependency.

Note:

I'm following approach b) of http://www.codeproject.com/Tips/211756/How-to-Distribute-C-run-time-CRT-Libraries-with-Yo?display=Print which talks about copying the CRT DLL files and Microsoft.VCXX.CRT.manifest file inside application folder.

like image 428
amit Avatar asked Nov 11 '11 17:11

amit


People also ask

What is C run time library?

The C runtime Library (CRT) is the part of the C++ Standard Library that incorporates the ISO C standard library. The Visual C++ libraries that implement the CRT support native code development, and both mixed native and managed code. All versions of the CRT support multi-threaded development.

Which library helps us to provide runtime details of our application?

Open Source, Embedded Linux, and Android The compiler support library is called libgcc and is provided by the compiler itself to supply low-level compiler support routines such as software floating-point emulation and support for exception-handling. This library is used by virtually all programs compiled with GCC.

What is UCRT and Msvcrt?

MSVCRT vs UCRT These are two variants of the C standard library on Microsoft Windows. MSVCRT (Microsoft Visual C++ Runtime) is available by default on all Microsoft Windows versions, but due to backwards compatibility issues is stuck in the past, not C99 compatible and is missing some features.

What is Libcmt lib?

LIBCMT. LIB is a statically linked library that supports multithreaded programs. CRTDLL. LIB is an import library for CRTDLL. DLL that also supports multithreaded programs.


1 Answers

The default for Visual Studio 2008 is to bind to version 9.0.21022.8. This is regardless of whatever version of service pack or hotfix you have installed, since updates to Visual Studio should not necessarily force your application to have to upgrade (as described here).

Other possible versions are 9.0.30729.1 for Service Pack 1 or 9.0.30729.6161 for SP1 with a security update. There are others.

Because of the default behaviour, it is likely that your application is using 9.0.21022.8 and there is a library which has been compiled to use 9.0.30729.1. You can find out what version of each library is dependant on by using the following command line (described here):

dumpbin /directives <name>.lib

In order to control the version of the runtime that your application binds to you can define preprocessor symbols in your project settings (must be in the project settings or on the command line) to either bind to the default version (9.0.21022.8 - by not defining them) or binding to the same version as your installed Visual Studio:

_BIND_TO_CURRENT_VCLIBS_VERSION=1

Apparently you can also specify the exact version you want to bind to using the defines from this answer (maybe I should have found that first before typing all this out :).

If you find it is your application that binds to 9.0.30729.1 and the dependant library is binding to 9.0.21022.8 then you simply need to remove the preprocessor definition.

The other difficulty is that when you upgrade Visual Studio, the runtime merge modules in your redistributable folder are also upgraded to those versions. So if you have a setup project that uses those merge modules and you are trying to bind to the default version you would end up installing the new versions of the runtimes.

Resolving the runtime version would not be a problem if you also distribute the runtime policy merge modules, as the library loader will at runtime look at the policy of your runtime and automatically load the newest version even if you bind to the default version. Even with private assemblies the loader will first look in the WinSxS folder so if the policies are there you will bind to the newest version. So your mixed version numbers in your manifest will both redirect to the newest version.

Sometimes that is not desired and you can control that to force it to load only the version in the manifest that you specify, which is explained in an answer to this similar SO question.

like image 58
tinman Avatar answered Sep 19 '22 10:09

tinman