How to compile C++ app for Windows XP in MSVS? - c++

As I read this article, it is enough to download most recent MSVS 2022 and then install toolset C++ Windows XP Support for VS 2017 (v141) tools [Deprecated].
After that in Visual Studio inside project properties I set this toolset. According to linked article it is enough to compile C++ app with XP support.
But after my .exe file is created if I run it on XP 64-bit SP2 then it shows error that CompareStringEx function is not found in KERNEL32.DLL.
Hence it appears that it is not enough to use this toolset. Something else is needed.
In some other places I see that one needs also to add define /D_USING_V110_SDK71_ when compiling and option /SUBSYSTEM:CONSOLE,5.01 when linking. In my project properties I also tried to add this two options, but still CompareStringEx is inside import table of final application.
As suggested by #BenVoigt, I did defines /DWINVER=0x0502 /D_WIN32_WINNT=0x0502. Also set C++ standard to /std:c++14 (I would set C++11 but this MSVS version allows to set only C++14 at minimum). Still some non-XP symbols remain in final EXE like InitializeSRWLock that is possibly used by C++11's std::mutex in my code.
Does anyone know everything what is needed in order to compile fully XP-compatible application?
Update. I managed to build working XP application by doing things above plus setting C++ CRT runtime to Multi Threaded DLL, i.e. using dynamic DLL linkage of CRT. Also as suggested by #ChuckWalbourn (down x86 or x64 redists), I downloaded older version of msvcp140.dll.
But it is very important for my project to have statically linked runtime (C++ CRT), i.e. use Multi Threaded value for Runtime field in project properties. Only if it is REALLY not possible only then I will use DLL CRT. Until then solution about how to link CRT statically are welcome, of course to produce XP-compatible EXE.

TL;DR For Window XP VC++ REDIST support, install https://aka.ms/vs/15/release/VC_redist.x86.exe on your Windows XP system
-or-
if you are doing "side-by-side application local deployment", then use the DLLs from C:\Program Files\Microsoft Visual Studio\2022\<edition>\VC\Redist\MSVC\14.16.27012\x86\Microsoft.VC141.CRT.
If you want the latest bug fixes to the CRT, you can also download the REDIST for VS 2019 (16.7) per the link on Microsoft Docs.
For Windows XP targeting, you use the v141_xp Platform Toolset installed by Visual Studio (VS 2017, VS 2019, or VS 2022) which is the latest VS 2017 (v141) C++ compiler using an included Windows 7.1A SDK.
Make sure you have installed (for VS 2022) the following individual components since you are using MFC:
Microsoft.VisualStudio.Component.WinXP: C++ Windows XP Support for VS 2017 (v141) tools [Deprecated]
Microsoft.VisualStudio.Component.VC.v141.x86.x64: MSVC v141 - VS 2017 C++ x64/x86 build tools (v14.16)
Microsoft.VisualStudio.Component.VC.v141.MFC: C++ MFC for v141 build tools (x86 & x64)
If you are doing DirectX development, be sure to read this blog post as well for various implications of using the Windows 7.1A SDK.
For deployment to Windows XP, you can install the latest VS 2017 Visual C++ REDIST or use VS 2019 Visual C++ up to VS 2019 (16.7). After that the REDIST DLLs themselves are not compatible with Windows XP.
On your development system with VS 2022 installed, you are going to have a newer set of Visual C++ REDIST files which are binary compatible with your v141_xp Platform Toolset built EXE, but those VC++ REDIST DLLs are not compatible with Windows XP.
IOW: If you look at a dumpbin /imports of the 14.30 (v143 version), 14.29 (v142 latest version), and/or 14.16 (v141 latest version ) copies of msvcp140.dll you will see different imports. The msvcp140.dll sitting in your C:\windows\SysWOW64 folder is going to be the 14.30 version.

Related

Different C++ Redistributable DLL's for VS 2013 and VS 2015

I built my application using VS 2013, and delivered two DLLs:
msvcp120.dll
msvcr120.dll
Building the same application using VS 2015, instead we need:
msvcp140.dll
vcruntime140.dll
Is vcruntime140.dll replacing the former msvcp120.dll?
Yes.
Visual Studio usually breaks binary compatibility with older releases when it gets a major version update. The one notable exception is the transition from VS2015(14.x) to VS2017(15.x), which did not break binary compatibility.
For all other releases, when you change the version of Visual Studio, you'll need to change which Runtime Redistributables get installed onto the target computer.
EDIT: Per Christopher's observation: Don't manually install the .DLL files onto the target computer. Download the Redistributable Installer from Microsoft, and ship that with your program, with instructions (or an installer) that installs that first. This link goes to the 2015 version, but you should grab whichever version corresponds to the specific version of visual studio that you are using.

