Introducing the Universal CRT

In June of last year we published a pair of articles discussing the major changes that we had made to the Visual C++ C Runtime (CRT) for Visual Studio 2015. In “The Great C Runtime (CRT) Refactoring” we explained the major architectural changes that we had made to the CRT. In “C Runtime (CRT) Features, Fixes, and Breaking Changes in Visual Studio 14 CTP1” we enumerated all of the notable features we’d implemented and behavioral changes that we’d made.

We’ve received a lot of feedback from you, our customers, over the months since we wrote those articles and released the first Community Technology Preview (CTP) of Visual Studio 2015. We are especially appreciative about the many excellent bugs that you’ve reported on Microsoft Connect. While we haven’t made many changes to the CRT since that first CTP, we have indeed been hard at work on addressing your feedback, working on further improvements, and finishing up some longer-running projects. The recently-released Visual Studio 2015 CTP6 has all of these improvements that we’ve been working on. We’ll be discussing these changes in a pair of articles again: this article discusses the major architectural changes since the first CTP; a subsequent article will enumerate all of the new features, bug fixes, and breaking changes in greater detail.

In our articles last June, we explained how we had split the CRT into two logical parts: The VCRuntime, which contained the compiler support functionality required for things like process startup and exception handling, and a “stable” part that contained all of the purely library parts of the CRT, which we would service in-place in the future rather than releasing newly versioned DLLs with each major version of Visual Studio. At the time, this “stable” part took the form of two libraries: the AppCRT and the DesktopCRT (the release DLLs were named appcrt140.dll and desktopcrt140.dll).

The VCRuntime still exists in the same form and with equivalent contents as in previous CTPs. It’s in the “stable” part that we’ve made major changes in this latest CTP6. The AppCRT and DesktopCRT have been recombined into a single library, which we have named the Universal CRT. The new DLLs are named ucrtbase.dll (release) and ucrtbased.dll (debug); they do not include a version number because we’ll be servicing them in-place.

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.

Building Software using the Universal CRT

Previously, all of the CRT headers, sources, and libraries were distributed as part of the Visual C++ SDK, installed in the VC subdirectory of your Visual Studio installation (generally C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC). The files for the VCRuntime are still part of the Visual C++ SDK. The headers, sources, and libraries are now distributed as part of a separate Universal CRT SDK. This SDK is included with Visual Studio; it is installed by default to C:\Program Files (x86)\Windows Kits\10. The debug ucrtbased.dll is also included as part of this SDK and is installed to the system directory.

We have updated the Visual C++ MSBuild props and targets files to add the new Universal CRT directories to the include and library paths. If you create a new project in Visual Studio 2015 or upgrade an existing project to Visual Studio 2015, it should generally pick up these new directories automatically. If you upgrade a project that does not use the Visual C++ MSBuild props and targets files or that does not inherit the default include and library paths from those props and targets files, you’ll need to update your project manually to include the new directories. You can use the following MSBuild properties to find the Universal CRT SDK files:

    $(UniversalCRT_IncludePath)
    $(UniversalCRT_LibraryPath_x86)
    $(UniversalCRT_LibraryPath_x64)
    $(UniversalCRT_LibraryPath_arm)

So long as you do not link with the /nodefaultlib option, all of the correct library files will be found when you link your project. If you link with the /nodefaultlib option, you will need to link several extra libraries when you link. For example, whereas you previously might have just linked msvcrt.lib in order to use the CRT DLL, you will now also need to link vcruntime.lib and ucrt.lib. Here is a table that shows which libraries you will need to link for each “flavor” of the libraries:

    Release DLLs   (/MD ): msvcrt.lib   vcruntime.lib      ucrt.lib
    Debug DLLs     (/MDd): msvcrtd.lib  vcruntimed.lib     ucrtd.lib
    Release Static (/MT ): libcmt.lib   libvcruntime.lib   libucrt.lib
    Debug Static   (/MTd): libcmtd.lib  libvcruntimed.lib  libucrtd.lib

Distributing Software that uses the Universal CRT

In the past, you might have used one of the many ways described in “Deployment in Visual C++” to redistribute the Visual C++ libraries along with your software. For all Visual C++ libraries except the Universal CRT, there is no change in the way deployment can be done. Whatever mode of deployment (central, local or static linking) was used earlier can still be used.

However, with the above mentioned change to move the Universal CRT into the Windows Operating System, there are a few note-worthy changes:

  1. The Universal CRT is a Windows operating system component. It is a part of Windows 10. For Windows versions prior to Windows 10, the Universal CRT is distributed via Windows Update. There are Windows Update MSU packages for Windows Vista through Windows 8.1. Currently these MSU packages are installed as part of the VCRedist installation. In a future build of Visual Studio 2015, these MSU packages will also be distributed separately as part of the Universal CRT SDK and made available for download on support.microsoft.com.

  2. If you build software designed for use on Windows operating systems where the Universal CRT is not guaranteed to be installed (i.e., Windows 8.1 and below), your software will need to depend on the above mentioned Windows Update packages to install the Universal CRT.

  3. If you currently use the VCRedist (our redistributable package files), then things will just work for you as they did before. The Visual Studio 2015 VCRedist package includes the above mentioned Windows Update packages, so simply installing the VCRedist will install both the Visual C++ libraries and the Universal CRT. This is our recommended deployment mechanism. On Windows XP, for which there is no Universal CRT Windows Update MSU, the VCRedist will deploy the Universal CRT itself.

  4. If you currently statically link the Visual C++ libraries, then things will continue to work just as they currently work for you.  We strongly recommend against static linking of the Visual C++ libraries, for both performance and serviceability reasons, but we recognize that there are some use cases that require static libraries and we will continue to support the static libraries for those reasons.

  5. There will not be a merge module for the Universal CRT. If you currently use the CRT merge modules and still want to deploy the Visual C++ libraries centrally, we recommend that you move to the above mentioned Windows Update package or to the VCRedist. Alternatively, you may choose to link statically to the Universal CRT and the Visual C++ libraries.

  6. Updated September 11, 2015:  App-local deployment of the Universal CRT is supported.  To obtain the binaries for app-local deployment, install the Windows Software Development Kit (SDK) for Windows 10.  The binaries will be installed to C:\Program Files (x86)\Windows Kits\10\Redist\ucrt.  You will need to copy all of the DLLs with your app (note that the set of DLLs are necessary is different on different versions of Windows, so you must include all of the DLLs in order for your program to run on all supported versions of Windows).  App-local deployment of the Universal CRT is not supported. The Universal CRT is a Windows operating system component. Eventually (long-term), the Universal CRT will always be present on every machine, just like other operating system components today. We realize that there are today existing operating system versions where this component is not present, and we recognize that you, our customers will need to support these operating systems for some time. We hope that using the Windows Update package or static linking will suffice. One of the primary goals in our effort to refactor the CRT for this release was to mitigate the runtime proliferation problem, where over time computers end up with a large number of copies of the runtime libraries.

As we mentioned previously, we’ve made many bug fixes and other improvements to the CRT since we introduced the refactored CRT last June in CTP1. Later this week we’ll have a second article that discusses these changes in greater detail. In the meantime, we’re very interested in your feedback about the new Universal CRT.

James McNellis and Raman Sharma
Visual C++ Libraries