如何在Visual Studio中选择C++和C#的编译器版本
MSBuild简介
Visual Studio的编译引擎是MSBuild,它提供了一套项目文件(.csproj
,.vbproj
, vcxproj
)的XML的Schema,用来指定如何处理和编译项目。
当然MSBuild不依赖于Visual Studio,完全可以在不安装Visual Studio的情况下使用MSBuild。比如可以从Microsoft Build Tools 2015下载MSBuild来编译C#。2016年3月31号微软也宣布了Visual C++ Build Tools 2015,可以下载来编译VC++的项目。
MSBuild也是一个MIT License的开源软件,可以在Github上看到它的仓库。
MSBuild Toolset (ToolsVersion)是一个任务、目标和工具的集合,指定MSBuild的行为。通常一个MSBuild的Toolset包含microsoft.common.tasks
文件,microsoft.common.targets
文件和编译器比如csc.exe
,cl.exe
和link.exe
。
在装Visual Studio时会按照对应版本的MSBuild,比如Visual Studio 2015对应的MSBuild就是v14。如果我们用Visual Studio创建C#和C++的项目,在.csproj
和.vcxproj
文件的第一行都指定了对应MSBuild的Toolset,如下所示。
1 | <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
在Visual Studio中编译项目时就会使用v14的MSBuild来编译。
用VS2015的MSBuild来编译VS2015创建的项目
我们也可以直接使用MSBuild来编译,我分别创建了一个空的C#和空的C++的Console应用,然后打开MSBuild Command Prompt for VS2015,用如下命令行来编译
1 | msbuild CompilerDemo.sln /t:rebuild |
可以看到如下的命令行输出:1
2
3
4
5
6
7
8CoreCompile:
C:\Program Files (x86)\MSBuild\14.0\bin\csc.exe ...
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\CL.exe ...
Link:
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\link.exe ...
说明在编译项目时使用了v14的MSBuild下的csc.exe
,cl.exe
和link.exe
。
用VS2013的MSBuild来编译VS2015创建的项目
如果我们打开Developer Command Prompt for VS2013,用VS2013的MSBuild编译项目。
1 | msbuild CompilerDemo.sln /t:rebuild |
得到如下的命令行输出:
1 | CoreCompile: |
我们看到用v12的MSBuild编译C#项目时成功了,但是编译C++项目时失败了,说找不到Platform Toolset = ‘v140’。我们回头打开.vcxproj
文件,可以看到在这个文件里指定了<PlatformToolset>v140</PlatformToolset>
。我们把它改成v120,再重新编译,这次发现成功了。
1 | ClCompile: |
用VS2015的MSBuild来编译VS2015创建的项目(修改C++项目的PlatformToolset)
修改完PlatformToolset
之后,我们再用VS2015的MSBuild编译一下,看看结果。
1 | CoreCompile: |
我们发现它使用了v14的csc.exe
,但是使用了v12的cl.exe
和link
。
用VS2015的MSBuild来编译,但是指定VS2013的C++和C#的编译器
那有没有办法让VS2015的MSBuild也使用v12的C#的编译器(csc.exe
)呢?我们可以参考一下Overriding ToolsVersion Settings。
可以使用MSBuild的命令行参数开关:/ToolsVersion
,简写为/tv
。打开MSBuild Command Prompt for VS2015,用如下命令行来编译。1
msbuild CompilerDemo.sln /t:rebuild /tv:"12.0"
我们得到了如下的命令行输出:1
2
3
4
5
6CoreCompile:
C:\Program Files (x86)\MSBuild\12.0\bin\Csc.exe ...
ClCompile:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\CL.exe ...
Link:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe ...
嗯,我们终于在VS2015的MSBuild命令下,成功的使用了VS2013的C++和C#的编译器。
用Visual Studio 2015来编译,但是指定VS2013的C++和C#的编译器
那么有没有办法来让Visual Studio 2015在编译时也用2013的编译器呢?我们没有办法来指定MSBuild的开关了。根据Overriding ToolsVersion Settings介绍的方法,需要做两件事。
修改项目文件的ToolsVersion
属性
在本文的开头提到了在项目文件的第一行写明了对应MSBuild的Toolset。我们可以修改这个属性,把项目文件的第一行改成:1
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
设置环境变量MSBUILDLEGACYDEFAULTTOOLSVERSION
1 | set MSBUILDLEGACYDEFAULTTOOLSVERSION=true |
这样在Visual Studio 2015中编译也会使用VS2013的编译器了。而且直接在MSBuild Command Prompt for VS2015中直接使用MSBuild,不需要制定/tv
开关,也是使用VS2013的编译器了。
来验证一下,如果我们在代码中使用了C#6的新特性(VS2015支持)。1
2object o = null;
Console.WriteLine(o?.ToString());
那么在Visual Studio 2015中编译会报错。
1 | Build FAILED. |
在Visual Studio 2015中指定C#语言的版本
另外在Visual Studio中可以指定支持的C#语言的版本。右键项目-》属性-》编译-》高级-》语言版本。Visual Studio 2015的默认就是支持的最高版本C# 6.0,可以在这里选择不同的版本。
总结 TLDR
对于C++项目
通过设置PlatformToolset
来指定C++的编译器版本。
对于C#项目
使用相应版本的MSBuild。
或者
使用MSBuild的命令行开关/ToolsVersion
(/tv
)。
或者
1. 修改项目文件的ToolsVersion
属性。
2. 设置环境变量MSBUILDLEGACYDEFAULTTOOLSVERSION
。