Is MSVCP140.dll OS/version-dependant?

So I tried to run my program in another computer, as you'd expect from the title, the computer was missing msvcp140.dll - I downloaded it from the internet (didn't have other options at the time) and it didn't work.
Aside from 32-64 bit versions of said .dll, are there different versions for each version of visual studio and/or for each Windows' version (7, 8, 10)?
I would rather not have make users install Visual Studio on their computer just for my program.
msvcp140.dll is a Dynamic Link Library (DLL) that is a part of Microsoft Visual C++ component. Your machine might not have the Microsoft redistributable for Visual C++.(I assuming you are using VC++ compiler). Since the other machine does not have MSVS installed, there is no guarantee it has the redist installed. Just install the appropriate redist package from your Visual Studio version to avoid error. msvcp140.dll is Microsoft Visual C++ version dependent.
If you don't want to redistribute MSVC DLLs with your application, you can make a static build of your application.
In Project Settings -> C/C++ -> Code Generation -> Runtime Library -> Select /MT or /MTd (debug)
A statically linked module will not require any MSVC DLLs (other than omp140, if you use OpenMP)
(The downside is that your EXE will become larger)

How to install Visual Studio Build Tools 2010 on Visual Studio 2015 Community?

I have a project created on Visual Studio 2010. When I try to run the project on Visual Studio 2015 Community edition I get the error below,
Severity Code Description Project File Line
Error MSB8020 The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found. To build using the v100 build tools, please install Visual Studio 2010 build tools. Alternatively, you may upgrade to the current Visual Studio tools by selecting the Project menu or right-click the solution, and then selecting "Retarget solution". graphics C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.Cpp.Platform.targets 55
And when I tried to build it with Visual Studio 2015 Build Tools I encountered about 1500+ errors.
Is there any way to make the project work?
If you can't install VS2010, Windows SDK for Windows 7 contains needed compiler tools (v100), you may actually skip installing the SDK itself and install only the compiler tools, headers and libs. Please note, that the compiler included in Windows SDK is the same that VS2010 has, but VS2010 SP1 has a bit newer compiler. If you need that, you'll also need to install Microsoft Visual C++ 2010 Service Pack 1 Compiler Update for the Windows SDK 7.1. But be aware, that if you install these, you may have issues later if you decide to install VS2010, there are bugs in installer that requires you to install components in strict order. Also, if your code uses MFC or ATL you must install VS2010, installing Windows SDK will not be enough.
You either install VS 2010 and build your project, or better yet you upgrade your projects. The VS 2015 custom install options will let you install the v120 Platform Toolset, but not the v110 or v100 Platform Toolsets.
One major change in VS 2015 is that the C++ tools (i.e. v140) are not installed by the Typical installation option. See the Visual C++ Team Blog.
Keep in mind that Visual C++ 2010 used the C++0x Draft Standard, and Visual C++ 2015 meets the C++11 Standard with the exception of Expression SFINAE (which is partly there in Update 1), so quite a bit has changed in the intervening years including some breaking changes. Since you are jumping three major releases at once--and about 10 minor updates--, it can be a bit overwhelming especially working through all the new warnings.
Another thing to keep in mind is that Visual C++ 2010 used the Windows 7.1 SDK, while Visual C++ 2012 or later use the Windows 8.x SDK. There's been a lot of change there too particularly for DirectX development. It's particularly important for Windows desktop apps that you set the _WIN32_WINNT preprocessor define for your target platform as the Windows 8.x SDK does not default to the 'oldest supported platform' like earlier Windows SDKs did. See Using the Windows Headers
VS 2010 and the v100 toolset supports targeting Windows XP and Windows Server 2003. The v140 toolset does not support targeting Windows XP / Server 2003. You have to use v140_xp Platform Toolset instead. See this post for some notes as this means you are again using the Windows 7.1 SDK rather than the Windows 8.x SDK with the _xp toolsets.
See Breaking Changes in Visual C++ 2012, Breaking Changes in Visual C++ 2013, and Breaking Changes in Visual C++ 2015.
See also Support For C++11/14/17 Features (Modern C++), and Where is the DirectX SDK?.
If you need to build the code both with VS 2010 and with VS 2015, then you should create two projects/solution files, one for each. You may also want to read this article for some notes on writing code that can build with multiple Visual C++ toolsets, which again is particularly challenging due to the Windows SDK changes.
VS 2015 supports targeting Windows Vista SP2, Windows 7 SP1, Windows 8.0, Windows 8.1, Windows 10, and optionally Windows XP SP3. It does not support targeting Windows Vista RTM, Windows Vista SP1, or Windows 7 RTM.

