【问题标题】:How to override compile command of Visual Studio 2017 Community [duplicate]如何覆盖 Visual Studio 2017 社区的编译命令 [重复]
【发布时间】:2018-01-31 18:25:27
【问题描述】:

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

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

我想全局更改它。我该怎么做?

【问题讨论】:

  • 找到 cl.exe 文件,将其替换为您自己的文件,记录参数。可选调用带有参数的原始 cl.exe。
  • 请具体说明。你说你想捕捉论点并创建统计数据。您还说您想用脚本覆盖编译器。这两者并不相互排斥。后者不是第一个问题的唯一解决方案,我怀疑您真的只是想要第一个问题的解决方案?
  • @stijn 我澄清了这个问题。我真的很想覆盖编译。如果我成功了,捕捉论点只是我能做的许多事情之一。
  • @RichardCritten 好吧,这有一些缺陷,尽管它可能是一个好的开始。但是a)visual studio 可能会在更新时覆盖它,b)shell 脚本不能有.exe 扩展名,所以我必须制作简单的C 程序来运行实际的脚本。我特别想使用 Node.js。我的最终目标是在另一台机器上编译文件(为了好玩,不是因为我真的需要)。
  • 啊,你还不知道 MsBuild :] 只是通过谷歌搜索这将是一个艰难的过程,给我一些时间,我会准备一个答案让你开始。

标签: c++ compilation visual-studio-2017 visual-studio-community


【解决方案1】:

对于标准 C++ 项目文件编译是通过调用名为 ClCompile 的 MsBuild Target 完成的。请注意,还有一个名为 ClCompile 的 MsBuild Item 列出了实际使用的 C++ 源文件,这可以通过在文本编辑器中打开 .vcxproj 轻松查看。因此,此 ClCompile 项在 ClCompile 目标中使用,在那里它被传递给 CL Task,后者又将调用 cl.exe,即实际的编译器可执行文件。此代码可以在您使用的工具集的 Microsoft.CppCommon.targets 文件中找到,用于在 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community 的 64 位计算机上默认安装 VS2017 社区\Common7\IDE\VC\VCTargets\Microsoft.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 Studio\2017\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 目录中以进行全局覆盖。

【讨论】:

  • 我是否理解正确,如果我按照您概述的方式覆盖 ClCompile target,我将能够在 Visual Studio 中选择该目标进行构建?无论如何,非常感谢您的帮助,这是进行更多研究的一个很好的起点!
  • 如果您覆盖 ClCompile,它将被自动调用,而不是默认的 ClCompile 目标,例如在 VS 中,您点击构建或编译单个文件。
猜你喜欢
  • 2019-08-25
  • 1970-01-01
  • 2023-04-08
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-03
相关资源
最近更新 更多