When building a project or solution using a specific version of
msbuild
I can select an earlier .net toolchain by using the
/toolsversion
or
/tv
switch:
"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
This Just Works for all versions of
msbuild
, and the version of
csc.exe
etc. is correctly chosen based on the above:
> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:4.0 amazing.sln
...
CoreCompile:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe ...
...
> "C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
...
CoreCompile:
C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe ...
...
If I
don't specify
/tv
, then depending on which version of msbuild I'm using and a number of environment variables, I may get any of:
- The ToolsVersion specified in the top-level element in the project file
- The ToolsVersion corresponding to the version of
msbuild.exe
I'm using
- A value from
msbuild.exe.config
- A value from the registry
(See the
different versions of the Overriding ToolsVersion Settings page on MSDN).
So, in order to have builds that have consistent results on the build server and on my local machine, I use
/tv
when running
msbuild.exe
(in fact, this is enforced in a
psake
script, which also ensures it uses the corresponding version of
msbuild.exe
).
However I cannot use the
/tv
switch when building with Visual Studio. Instead, Visual Studio 2013 and up will use the .net toolchain that shipped with that version of Visual Studio
unless:
This is so baroque that I cannot believe anyone is actually doing it. My questions are thus:
And lastly:
- Should I even care? Given that each successive version of the C# compiler should be able to handle previous versions' input, and I can set the target .net framework and C# language level in the project file, is this enough to ensure repeatable builds?
(My prejudice is that I
should care, since:
- I want builds in the IDE and on the build server to be the same (of course)
- I want to be able to use VS2015 (and future versions) because it's a better IDE than previous versions, but I don't want to be obliged to use the new toolchain until I decide to.
Perhaps I want too much...)
For a concrete example of the problem, please see my
msbuild-vs-vs2015-toolsversion repository on github.
Some background: I'm asking this because we recently had a CI build error when one of my colleagues submitted C# 6.0 code that compiled fine with Roslyn on their copy of Visual Studio 2015, but failed in CI because
that uses the previous release of the .net toolchain (they'd used an automatic property with no setter, which is fine in Roslyn but not in earlier versions). We will be updating the CI build to Roslyn, but I wanted to see if we could prevent this sort of thing happening in the future.