Visual Studio 2012 First Impressions
A few weeks ago we released ODB 2.1.0. Besides a large number of new features, this version also added support for Visual Studio 2012. Specifically, all the runtime libraries, examples, and tests now come with project/solution files for and were successfully tested with Visual Studio 2012 in addition to 2010 and 2008. This blog post is a collection of notes on differences between Visual Studio 2010 and 2012 that we encountered while working on adding this support. The notes primarily focus on C++ and you may find them useful if you plan to migrate to 2012 or if you want to add support for this version of Visual Studio in your project.
The first thing that you will notice when installing Visual Studio 2012 (VS2012 from now on) is that you can no longer install just the C++ development environment. Now all the languages are always installed. So make sure you have enough free space available. VS2012 co-exists fine with VS2010 and VS2008 provided you install SP1 for VS2010. Failed that you will get a weird error from the linker saying that the COFF file is corrupt. To test ODB we have all three versions of VS installed on the same virtual machine and everything works fine.
After installing VS2012 I was preparing myself mentally for the mind-numbing task of setting up all the include/library search paths in VC++ Directories. In my case those are needed for all the 5 databases that ODB supports, all the ODB runtime libraries, plus Boost and Qt. Multiply that by two for 32 and 64-bit configurations, and you end up with a lot of directories. BTW, getting to the VC++ Directories dialog in VS2012 is exactly the same as in VS2010. That is, open the Property Manager tab, then open Microsoft.Cpp.Win32.User or Microsoft.Cpp.x64.User sheet.
Imagine my surprise when I opened this dialog for the first time and saw all the directories pre-populated! For a moment I thought, finally, Microsoft actually did something sensible for a change. However, my joy was short lived. At first I thought that VS2012 simply copied the directories from VS2010 and all I needed to do is just tweak them a bit. But then I realized that Microsoft could have also done something else: they could have shared the entries with VS2010! So I quickly modified one entry in VS2012 and sure enough I saw the same modification appearing in VS2010.
Why is this bad news? We all know that mixing libraries built using one version of VS with applications that use another is asking for trouble. In fact, some libraries, such as Qt, go a step further and actively prevent you from doing this by prefixing their symbols with the VS version. The fact that you are now forced to share VC++ Directories between VS2010 and 2012 just shows that Microsoft still doesn’t understand how developers are using their product.
Luckily, there is a fairly easy workaround for this problem. The idea is to include the VS version number into the path and then use the $(VisualStudioVersion)
variable in the VC++ Directories entries. Here is an example for the ODB runtime library, libodb
. First step is to create two directories with the library source code, say libodb-vc10.0
and libodb-vc11.0
. Then build libodb-vc10.0
with VS2010 and libodb-vc11.0
with VS2012. Once this is done, the final step is to open the VC++ Directories dialog (doesn’t matter whether it is VS2010 or 2012) and add the following paths:
Include: ...\libodb-vc$(VisualStudioVersion) Library: ...\libodb-vc$(VisualStudioVersion)\lib
In ODB, VS project and solution files are automatically generated from templates. So for us the first step in adding support for VS2012 was to come up with suitable library and executable project templates. As it turned out, it was actually easier to convert VS2010 projects to VS2012 rather than create ones from scratch. Comparing the 2010 and 2012 project files (.vcxproj
) revealed that the only difference between the two is the addition of the following PlatformToolset
tag after UseDebugLibraries
in each configuration:
<PlatformToolset>v110</PlatformToolset>
Similar to the project files, the VS2012 solution files (.sln
) are exactly the same except for the VS version embedded in them. The project filters files (.vcxproj.filters
) haven’t changed. So all that was needed to convert VS2010 project/solution templates to VS2012 was a couple of simple sed
scripts. Overall, in case of ODB, it took about half a day to create all the templates and update all the scripts. And another day to build and test all the configurations for all the databases.
I also haven’t encountered any spurious errors or warnings when compiling ODB with VS2012 compared to 2010. Though ODB source code was already fairly clean thanks to being tested with the latest versions of GCC and Clang with all the warnings enabled.
Compilation speed-wise, I haven’t noticed any significant improvements. While I haven’t done any thorough testing in this area, SQLite build times show a marginal improvement (39s for VS2012 vs 43s for 2010).
Finally, when it comes to C++11 support in VS2012, it appears Microsoft concentrated on user-visible features (like range-based for
-loop) at the expense of library-level ones. As a result, the list of unsupported C++11 features that could be useful in ODB is exactly the same for VS2012 as for 2010:
#if _MSC_VER >= 1600 # define ODB_CXX11 # define ODB_CXX11_NULLPTR //# define ODB_CXX11_DELETED_FUNCTION //# define ODB_CXX11_EXPLICIT_CONVERSION_OPERATOR //# define ODB_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGUMENT #endif
October 10th, 2012 at 2:36 pm
Your issue pertaining to your include and library directories and so forth. Have you looked into creating your own Property Sheets instead of editing Microsoft.Cpp.Win32.User or Microsoft.Cpp.x64.User directly? This way you can set specific properties per solution/project and keep things separate if so required.
Alternatively properties that are not specific to a solution can be shared by loading the same Property Sheet in the various projects where required.
I suspect this would avoid the problems you encountered re VS2010 and VS2012 sharing
October 11th, 2012 at 7:44 am
Kenneth, the problem with this approach is it requires modification of each project. In my case that would be hundreds of them. Plus, what I am looking for here is the equivalent to /usr/{include, lib} on UNIX; i.e., a mechanism to locate common headers/libraries (e.g., database access libraries) without having to hardcode non-portable locations into project files/makefiles.