Is there a reason (I guess yes but I try to discover it) to install 2019 redistributable when deploying a C++ application built with vc142 since applications seems to work perfectly with the previous redistributable package (coming with vc141)? I have in mind that both are binary compatible, but more than that, dumpbin /exports of msvcp140.dll and vcruntime140.dll from 2017 and 2019 redistributable produce the same output; file size are identical too.
Did I miss something?
Apparently there is no gotcha, the libraries are comptible, see : https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019
The article states: "This reflects the fact that both the runtime libraries and the applications compiled with either version of the compiler are binary compatible."
Maybe there are performance related differences.
As vs 2019 supports later c++ standard than 2017, this leaves one to wonder how this is possible with the old runtime libraries. I guess the differences are all built into the main executable/dll and don't require any changes in the runtime dlls.
Related
It was brought to my attention that my binary will crash on the CPU without SSE support, with exception code 0xC000001D (STATUS_ILLEGAL_INSTRUCTION), despite I'm compiling with option /arch:IA32. And I have been able to track down the exact place where it crashes: Wherever _snprintf_s() is called for the first time, it will crash. The crash is inside of ucrtbase.dll, not my own code.
Now, the interesting part is that, when I make a "fully static" build with compiler option /MT, so to avoid explicity dependency on ucrtbase.dll, the resulting binary works just fine! But, as soon as I compile the exactly some code as "shared" build, with option /MD, it will crash again in ucrtbase.dll.
So it would appear that "static" version of the UCRT still can work on the CPU without SSE support, but the "shared" (DLL) version can not. This inconsistency would clearly seem like a bug to me!
Any thoughts?
Build environment:
Windows 10 v1803
Visual Studio 2017.8 (v15.8.1)
Windows SDK v10.0.17134.12
Toolset: v141_xp
Compiler option: /arch:IA32
Test machine (used for compat-testing only):
CPU: Pentium II
OS: Windows XP with Service-Pack 3
Note: Redist DLLs (ucrtbase.dll +api-ms-win-*.dll) for the setup of the "shared" build have been copied straight from C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86 directory! To the best of my knowledge, this is the latest available version of these DLLs (v10.0.17134.12).
Even this minimal test program will reproduce the crash:
#include <stdio.h>
int main()
{
char buffer[128];
_snprintf_s(buffer, 128, _TRUNCATE, "Hello %s!\n", "World!");
fputs(buffer, stdout);
getc(stdin);
return 0;
}
Update:
After some more debugging and fiddling around, I made a very interesting observation: The UCRT "Redist" DLLs contained within the latest vcredist_x86.exe (Microsoft Visual C++ 2017 Redistributable installer), i.e. the version that ships with VS2017.8 (v14.15.26706), are actually quite different from those UCRT "Redist" DLLs that can be found in the Redist\ucrt\DLLs\x86 directory of the latest Windows SDK (v10.0.17134.12):
ucrtbase.dll from latest Windows SDK
v10.0.17134.12
ucrtbase.dll from latest Visual C++ 2017 Redistributable installer:
v10.0.10586.15
Indeed, I can confirm now that the application compiled with latest Visual C++ 2017 (v14.15.26706) and using the /MD option works correctly on the non-SSE CPU, as long as we use the "old" ucrtbase.dll version, as extracted from the latest vcredist_x86.exe installer.
I'm a bit concerned using such an old version of the UCRT, if the Windows SDK already provides a much newer version. But, apparently, that is what Microsoft is doing themselves with the Visual C++ 2017 Redistributable installer. So, I guess, it is what we are supposed to use...
Just in case anybody at Microsoft is reading this:
Things could have been way less confusing and error-prone for software developers, if, in the Redist\ucrt directory of the Windows SDK, there were separate sub-folders for each "incarnation" of the UCRT – the latest "cutting edge" version of the UCRT and the "compatible" version of the UCRT that we are actually supposed to redistribute. If then somebody at Microsoft spent three minutes for writing a little README file that tells us which "incarnation" of the CRT we should pick and put it at Redist\ucrt\README.txt, it would be almost impossible to do wrong...
I have an application written in QT. Previously I was using Visual Studio 2012 and Qt 5.3.1 after which I recently upgraded to Visual Studio 2015 and QT 5.6. I would previously provide msvcp110 and msvcr110 as part of the installation (I know that wasn't the best practice but I got away with it).
After upgrading I had to now install VC++ 2015 because of the changes with VS 2015. I don't mind the changes and currently providing redist packages to be installed.
The problem I am facing is that, I do have to provide VC++ 2012 as well and recently running the software in Windows 8.1 Pro, I was asked to provide VC++ 2013 as well (never used VS2013 for compiling). The diagnosis was from dependency walker and google. Not only that, I had to install x86 and x64 of all the 3 versions of VC++ for the software to start (wouldn't even start to be honest).
Why do I need VC++ 2012 and 2013 when I now use only Visual Studio 2015?
How do I get rid of the other redist packages? Is it some code I have written which is dependent? If yes any chance I can find out?
Why do I need to provide both the 32 and 64 bit versions when I compile strictly in the 64 bit compiler?
Any way to diagnose without dependency walker? Can there be some logging when the application refuses to start at all?
Apologies for the long post, but any light here can restore my sanity.
Thanks in advance.
You are using DLLs linked to the older runtime. You can use Dependency Walker on your development machine to track this down, shouldn't need to install any tools on a customer machine for that.
Migrate all the files shipped with your application to a version built against VC++ 2015.
You didn't provide any details that could reveal the reason.
For DLLs other than the language runtime library, you can use delay-loading and then be able to trap failure to load the library. You can't effectively delay-load msvcr*.dll though. One option would be to create a very thin EXE that uses no support DLL at all (either use pure Win32 API, or statically link the runtime) which does nothing except install an error handler and then load your main program which is now in the form of a DLL. Loading your main program DLL should be done either using delay-load linking or LoadLibrary()+GetProcAddress() -- either one will allow catching errors. This main program DLL would be free to import the runtime DLLs as usual.
I've generally assumed that each version of Visual Studio was tied to a different version of the C run-time. For example: VS2005 : msvcr80.dll :: VS2008 : msvcr90.dll
One of my co-workers told me that his installer indicated that our VS2013 project had a dependency on msvcr110.dll. We both found this odd, because this is the same dependency used by VS2012.
However, MSDN backs this up:
Visual Studio 2012 C Run-Time Libraries
Visual Studio 2013 C Run-Time Libraries
Does Visual Studio 2013 indeed reuse the run-time from 2012, or am I missing something?
Edit: I forgot to mention in my original question that the Visual Studio 2013 redistributable run-time comes with a file msvcr120.dll. My confusion comes in from the fact that this file exists, yet is neither identified by our installer nor mentioned in the MSDN documentation.
Edit: After talking with my co-worker about how the dependency was being determined, the reason the installer thought our projects had a dependency on msvcr110.dll was because it was looking at an old build.
This just unfortunately coincided with the copy/paste error in the MSDN documentation regarding the versions of the run-time. I'll contact Microsoft to let them know about the documentation error. Thanks again for the help, everyone.
Note: Even if they did use the same run-time, I wouldn't assume such for any future releases. I just found this curious.
By default VS 2013 C and C++ projects will depend on msvcr120.dll (or the debug build equivalent of msvcr120d.dll).
However, it's very easy to change the dependency to msvcr110.dll by changing the 'platform toolset' to "Visual Studio 2012 (v110)" in the project settings if VS1012 is installed on the machine. Older versions of the runtimes going back to VS 2008 (v90) are supported.
I assume that the doc page for the 2013 runtime that you linked to wasn't updated due to a simple oversight.
I have a software with a couple of executables, that depends on both VC++ 2012 and VC++ 2010 (msvc110.dll, and msvc100.dll, something like that). I want to ship my application with the 2012 version redistributable, that is 7mb, and avoid using the 2010 redistributable so I reduce the size of the installer.
My question is, is the 2012 version of the redistributable backwards compatible with the 2010 version? Or should I embed both of them in the installer?
Note that the executables are already compiled, and I don't have the source code to compile them using the same version.
Unfortunately if you don't ship the runtime the module was compiled against,if it does not exist on the target system, your app will fail. How it fails depends on how you built your app (e.g. linked lib dll, versus OpenLibrary module).
As for compatibility, our team had similar questions so I wrote experimental test code using VS2005, VS2010 and VS2012 modules where one module would create a std::vector (etc) and pass it to another module for use. It failed badly. Extremely easy to reproduce this experiment.
You will need to ship both.
You have several exe, just ship them all or mark it down as a requirement for your app.
DLLs are not big.
If you can rebuild apps to align them so they use the same crt, that would be better.
I own VS 2008 Pro, and would like to do compatibility testing with VS 2005's runtime MSVCRT80, but I do not want to buy it just for that. Is there a way to link against MSVCRT80 without getting VS 2005?
Thanks
Official support for native multi-targeting didn't appear until Visual Studio 2010, which allows you to select either v100 or v90 as your "Platform Toolset". There is no such feature in Visual Studio 2008.
There is a discussion here on how one can achieve the same effect in Visual Studio 2008, but it appears you need to have VS 2005 installed on your computer as well in order for this to work. It isn't going to work if you just have the runtime libraries installed because you need the proper version of the compiler and linker, which you'll only have if you install VS 2005.
On that note, I'm not really sure what you mean by "compatibility testing". If you compile your app against v90 in VS 2008, it's not going to work with the older versions of the runtime. You have to compile and link against the version you want your app to use.
Finally, consider whether it's really relevant or not. Since you must include MSVCRT with your application anyway, what's the advantage of trying to link against an older version of the runtime? Just include v90 and be done with it.
Links to a still-working (as of 11 Jan 2011) Microsoft download for Visual C++ Express 2005 can be found here:
http://apdubey.blogspot.com/2009/04/microsoft-visual-studio-2005-express.html
This should let you compile against the VS2005 runtime without having to buy anything.
(in case the blogspot article goes away, the link for the .iso is http://go.microsoft.com/fwlink/?linkid=57034).