Visual C++11 executables and Windows XP [duplicate]

I compile my C++ source code with Visual Studio 11 Developer Preview. I statically link to the runtime library.
The resulting executable cannot be executed on Windows XP. When I try to execute it on Windows XP I get the error message "[Executable Path] is not a valid Win32 Application.".
According to Microsoft Visual Studio 11 won't support Windows XP.
How does it work that the resulting executable cannot be executed on Windows XP? Is there anything special within the executable?
They seem to drop support for older systems in every new release of VS (NT4,2000,XP) Even if you don't use the CRT at all, they still force the PE subsystem version to high numbers. You can work around that by changing the numbers back to 5.0 in a post build step. Just changing those numbers should allow the exe to start on XP unless the new CRT is using WinAPI functions that don't exist on XP.
The other alternative if you want to keep using VS11 is to use multi-targeting and older compilers...
Visual Studio 2012 will be able to target Windows XP later in 2012:
Targeting Windows XP with C++ in Visual Studio 2012
"Later this fall, Microsoft will provide an update to Visual Studio 2012 that will enable C++ applications to target Windows XP. This update will make the necessary modifications to the Visual C++ 2012 compiler, runtime, and libraries to enable developers to create applications and DLLs that run on Windows XP and higher versions as well as Windows Server 2003 and higher."
Edit: This has now happened (phew!)
The workaround is to use a different Platform Toolset, which will link a different version of CRT and produce binaries compatible to older operating systems.
See more here: Target Windows XP in Visual Studio 11 Beta using the Visual Studio 2010 compiler and libraries.
With v90 toolset your binary will be able to run even in older systems, such as Windows 2000.
http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-65-69/7444.BlogPic.png
The runtime libraries bundled with VS 2010 and higher enforce your executable to import two new functions from kernel32.dll that are missing on Windows XP: EncodePointer and DecodePointer. Those are needed for yet another idiotic naive attempt to enhance the software "security".
In VS 2010 there is an option to use the runtime libraries of Visual Studio 2008, which solves this problem. I don't know if there's such an option in later versions of VS.

What is special about the executables compiled with Visual Studio 11 which results in that the executables cannot be executed on Windows XP?

I compile my C++ source code with Visual Studio 11 Developer Preview. I statically link to the runtime library.
The resulting executable cannot be executed on Windows XP. When I try to execute it on Windows XP I get the error message "[Executable Path] is not a valid Win32 Application.".
According to Microsoft Visual Studio 11 won't support Windows XP.
How does it work that the resulting executable cannot be executed on Windows XP? Is there anything special within the executable?
They seem to drop support for older systems in every new release of VS (NT4,2000,XP) Even if you don't use the CRT at all, they still force the PE subsystem version to high numbers. You can work around that by changing the numbers back to 5.0 in a post build step. Just changing those numbers should allow the exe to start on XP unless the new CRT is using WinAPI functions that don't exist on XP.
The other alternative if you want to keep using VS11 is to use multi-targeting and older compilers...
Visual Studio 2012 will be able to target Windows XP later in 2012:
Targeting Windows XP with C++ in Visual Studio 2012
"Later this fall, Microsoft will provide an update to Visual Studio 2012 that will enable C++ applications to target Windows XP. This update will make the necessary modifications to the Visual C++ 2012 compiler, runtime, and libraries to enable developers to create applications and DLLs that run on Windows XP and higher versions as well as Windows Server 2003 and higher."
Edit: This has now happened (phew!)
The workaround is to use a different Platform Toolset, which will link a different version of CRT and produce binaries compatible to older operating systems.
See more here: Target Windows XP in Visual Studio 11 Beta using the Visual Studio 2010 compiler and libraries.
With v90 toolset your binary will be able to run even in older systems, such as Windows 2000.
http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-65-69/7444.BlogPic.png
The runtime libraries bundled with VS 2010 and higher enforce your executable to import two new functions from kernel32.dll that are missing on Windows XP: EncodePointer and DecodePointer. Those are needed for yet another idiotic naive attempt to enhance the software "security".
In VS 2010 there is an option to use the runtime libraries of Visual Studio 2008, which solves this problem. I don't know if there's such an option in later versions of VS.