Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSBuild Inheriting Platform Toolset

I am attempting to overhaul my project's build processes. We have ~330 Visual C++ projects that we have upgraded in the last year from Visual Studio 2005 to Visual Studio 2013. I would like to take advantage of MSBuild to improve our build time over our very serial build scripts that we have now. I have completed a rough first pass and dropped the build times for a Release build from ~2 hours to ~20 minutes. In the process of doing this, I am consolidating a lot of common project settings into a .props file . In doing so, I have hit a stumbling block.

I wish to inherit the Platform Toolset from one VSProps file to all of the projects that include it. At the top of the new .props file I created, I put the following:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="Configuration">
   <PlatformToolSet>v120</PlatformToolSet>
</PropertyGroup>
<PropertyGroup Label="UserMacros" />

I then removed the corresponding <PlatformToolSet>v120</PlatformToolset> from the individual project files.

Alas, things have started to go downhill. The projects (in Visual Studio 2013) now say in the Solution Explorer something like CoreGeometry (Visual Studio 2010) and the projects themselves seem to want to reference the v100 platform toolset. When I build, it then complains at me:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(362,5): warning MSB8003: Could not find WindowsSDKDir variable from the registry. TargetFrameworkVersion or PlatformToolset may be set to an invalid version number.

1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(341,5): error MSB6006: "CL.exe" exited with code -1073741515.

The only way I have been able to work around this is to manually set the PlatformToolset on the .vcxproj themselves, which is not terrible, I just am a bit annoyed that every other property seems to inherit, but the PlatformToolset does not.

My question is thus: Can I use a .props file to inherit a common PlatformToolSet into a .vcxproj that does not specify a platform toolset?

A second question: Should I even be messing with the Platform ToolSet in this manner or am I setting myself up at risk for a maintenance nightmare later?

like image 984
Kevin K Avatar asked Oct 25 '25 05:10

Kevin K


1 Answers

It is very good practice to extract common settings to a separate .props file and <Import> that from all projects. I am doing the same with my projects, including configuring PlatformToolset property in .props file, and I have no problems building it this way.

Few points related to this:

  1. There is nothing special about PlatformToolset property, or any other property for that matter. Configuring properties inside .props file is identical to setting it inside .vcxproj file directly (however see my point below about ordering). Of course, there are some built-in properties, which you cannot configure at all, but those are always read-only properties.
  2. The only case where you would not be able to override a property, if it the property value is passed directly from command line for the build (e.g. msbuild mysolution.sln /p:Platform=x86 will have everything built with Platform property set to x86 and overrides in projects won't take effect).
  3. There is a difference between msbuild engine interpreting your projects and Visual Studio showing settings for the project. In some cases you might find that after refactoring .vcxproj files some standard project configuration dialogs not showing information you configured in .props file. To alleviate this, make sure that your <Import> command for .props file is always able to locate the .props file, by setting absolute path to .props file. Second, ensure you specify Label attribute for the <PropertyGroup> element in your configuration file like it was specified in your .vcxproj file.
  4. Finally, make sure your <Import> element is in the right place. Usually you want it to be the very first Import, before you import standard .targets and .props, like Microsoft.Cpp.defaults.props, etc. The reason is msbuild works by performing sequential scans through the statements, so order of instructions matter.

To make #3 and #4 easier, here is a trick to specify absolute path to the .props file. Assume that your solution name is MySolution.sln and custom props file is MyCustomProps.props, placed in the same directory where solution is:

<PropertyGroup>
       <RootFolder>$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory),MySolution.sln))</RootFolder>
</PropertyGroup>
<Import Project="$(RootFolder)\MyCustomProps.props" />
like image 187
seva titov Avatar answered Oct 28 '25 04:10

seva titov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!