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

查看:131
本文介绍了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会重新评估targt,并发现缺少输出文件,从而导致使用我的目标对其进行重新构建.

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文件以查明项目的输出文件是什么.可能还有更多内容,如果您在Internet上四处逛逛,则可能会获得更多有关此信息.

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>

手动或通过项目的属性页进行 Custom Build Step (自定义构建步骤),您会看到行为恰好是您所需要的:如果删除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)\ MSBuild \ Microsoft.Cpp \ v4.0 \ V120 (调整所用平台/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)\MSBuild\Microsoft.Cpp\v4.0\V120 (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. In my experience the line starting with ^ is just a comment - I don't use it myself and my custom targets work ok and the same is said here.

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天全站免登陆