-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wrong VisualStudioVersion set by Microsoft.Common.props #52
Comments
This is "by design" because you're using the .NET 4.X version of the MSBuild engine, which does not officially support VS 2013+ projects. Per the comment in Microsoft.Common.props above the line you flagged:
If you update your tool to instead use the VS 2013 or VS 2015 (or OSS :) ) version of MSBuild, you should no longer see the behavior difference caused by the common props. (Although as explained below, you will also default to always using the "current" ToolsVersion instead of reading it from the project file.) Historical background for the curious: In VS 2013, we updated ToolsVersion for the first time since Visual Studio started making asset compatibility guarantees (VS 2010 SP1). At that point, we had to figure out what it meant for, e.g., MSBuild N to build a compatible project from VS N+1, and the above code is part of the answer we came to. Specifically, the answer to the question of "what happens when VS 2012 (MSBuild 4.X) attempts to build a VS 2013 (MSBuild 12) project?". Until VS 2013, we'd simply read the "ToolsVersion" tag in the project and used it. That worked in the world pre-VS 2010 SP1, where Visual Studio forced an update to the ToolsVersion every release and only supported loading projects with that ToolsVersion -- if something was ToolsVersion 3.5, you could depend on the fact that it only worked with, and was only expected to work with, VS 2008. And if someone tried to build a ToolsVersion 3.5 project on a machine without VS 2008 / .NET 3.5 installed ... well, that was their problem. (Side note: we're speaking specifically of build process components, not the core engine, here. All later versions should be capable of building projects from all earlier versions of MSBuild, with the appropriate build process, as long as that build process is installed.) It also worked in the world of VS 2010 SP1 / VS 2012, because due to MSBuild being an in-place update from 4.0 -> 4.5, the ToolsVersion didn't change -- all tool differentiation was done at the sub-toolset level (as directed by VisualStudioVersion). However, in VS 2013, with ToolsVersion 12.0, and with the expectation that the following release would update ToolsVersion yet again, we had to answer the question, "What is the appropriate behavior for a ToolsVersion 14.0 project loaded in VS 2013?" We couldn't just say "Use the 14.0 build process", because (a) there's no guarantee that VS 2015 would even be on the machine, (b) since VS 2013 is built against MSBuild 12, if there was any new MSBuild syntax introduced in VS 2015, there was a non-trivial chance that MSBuild 12 wouldn't even be able load or build the project, and (c) even if MSBuild could, if there were sufficiently large functional differences in the build process for a particular project type between VS 2013 and 2015, all the VS support infrastructure (project systems, designers, etc.) might behave in strange/unexpected ways. So the answer we came to was that we'd make MSBuild ignore the "ToolsVersion" tag in project file by default, and always use the "current" ToolsVersion. Thus, in the above example, even though the project file said 'ToolsVersion="14.0"', VS 2013 (MSBuild 12) would build the project as though it were a ToolsVersion="12.0" project. All tools would be known to exist, all behavior would be as expected. Cool. That solved VS 2013 and all future versions of VS. However, the asset compatibility guarantee wasn't just "VS 2013 and up", it included VS 2010 SP1 and VS 2012, which were based on MSBuild 4.0 and 4.5 respectively. In MSBuild 4.0, we'd added some much simpler defaulting logic: If MSBuild didn't recognize the ToolsVersion in the project file, it would default to the current version ("4.0"). So as long as someone loaded a 12.0 or higher project on a machine with ONLY VS 2010 and/or VS 2012 installed, we were also fine. But if someone, say, attempted to load a ToolsVersion 12.0 project in VS 2010 SP1 on a machine with both that and VS 2013 installed, MSBuild 4.X (probably technically 4.5.1 since that's what comes with 2013) would happily load the project up as a ToolsVersion 12.0 project ... right until the point where it ran into a construct it didn't recognize, at which point it would log some likely-unhelpful error and exit. We couldn't do anything about the fact that MSBuild 4.X would attempt to load the project as a ToolsVersion 12.0 project. (At least not without changing MSBuild 4.X, which would have been ... logistically difficult.) What we could do, however, was make that ToolsVersion 12.0 project "look like" a ToolsVersion 4.X project as much as possible. To do this, we added a new built-in property, MSBuildAssemblyVersion, that we could then key off of in the targets: if it existed, we were 12+, business as usual. If it didn't exist, we were 4.X trying to build a 12+ project, and tweaking was required. Thus the above code in Microsoft.Common.props, to reset VisualStudioVersion to one of the allowed 4.X values: 10.0 or 11.0. Thus also the redirection code e.g. here: https://github.com/Microsoft/msbuild/blob/master/src/XMakeTasks/Microsoft.Common.targets#L32 to make sure that, when a project imported "$(MSBuildToolsPath)\Microsoft.Common.targets", it would get the 4.X one, instead of the 12+ one. This wasn't a 100% complete solution:
But we found that in practice, most of the time it was "good enough". |
* Silence some warnings about things that MSVC 2015 warns about that MSVC 2013 didn't. * Change the solution so that it opens in Visual Studio 2015 if Visual Studio 2015 is installed. * Change ToolsVersion to 14.0 in the project files so that Visual Studio 2015 does not put a warning in the build log about the version being 12.0. This means that Visual Studio 2013 will have a warning, but the warning is harmless, and if we have to choose, it's better for VS 2013 to warn than VS 2015 to warn, in the long term. See dotnet/msbuild#52 (comment). * Build with the VS 2013 XP-compatible toolchain if using Visual Studio 2013 (including its msbuild); Otherwise build with the Visual Studio 2015 XP-compatible toolchain. See https://social.msdn.microsoft.com/Forums/vstudio/en-US/ \ d06c3741-c637-4627-9b1a-1e068803a067/ \ setting-platformtoolset-value-based-on-vs-version.
* Silence some warnings about things that MSVC 2015 warns about that MSVC 2013 didn't. * Change the solution so that it opens in Visual Studio 2015 if Visual Studio 2015 is installed. * Change ToolsVersion to 14.0 in the project files so that Visual Studio 2015 does not put a warning in the build log about the version being 12.0. This means that Visual Studio 2013 will have a warning, but the warning is harmless, and if we have to choose, it's better for VS 2013 to warn than VS 2015 to warn, in the long term. See dotnet/msbuild#52 (comment). * Build with the VS 2013 XP-compatible toolchain if using Visual Studio 2013 (including its msbuild); Otherwise build with the Visual Studio 2015 XP-compatible toolchain. See https://social.msdn.microsoft.com/Forums/vstudio/en-US/ \ d06c3741-c637-4627-9b1a-1e068803a067/ \ setting-platformtoolset-value-based-on-vs-version.
remove the dependency on MSBuild from .NET 4 as it will give wrong results for VS2013 onwards, as per dotnet/msbuild#52
Since the VisualStudioVersion resolves to 10 instead of 14 when I create an asp.net core project with the web api template the build is looking for |
oh man, my head hurts. What a mess, but thank you for the explanation. |
1. MSBuild tools version is generally does not correlate with the Visual Studio or SDK version, and the changes between different versions of scripts under Contracts/MsBuild/ were inconsequential anyway. We now use a common set of build files for all MSBuild versions 4.0 and above. See dotnet/msbuild#52 (comment) for the elaboration on the versioning conventions. 2. Generated contract assemblies are included into the project's output group (BuiltProjectOutputGroupOutput), and therefore picked up by the Pack target to be included into the package.
MSBuild tools version is generally does not correlate with the Visual Studio or SDK version, and the changes between different versions of scripts under Contracts/MsBuild/ were inconsequential anyway. We now use a common set of build files for all MSBuild versions 4.0 and above. See dotnet/msbuild#52 (comment) for the elaboration on the versioning conventions.
1. MSBuild tools version is generally does not correlate with the Visual Studio or SDK version, and the changes between different versions of scripts under Contracts/MsBuild/ were inconsequential anyway. We now use a common set of build files for all MSBuild versions 4.0 and above. See dotnet/msbuild#52 (comment) for the elaboration on the versioning conventions. 2. Generated contract assemblies are included into the project's output group (BuiltProjectOutputGroupOutput), and therefore picked up by the Pack target to be included into the package.
Merge upstream master branch and update SDKs accordingly
The
VisualStudioVersion
property is correct withoutMicrosoft.Common.props
, but with that props file, the property ends up being10.0
for ToolsVersion12.0
and14.0
.I am using Microsoft.Build.Evaluation.Project to load the project files with the constructor to pass in the global properties. Loaded from assembly: C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Build\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.Build.dll
The
VisualStudioVersion
appears to depend on two things:the
ToolsVersion
in the project filethe
Microsoft.Common.props
if it existsno ToolsVersion and no common.props has no VisualStudioVersion
MSBuildToolsVersion 2.0
MSBuildToolsVersion 11.0
MSBuildToolsVersion 10.0
MSBuildToolsVersion 10.0
I consider 7 & 8 to be bugs. I think this is the cause:
https://github.com/Microsoft/msbuild/blob/master/src/XMakeTasks/Microsoft.Common.props#L38
More info: ctaggart/SourceLink#50 (comment)
The text was updated successfully, but these errors were encountered: