如何覆盖 Visual Studio 2017 Community 的编译命令

How to override compile command of Visual Studio 2017 Community

我想用一个简单的 shell 脚本覆盖默认的 Visual Studio C++ 编译器。我想要的是捕获参数,例如文件名,并创建一些统计信息。但是我想完全覆盖编译过程——也就是说,我想从我的 shell 脚本中调用原始编译。

我用谷歌搜索,但我发现的只是如何在项目中执行预构建和 post-构建脚本。这不是我想要的。

我想在全球范围内更改此设置。我该怎么做?

对于标准 C++ 项目文件编译是通过调用 MsBuild Target named ClCompile. Note there's also an MsBuild Item named ClCompile which lists the actual C++ source files used, this can be readily seen by opening your .vcxproj in a text editor. Consequently this ClCompile Item is used in the ClCompile Target, where it gets passed to the CL Task 完成的,后者又将调用 cl.exe,实际的编译器可执行文件。此代码可以在您使用的工具集的 Microsoft.CppCommon.targets 文件中找到,对于在 C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\VC\VCTargets\Microsoft 的 64 位计算机上默认安装的 VS2017 社区.CppCommon.targets.

这 3 个中的任何一个都可以用自定义版本覆盖,但是正如您认为已经只是替换磁盘上的 cl.exe 并不是最好的主意。

但是 CL 可以简单地通过覆盖 CLToolExe 和 CLToolPath properties 来使用任何可执行文件。实际上:打开您的 .vcxproj 文件并添加

<PropertyGroup>
  <CLToolExe>mycl.exe</CLToolExe>
  <CLToolPath>c:\path\to\mycompilerstub\</CLToolPath>
</PropertyGroup>

一直到最后,在导入 Microsoft.Cpp.targets 行之后;将调用 mycl.exe 而不是 cl.exe。如果您希望在您的计算机上全局获得相同的效果,您可以将该 PropertyGroup 放在一个单独的 msbuild 文件中,并将其保存在例如 C:\Program Files (x86)\Microsoft Visual Studio17\Community\Common7\IDE\VC\VCTargets\Platforms\x64\ImportAfter\MyCustomImport.targets 中。该目录中的任何目标文件都将自动导入。

作为替代方案,您可以覆盖 ClCompile 目标或 CL 任务。不过,这涉及更多,例如对于 ClCompile,您首先要复制 Microsoft.CppCommon.targets 中的整个实现,然后添加您需要的任何逻辑。优点是您可以直接访问例如源文件等,而无需解析命令行。例如,这将覆盖 ClCompile 并打印源文件并将它们传递给自定义可执行文件:

<Target Name="ClCompile"
        Condition="'@(ClCompile)' != ''"
        DependsOnTargets="SelectClCompile">

  <Message Text="All the sources = @(ClCompile)"/>
  <Exec Command="mycustom.exe @(ClCompile)" />

  ... <!--rest of implementation copied from Microsoft.CppCommon.targets goes here-->
</Target>

同样,这需要放在项目文件的末尾或 ImportAfter 目录中以进行全局覆盖。