Binary compatibility between VS2017 and VS2015 - abi

This SO post:
Is Visual-C++-2017 binary compatible with VC++-2015? clearly says that VS 2017 is binary compatible with VS 2015. It even looks like the official position.
My question is, in the past, I distinctly remember running into linker errors (I do not recall the specific set of errors) every time I try to link in a static library that was compiled with a different version of MSVC into an EXE that is being built with a newer version of MSVC.
Yet, binary (in)compatibility sounds like something that will blow up in your face at runtime, not link time.
Can someone tell me if previous versions of MSVC did indeed producer linker errors on version mismatches? How was this accomplished?
EDIT
How does this affect static libraries built with WPO/LTCG turned on? I believe these produce intermediate object files (as opposed to COFF) and Microsoft did not guarantee the format of these intermediate files to remain stagnant across different versions of the compiler.

As I answered on the linked question, the v140 toolset in VS 2015 and the v141 toolset in VS 2017 are binary compatible. v141 was built as a member of the same "family" as all the updates to v140 (e.g., VS 2015 Update 1, 2, 3) were all in the same family. This was an intentional design decision that helps developers to move to a new version of VS without worrying about having to make changes in their source code.
VS 2017 can support multiple toolsets. The next toolset will not be binary compatible with v140/v141. But you'll still be able to install v141 as you move your code to be compatible with the new C++ features in the next toolset.
Note that we never have supported binary compatibility across major versions. You can't link a binary built with v140 and a binary built with v130, regardless of WPO/LTCG/etc. Yes, it often works--we try to minimize breaking changes in our libraries so often it is the case that linking some code across major versions doesn't hit any errors. But eventually you'll run into something that changed and you'll see an error.
As to whether you see a link error or a runtime error, that depends on the incompatible library API that you called. If the exported shape of the API changed--the name of the function, the number of parameters--then the linker will fail to find it. If the shape is the same but the behavior has changed, you can end up with a runtime failure.
--Andrew Pardoe, MSVC tools

Microsoft claims that they are compatible, and this is supported by the compiler verison number which was just bumped from 1400 to 1410 this time:
https://blogs.msdn.microsoft.com/vcblog/2017/03/07/binary-compatibility-and-pain-free-upgrade-why-moving-to-visual-studio-2017-is-almost-too-easy/

Related

How to configure nvidia CUDA for VIsual Studio 2017 [duplicate]

Visual Studio 2017 RC includes much tighter CMake integration, allowing one to skip the intermediate step of generating project/solution files and use CMake effectively as the project file itself. There is sufficient documentation from Microsoft for using these features with regular C++ files, and there is sufficient documentation on this website (example) for making CUDA and Cmake play nicely, when it comes to linking CUDA code to C++ code.
What I can't find information on is how to make CMake, Visual Studio 2017 RC, and CUDA 8.0 all play nicely. This is a difficult problem, because 2017RC has no integration for the CUDA SDK anyways, and I was hoping to use 2017RC so that my C++ interface to the CUDA code could use C++14 and/or C++17. I'm working on the beginning of a large project that will primarily involve writing a static CUDA library that is accessed through C++: so, I'd like to get the CMake to take care of compiling my CUDA sources into a static library, and for it to help with feeding the linking information to Visual Studio. So far, I haven't had any success with using FindCUDA's various features to accomplish this, but I'm assuming that's due to a misunderstanding on my part. I've read through the documentation on separable compilation from Nvidia, but that wasn't helpful for figuring out CMake.
Further, whenever I try to use CMake in VS2017RC, I still end up with the various vcxproj files that CMake likes to spit out. Is this due to an error on my part? How do I edit the build command arguments, or CMakeLists.txt, to get the functionality demonstrated here to work?
The very short (and only at the time of writing) answer is that you can't. CUDA 8 doesn't support VS2017. Only VS2015 is presently supported.
You can always find the compiler/IDE versions which the release version of CUDA supports here
Edit to add that the CUDA 9 release will add official support for VS2017.
All you need to do is set the CUDA_HOST_COMPILER variable to a supported compiler for example the visual studio 2015 compiler.
In my case this is:
C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe
As both runtime libraries are binary compatible you can use the 2015 compiler within CUDA and compile all the rest of the application with the 2017 compiler.

How can I check the LIB file version?

After reinstalling Visual Studio 2010, I recompiled the code and encountered the following error:
Error 'LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt'
A solution mentioned that the lib file is incompatible and I need to install Visual Studio 2010 SP1. I did that, and now it has been solved.
I am wondering how can I check whether a lib file is created by SP1 or not?
I tried dumpbin, but I cannot find the version in its result.
It was not an incompatibility with your LIB file that caused the problem here, so checking the version of the linker that created it would not be a solution anyway.
The issue is that cvtres.exe (used internally by the linker toolchain) depends on a particular DLL (msvcr100_clr0400.dll) shipped with VS 2010 RTM. When you update to a later version of the .NET Framework (e.g., by installing .NET 4.5 or installing a later version of VS), this DLL is replaced. That stops cvtres.exe from working.
The reason why installing VS 2010 SP1 fixes it is because it actually modifies the cvtres.exe application to break the dependency. And now that all pieces of the linker toolchain work, you can compile and link the code without error.
Of course, there are other problems you can have when you start mixing libraries created by different versions of the compiler and/or linker. They aren't guaranteed to create 100% compatible output, so mixing them is not supported (at least not between major versions, I'm uncertain about how this rule applies to service packs).
In general, it's best to just recompile all libraries whenever you update your build system. The only time you wouldn't do this is if you didn't have the source code, in which case, you need to be very careful about updating your build system, lest you introduce gratuitous incompatibilities.
As far as determining the version of the linker that prepared a particular binary, using dumpbin.exe (included with the SDK) is exactly the correct approach. For static libraries, run the following command from the Visual Studio SDK Command Prompt:
dumpbin /rawdata:1 MyLibrary.lib
You'll see the assembly manifest, which will include the full path to the compiler used to build the library as well as the version of the CRT that it depends upon.
For dynamic libraries (i.e., DLLs) and executables, run the following command:
dumpbin /headers MyApp.exe
Look under the "Optional Header Values" section (not actually optional) for the version of the linker, along with a timestamp of when it was generated.
Note that you're very unlikely to find this information in release builds of a library or binary.

Compiling Visual Studio 2010 project in VS 2012 (C++): error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700'

I've been sent a sample app for a newly minted SDK, and I can't compile it - it won't compile at all in Visual Studio Express for reasons of ATL, and that seems to be the only version of VS 2010 that Microsoft still makes available. So I'm trying to compile it in VS 2012 Professional, but it gives me error LNK2038. From what I can gather e.g. from this thread, the problem is down to trying to use .lib files compiled for 2010 in the 2012 version. Since I'm not the one who compiled the .lib, and I don't have the code for it, and VS 2010 is inaccessible, I'm really not sure what to do about this unless the original authors recompile it. Any suggestions? Something basic I'm missing? Many thanks for any help.
Library files cannot be reused across different versions of the compiler. You will need to do one of the following:
Compile your project with the same version of the compiler used for creating the library files you have.
Obtain new library files from the owner of the code, compiled using the same compiler you are now using.
Obtain the source code for the libraries, and compile new versions of them yourself.
Rewrite the code you own to not depend on the libraries you cannot control, since your build environment does not allow for their use.

Why do 3ds Max plug-ins need to be built with a specific version of Visual C++?

The requirements listed in the 3ds Max SDK state that plug-ins for 3ds Max 2011 must be built with Visual C++ 9.0 (Visual Studio 2008).
If I create a DLL with a different version of Visual C++, won't the binary be identical? Is this simply a matter of choosing the right compiler settings?
What problems will I run into if I try to build a plug-in using Visual C++ 2010 (Visual Studio 2010)?
I don't know specifically for 3ds Max, but the usual reason is the C Runtime library. If the host application uses the DLL version of the CRT, then plugins will also need to use the same version.
Otherwise, imagine the case where your plugin creates some memory using malloc(), and passes it to the host application, which uses it and then calls free(). If your plugin and the host application are using different CRTs, the host's call to free() will fail or crash because it wasn't the host's CRT that malloc()ed that block of memory.
The binary won't be identical but the binary interfaces should be, which is what you need.
The reason you can't use VS2010 is because it is not yet production quality. They think you should wait for VS2010 SP1 at a minimum.
You think they are just being obstinate and stubborn, eh? Ruining all your fun. They have reasons. Good ones.
Because of bugs like this:
https://connect.microsoft.com/VisualStudio/feedback/details/565959
I use both visual studio 2008 and 2010 for plugin development.
Only difference I've seen is that the user need the vs c++ runtime version for 2010\2008.
But there might be pitfalls - but I have not encountered any problems with it yet.
C++ doesn't have a standardised binary interface. The compiler "mangles" each symbol name (i.e. each function or static data) to include information about namespaces and signature, so that namespaces, argument overloading, &c. can work. Each compiler is free to decide how to do this. Different MSVS compiler versions do name mangling in different ways, so in general you can't link a C++ library compiled with 2005 and a library compiled with 2008 together: this includes loading a 2008 DLL from a 2005 executable (for example). You can do this if the interface between the libraries is C, as long as the relevant functions are marked with extern "C" to prevent name mangling. And in practice the differences are not always that great: for example, I never had trouble using VS2005 SP1 to compile a library for 3ds Max 9, which supposedly requires VS2005 with no service pack.
Microsoft is trying to fix this incompatibility, so in VS2010 they introduced an option, so VS2010 can produce binaries compatible with VS2005 programs or VS2008 programs (maybe some earlier versions too, I forget). If you have to create a plugin to work with multiple 3ds Max versions, and you don't get caught out by any VS2010 bugs, this is probably a good option. Also, the Intel C++ compiler has a mode where it produces binaries that are compatible with an MSVS version of your choice, which might be a better option for you if it's for hobby use or you can afford the slightly expensive price tag. (They achieve this by copying the way MSVS does name mangling.)

Boost installation on windows

i have downloaded boost_1_42_0,zip but i'm not sure how to set it up. does http://www.boostpro.com/download/boost_1_42_setup.exe has to do something with it?
If you are only going to use header only libraries in Boost then all you need to do is extract the source archive and add an include path to your project to the Boost root location. There's a, possibly not up to date, list of which libs need to be compiled in the Getting Started docs (see Section #3). If you do need to compile things you can follow the instructions in the Getting Started (see 5.2 and/or 5.3). The BoostPro installer is done independently and hence isn't always up to date, although Dave A. And Daniel W. do try to keep it current. But since there's a limit to how many configurations they can account for it has limits as to having the kind of binary you will need, and of course it's only for Visual Studio.
IIRC, the boostpro setup is an alternative way to get Boost running on your system. It is smallish program that starts by asking you which libraries and configurations you want, and then downloads the necessary files on the fly. It is much easier and faster to get going this way than by building from source, but it isn't always up to date, particularly just after a new source release, and only supports Microsoft's compilers, AFAIK.
Boost Getting Started on Windows
How to use Boost in Visual Studio 2010
Boost linking, Visual Studio & version control
Using Boost on Windows (Visual Studio)
Including Relevant Boost Libraries with C++ Source (Using Visual Studio)

Resources