Visual Studio 如何知道我的项目是最新的,因此它可以跳过运行 MSBuild? [英] How does Visual Studio know my project is up to date so it can skip running MSBuild?

查看:19
本文介绍了Visual Studio 如何知道我的项目是最新的,因此它可以跳过运行 MSBuild?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 C++ 项目中包含一个自定义 MSBuild 目标,它在 $(OutDir) 文件夹中为给定项目类型的每个项目生成一个数据文件.我将项目类型与属性页架构挂钩,因此您可以在解决方案资源管理器中的文件上选择它,并且我的目标声明输入和输出,以便增量构建工作.我还将我的目标添加到 $(BuildDependsOn) 属性中,以便在构建目标 Visual Studio 调用期间自动评估它.

I have a custom MSBuild target included in my C++ project that produces a data file in the $(OutDir) folder for each item of a given item type. I have the item type hooked up with a property page schema so you can select it on files in the solution explorer and my target declares input and outputs so incremental builds work. I have also added my target to the $(BuildDependsOn) property so it is automatically evaluated during the Build target Visual Studio invokes.

似乎一切正常,除了一件事:如果我删除了 $(OutDir) 中的一个输出数据文件,然后构建 Visual Studio 什么都不做,并说我的项目是最新的.如果我删除项目生成的 exe 文件或触摸其中一个 MSBuild 脚本的修改时间,Visual Studio 会重新评估目标并发现输出文件丢失,导致使用我的目标重新构建它.

Everything seems to work except for one thing: If I delete one of my output data files in the $(OutDir) and then build Visual Studio does nothing and says my project is up to date. If I delete the exe file the project produces or touch the modified time of one of the MSBuild scripts Visual Studio re-evaluates the targts and finds the output file is missing, causing it to be re-built using my target.

从 MSBuild 诊断日志来看,Visual Studio 似乎在内部维护一些输出文件和输入文件的列表,它会检查这些文件以避免评估 MSBuild 脚本.如何将我的输出文件添加到此列表中?

From the MSBuild diagnostic logging it seems like Visual Studio is internally maintaining some list of output files and input files that it checks to avoid evaluating the MSBuild script at all. How do I add my output files to this list?

推荐答案

MsBuild/VS 确实有一个机制来确定输入文件是最新的,它围绕一个可执行的 tracker.exe 扫描.tlog 文件来确定项目的输出文件是什么.可能还有更多内容,如果您在互联网上四处查看,您可能会获得更多相关信息.

MsBuild/VS indeed have a mechanism to determine what is up-to-date with respect to the input files, it revolves around an executable tracker.exe which scans .tlog files to figure out what a project's output files are. There might be more to it, and if you look around on the internet you can probably get more info about this.

但问题是您实际上并不需要了解它的每一个细节:您可以在检查内置 CustomBuildStep 的工作原理时找到一个简单的使用示例并将其应用于你的情况.我将简要解释我是如何做到这一点的,因为我认为它可能对您处理此类 msbuild 问题也很有用.

But the thing is you don't really need to understand every single detail of it: you can find a simple usage example for it when inspecting how the built-in CustomBuildStep works and apply that to your case. I'll briefly explain how I got to this because I think it might be useful for you as well in dealing with msbuild questions like these.

如果你添加

<ItemDefinitionGroup>
  <CustomBuildStep>
    <Command>echo foo &gt; $(OutDir)foo.txt</Command>
    <Outputs>$(OutDir)foo.txt</Outputs>
  </CustomBuildStep>
</ItemDefinitionGroup>

手动或通过自定义构建步骤的项目属性页,您将看到行为正是您所需要的:如果删除 foo.txt,构建将开始,而构建被标记如果不是最新的(好吧,并且当其余的输出也是最新的).

either manually or via the project's property pages for Custom Build Step you'll see the beahviour is eactly what you need: if foo.txt is deleted a build will start, while a build is marked up-to-date if it is not (well, and when the rest of the outputs are also up-to-date).

因此,关键是做 CustomBuildStep 在后台所做的事情,而弄清楚这一点只是使用您选择的工具在 下的所有文件中搜索所有出现的 CustomBuildStep 的问题C:Program Files (x86)MSBuildMicrosoft.Cppv4.0V120(根据使用的平台/VS 版本调整路径).

Hence the key is to do what CustomBuildStep does under the hood, and figuring that out is just a matter of using your tool of choice to search all occurrences of CustomBuildStep in all files under C:Program Files (x86)MSBuildMicrosoft.Cppv4.0V120 (adjust path for platform/VS version used).

这将我们带到 Microsoft.CppCommon.Targets,其中名为 CustomBuildStep 的目标(请注意,这与上面 ItemDefinitionGroup 中的条目名称相同)调用实际CustomBuildStep 命令.它还有一个特别有趣的地方:

This leads us to Microsoft.CppCommon.Targets where the target named CustomBuildStep (mind you, that's the same name as the entry in the ItemDefinitionGroup above) invokes the actual CustomBuildStep command. It also has this particularily interesting bit:

<!-- Appended tlog to track custom build events -->
<WriteLinesToFile Encoding="Unicode"
  File="$(TLogLocation)$(ProjectName).write.1u.tlog"
  Lines="@(CustomBuildStep->'^%(Identity)');@(CustomBuildStep->MetaData('Outputs')->FullPath()->Distinct())"/>

因此,这会将输出的路径写入跟踪器使用的目录中的 .tlog 文件,并使其按需要工作.另请参阅此处了解有关格式的更多信息.

So this writes the path of the Outputs to a .tlog file in the directory used by the tracker and makes it work as desired. Also see here for more information about the format.

tl;dr 使用 WriteLinesToFile 将目标输出的完整路径附加到 $(TLogLocation)$(ProjectName).write.1u.tlog 之类的文件中.我说 like 因为 write.tlog、write.u.tlog 等也可以.

tl;dr Use WriteLinesToFile to append full paths of your targets' outputs to a file like $(TLogLocation)$(ProjectName).write.1u.tlog. I'm saying like because write.tlog, write.u.tlog etc also work.

这篇关于Visual Studio 如何知道我的项目是最新的,因此它可以跳过运行 MSBuild?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