When creating a project or solution using a specific version of msbuild I can select an earlier .net tool chain using the /toolsversion or /tv switch:
"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
This is Just Works for all versions of msbuild , and the version is csc.exe , etc. correctly selected 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 do not specify /tv , then depending on which version of msbuild I am using and a number of environment variables, I can get any of:
- ToolsVersion tool specified in the top-level element in the project file
- ToolsVersion tool corresponding to
msbuild.exe version I am using - Value from
msbuild.exe.config - Value from the registry
(see the various versions of the Tool Parameter Override Settings page on MSDN ).
So, in order to have assemblies that have consistent results on the build server and on my local machine, I use /tv when running msbuild.exe (actually this is enforced in the psake script, which also ensures that it uses the appropriate version of msbuild.exe ).
However, I cannot use the /tv switch when creating using Visual Studio. Instead, Visual Studio 2013 and above will use the .net toolchain that ships with this version of Visual Studio if:
- The environment variable
MSBUILDLEGACYDEFAULTTOOLSVERSION and ... - ... all project files have the ToolsVersion attribute set for the version I want to use.
It is so baroque that I canβt believe that someone is actually doing it. My questions are as follows:
- Does anyone do the
MSBUILDLEGACYDEFAULTTOOLSVERSION thing? - If not, is there another way to force Visual Studio to use a specific ToolsVersion utility that does not use the version of Visual Studio that ships with this ToolsVersion utility? Something that could be saved in version control (for example, in a project or in some other settings file) would be ideal.
And finally:
- I do not care? Given that each subsequent version of the C # compiler should be able to process the input of previous versions, and I can set the target .net structure and the C # language level in the project file, is this enough to ensure repeatability of the assembly?
(My prejudice is that I should take care because:
- I want the 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 is a better IDE than previous ones, but I do not want to be required to use a new toolchain until I decide.
Maybe I want too much ...)
For a specific example of the problem, see my msbuild-vs-vs2015-toolsversion repository on github.
Some suggestion: I am asking about this because we recently had a CI build error when one of my colleagues presented C # 6.0 code that was compiled with Roslyn on their copy of Visual Studio 2015 but failed in CI because it uses the previous one release of the .net toolchain (they used an automatic property without a setter, which is fine in Roslyn, but not in earlier versions). We will upgrade the CI build to Roslyn, but I wanted to see if we could prevent this from happening in the future.