6

In my VS2012 I have 4 toolsets available: v90, v100, v110 and v110_xp. I did a simple test with two projects testlib (a static library) and testexe (console application). The interface was just one function with signature void test(). The results:

  • testlib(v90), testexe(anything other than v90) -> does not link
  • testlib(v100), testexe(v110 or v110_xp) -> does link

However, it seemed somewhat weird to me that v100 and v110 would link so I tried to complicate the scenario a little bit. Now my method looks like this: std::map<std::string, std::string> test(const std::string& arg). As expected, the testlib(v100) and testexe(v110) do not link (mismatch detected for '_MSC_VER').

But still the testlib(v110) and testexe(v110_xp) do link and the resulting exe works on Windows XP. Is this just by chance or is this a supported scenario? If this is just by chance then an example code that is using only features available in v110_xp and breaks this compatibility would be welcome. I am wondering whether I should deploy two versions of my library to my clients or just the one compiled with v110 will do.

Tomasz Grobelny
  • 2,666
  • 3
  • 33
  • 43
  • You left out the November 2012 CTP, which at least attempts to get near implementing the C++11 standard (you know thats hard; ask Herb =P). – WhozCraig Jan 20 '13 at 15:52
  • It sounds like you're exposing standard-based objects out of your library (like std::string, etc) and hoping it 'just work' with clients of said-library built on a different toolchain. Even if they are vendor-specific (in this case, all from MS), the difference in name-mangling algorithms alone is not guaranteed, much less a full [ABI](http://en.wikipedia.org/wiki/Application_binary_interface) for any lib-based implementation of their code. Unrelated: I didnt know 2012 came with a v9 toolchain, btw. Do you have vs2008 on the same machine? – WhozCraig Jan 20 '13 at 16:18
  • Yes, I have vs2008, vs2010 and vs2012 installed on this machine - the intro of my question might have been a bit misleading. – Tomasz Grobelny Jan 20 '13 at 16:36

3 Answers3

12

The word "toolset" is a bit of a misnomer to describe the differences between v110 and v110_xp. You are still using the same build tools. And you still have the same version of the CRT. Something you can see by comparing what you see in the Debug + Windows + Module list of loaded DLL between the two builds. Note the name and location of msvcr110.dll.

The CRT was in fact updated by Update 1, it now supports both XP and newer Windows versions. This works by it binding dynamically to the later winapi functions at runtime, using GetProcAddress(), limping along if it can't find them when you run on XP.

What is different is that you got another version of the Windows SDK. The last one that was still compatible with XP, version 7.1. You'll find it back in C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A. When you build with the v110 toolset then you'll use the SDK include and library files stored in C:\Program Files (x86)\Windows Kits\8.0

The specific changes when you use v110_xp are visible when you search the c:\program files (x86)\msbuild directory for that string:

  • the directories for include and lib files, etcetera, are changed to the Windows 7.1 SDK paths
  • the _USING_V110_SDK71_ preprocessor symbol is added, not otherwise used anywhere important
  • the linker's /SUBSYSTEM option is altered to require only Windows version 5.02, the XP version number.

Long story short, mixing modules that were built with a mix of v110 and v110_xp toolsets is not a problem.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I didn't say anything about CRT or memory allocation. I mentioned importing/exporting classes, and using classes (like vector) interchangeably in different DLL. Assume vector allocated on A.DLL, and being passed to B.DLL - Both DLL are using different compiler/linker. This is very known, exiting, and possibly non-solvable problem! – Ajay Jan 20 '13 at 17:11
  • That's why thought it was worth mentioning it. This unsolvable problem is in fact solved ;) – Hans Passant Jan 20 '13 at 17:13
  • I don't agree to it. Assume I've a DLL built using VS2008, which takes a `map`. Now I am calling it from VS2010/12 built DLL - how you can be sure it wont cause any issue? It's NOT about memory allocation, but about the object itself. – Ajay Jan 20 '13 at 17:16
  • 2
    No, this fix cannot work retroactively of course. It cannot reach in to an old DLL and replace the CRT. It works for VS2012 builds and beyond, the OP's case. – Hans Passant Jan 20 '13 at 17:19
  • @HansPassant, I am sorry. I still disagree with you! I am not at all referring to memory allocation. Just a simple thing CStringA is NOT CStringW, and hence CString would be diff in different builds. A secure version of STL is not same as unsecure. Know what I am saying!? – Ajay Jan 20 '13 at 18:19
  • @HansPassant your conclusion is that "mixing modules that were built with a mix of v110 and v110_xp toolsets is not a problem". What happens when I build my application with v110_xp and statically link to the boost libraries that were built using v110 - will it run under WinXP? (Or the other question would be: how to build the boost libraries with v110_xp? It looks like this new toolset is not supported yet by boost.build - or do you have a solution for that?) – Robert Hegner Jan 29 '13 at 08:30
  • @RobertHegner: "the testlib(v110) and testexe(v110_xp) do link and the resulting exe works on Windows XP" - not sure about boost, but there is a chance it will work ok. – Tomasz Grobelny Jan 29 '13 at 12:25
  • @TomaszGrobelny yes in your simple test scenario. But I still have your original concern - "Is this just by chance or is this a supported scenario"? Hans Passant is very clear about _building_ a mix of v110 and v110_xp (same compiler, same linker, same CRT, so no problem at build time). But does such a combination _run_ under WinXP in any case? What happens if testlib(v110) uses some v8.0 WinAPI functions? Will I get some meaningful exception or will it just silently crash? I don't really feel confident with using boost(v110) with exe(v110_xp) in a production environment... – Robert Hegner Jan 29 '13 at 15:30
  • 1
    There is never a workaround for setting the _WIN32_WINNT macro wrong. You *have* to target the Windows version you want to support. If that is XP then you have to set it to 0x0501 so you can't accidentally use winapi functions that are only available in later Windows versions. This is quite unrelated to the toolset, it is a general requirement. – Hans Passant Jan 29 '13 at 16:01
5

Mixing v110_xp executables and v110 libraries is officially unsupported.

Having escalated this issue separately with Microsoft they responded to these questions:

Q1: Can the application which uses these libraries (v110) and is built with toolset v110_xp run properly on Windows XP machine?

Only executable built with v110_xp toolset can run properly on Windows XP machine. As a result, if the application need to run properly on Windows XP machine, you will need to make sure that your project is switched from the default v110 toolset to the newly introduced v110_xp toolset inside your project’s property pages, including the executable and DLLs if there is any.

Q2: Do we need to release another version of these libraries built with toolset v110_xp?

I think this depends on what kinds of platform do you need to deploy your application on. If your deployment plan includes Windows XP machines, it is necessary to release a new version of the executable/DLLs built with v110_xp toolset. However, considering that the same executable/DLLs built with v110_xp toolset will also run on Vista and later, I suggest that you can just keep a single version of the executable/DLLs built with v110_xp toolset and this can run on all of other platforms. When Windows XP is no longer in your deployment plan, then you can convert the whole executable/DLLs to be rebuilt with v110 toolset. Certainly it will be good if you can maintain the two versions of executable/DLLs in the same time if you want to target Windows XP and other system separately.

Q3: Does Microsoft support libraries built with toolset v110 on Windows XP?

The answer is NO. Everything needs to be built in v110_xp mode if you want to run the application properly on Windows XP.

Steve-o
  • 12,678
  • 2
  • 41
  • 60
  • Makes sense for DLLs. But the original question was about static libraries. – Tomasz Grobelny Apr 11 '13 at 20:18
  • As HansPassant pointed out: "you still have the same version of the CRT". The point I'm trying to make is that in my opinion the two answers do not contradict each other and both are valid. Except that the one by HansPassant is more relevant to the question (but still thanks for sharing this). – Tomasz Grobelny Apr 14 '13 at 18:44
  • @TomaszGrobelny Microsoft's response is for both shared and static libraries. Static libraries on Windows [target a specific CRT](http://stackoverflow.com/q/5375714/175849) so you still end up with a mess. – Steve-o Apr 14 '13 at 22:01
  • I have an exe which does not work on windows XP. Can I detect that it was not compiled in v110_xp mode or something like that? – Tomas Kubes Apr 09 '14 at 19:06
1

Please do not mix DLL having/exporting classes with different versions of Visual Studio (even minor version differences). STL and MFC have classes built on top of templates (classes itself may not be templatized for the user), which prevents linking and/or compilation between different versions.

A simple example would be CString: static and dynamic linking with MFC would have different CString implementations. Unicode and ANSI CStrings are also different. Another example is STL itself: Debug build vector is different than release build vector. Also, in case of STL collections, compiler settings would also change the size/implementation of container (like vector, list).

So, it better not to import export classes/functions having these type of classes as parameters. Don't even pass them in opaque way (like on top of a void-pointer).

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • Ok, I understand that mixing different versions is not possible (as shown above). But now I am using only the latest VS2012 with its specific toolsets (v110 and v110_xp). Am I allowed to mix those two toolsets? – Tomasz Grobelny Jan 20 '13 at 16:41