使用特定版本的msbuild
I 构建项目或解决方案时,可以使用/toolsversion
或/tv
切换选择较早的.net工具链:
"C:\Program Files (x86)\MSBuild\14.0\bin\msbuild" /tv:12.0 amazing.sln
根据以上内容正确选择适用于所有版本的Just Works msbuild
和版本csc.exe
等:
> "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 ... ...
如果我没有指定/tv
,那么根据我正在使用的msbuild的版本和一些环境变量,我可能得到以下任何一个:
ToolsVersion在项目文件的顶级元素中指定
ToolsVersion对应于msbuild.exe
我正在使用的版本
来自的价值 msbuild.exe.config
注册表中的值
(请参阅 MSDN上的Overriding ToolsVersion Settings页面的不同版本).
因此,为了在构建服务器和本地机器上具有一致结果的构建,我/tv
在运行时使用msbuild.exe
(事实上,这是在psake
脚本中强制执行的,这也确保它使用相应的版本msbuild.exe
).
但是,/tv
在使用Visual Studio构建时,我无法使用该开关.相反,Visual Studio 2013及更高版本将使用该版本的Visual Studio附带的.net工具链,除非:
环境变量MSBUILDLEGACYDEFAULTTOOLSVERSION
已设置并且 ......
...所有项目文件都将ToolsVersion属性设置为我想要使用的版本.
这是如此巴洛克式,我无法相信任何人实际上是这样做的.我的问题是这样的:
是谁在做MSBUILDLEGACYDEFAULTTOOLSVERSION
的事情吗?
如果没有,是否有另一种方法可以使Visual Studio使用特定的ToolsVersion,而不使用随ToolsVersion一起提供的Visual Studio版本?可以存储在版本控制中的东西(所以在项目或其他设置文件中)将是理想的.
最后:
我应该关心吗?鉴于C#编译器的每个连续版本都应该能够处理以前版本的输入,并且我可以在项目文件中设置目标.net框架和C#语言级别,这是否足以确保可重复的构建?
(我的偏见是我应该关心,因为:
我想在IDE和构建服务器上的构建是相同的(当然)
我希望能够使用VS2015(以及未来的版本),因为它比以前的版本更好的IDE,但我不想在我决定之前使用新的工具链.
也许我想要太多......)
有关此问题的具体示例,请参阅github上的msbuild-vs-vs2015-toolsversion存储库.
一些背景:我问这个是因为我们最近有一个CI构建错误,当我的一个同事提交了C#6.0代码,这些代码在他们的Visual Studio 2015副本上与Roslyn编译良好,但在CI中失败,因为它使用了之前的版本.net工具链(他们使用了没有setter的自动属性,这在Roslyn中很好,但在早期版本中没有).我们将更新CI构建到Roslyn,但我想看看我们是否可以阻止将来发生这种事情.
我通过编写Visual Studio扩展来解决这个问题,该扩展MSBUILDDEFAULTTOOLSVERSION
在构建期间临时设置环境变量; 要使用的值是从与文件.toolsversion
相同的目录中的.sln
文件中读取的.psake脚本读取相同的.toolsversion
文件并将值传递给/tv
交换机.
可以在此处找到扩展的代码:https://github.com/guyboltonking/set-toolsversion-extension.可悲的是,我目前没有使用C++,或者确实使用Visual Studio,所以我无法为它提供任何支持(但我可以告诉你,我几个月没有任何问题地使用它).
感谢@efaruk提醒我存在的问题MSBUILDDEFAULTTOOLSVERSION
.
编辑:感谢@ mbadawi23,现在可以使用VS2015和VS2017的扩展.