Visual studio 2015 run-time dependencies or how to get rid of Universal CRT?

I too was fighting with statically linking a solution with multiple components/project library dependencies importing functions from various parts of the MSVCRT, UCRT and Kernel. The hope was the resulting EXE could be just copied around where it was needed (it was no product which would justify a full MSI installation).

After almost giving-up I found the best solution was the follow the guidelines hidden in the Universal C Runtime announcement, specifically:

We strongly recommend against static linking of the Visual C++ libraries, for both performance and serviceability reasons

Just remove all the "special" linker options you tried, drop-back to /MT|/MD (Multi-Threaded CRT DLL Release|Debug) runtime library choice and it works everywhere, e.g. newer Windows 10 workstations, 2012 R2 servers and Windows 7). Just install/redistribute MSVCRT (VC_Redist*.exe) and KB2999226 (UCRT via Windows Update) as Microsoft tell us to do, because as they also say:

The Universal CRT is a component of the Windows operating system. It is included as a part of Windows 10, starting with the January Technical Preview, and it is available for older versions of the operating system via Windows Update.

So logically the only additional deployment dependency our C++ solutions add for the customer is the MSVCRT, because the UCRT should already be there on up-to-date/well maintained machines. Of course it adds a bit of uncertainty; you can't just copy the EXE and run on any machine, good or bad.

If you produce a decent deployment package like an MSI then it's straightforward to include when you have tools like WIX. Also to note is since the recent SDK you can include the 40-odd DLLs locally, but that doesn't satisfy the security update principle so I wouldn't do that.

This is really the only supported way to do it, see another example here. This article also suggests we link against "mincore_downlevel.lib" which is an important tip, crucial to whether you get these "api-ms-win*" missing DLL errors. For example:

  1. Project SDK version set to 10, link with mincore.lib = Runs only on Windows 10, but not 8.1/2012 R2 or Windows 7/2008 R2 server.
  2. Project SDK version set to 8.1, link with mincore.lib = Runs on both Windows 10 and 8.1/2012 R2 server, but not Windows 7/2008 R2 server.
  3. Project SDK version set to 10, link with mincore_downlevel.lib = Runs on all!

In summary:

  1. Do not link statically, leave the default DLL C runtimes selected in the project settings.
  2. You don't need the old SDKs, can develop with the latest Windows 10 SDK, but you must link with "mincore_downlevel.lib" not "mincore.lib" if you want to support older Windows versions.
  3. For ease of use, add this to your targetver.h or stdafx.h which also documents your choice (remove the other line):
// Libraries
#pragma comment(lib, "mincore.lib")             // Lowest OS support is same as SDK
#pragma comment(lib, "mincore_downlevel.lib")   // Support OS older than SDK

No, you can't get rid of them, but I was able to statically-link to them by setting the C/C++ > Code Generation > Runtime Library compiler option

  • For Debug: from /MDd to /MTd
  • For Release: from /MD to /MT

This removed all the API-MS-WIN-CRT-* and runtime dll references and caused all the CRT code to be statically linked.

Details on the new VS2015 Universal CRT (dynamic and static) are here: https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

Note that the only other option is to compile with an older-compiler (like virus developers), not newer, because Microsoft promises same UCRT-requirements for any newer compiler-version as well.