Luc*_*cas 5 msbuild visual-studio visual-studio-2015
我有一个自定义的MSBuild目标包含在我的C++项目中,它在$(OutDir)文件夹中为给定项类型的每个项生成一个数据文件.我有一个项目类型与一个属性页面模式连接,所以你可以在解决方案资源管理器中的文件上选择它,我的目标声明输入和输出,所以增量构建工作.我还将目标添加到$(BuildDependsOn)属性中,因此在构建目标Visual Studio调用期间会自动评估它.
除了一件事,一切似乎都有效:如果我删除$(OutDir)中的一个输出数据文件,然后构建Visual Studio什么都不做,并说我的项目是最新的.如果我删除项目生成或触摸其中一个MSBuild脚本的修改时间的exe文件,Visual Studio将重新评估该targ并发现输出文件丢失,导致使用我的目标重建它.
从MSBuild诊断日志记录看起来,Visual Studio在内部维护一些输出文件和输入文件列表,它会检查以避免评估MSBuild脚本.如何将输出文件添加到此列表中?
MsBuild/VS确实有一种机制来确定输入文件的最新信息,它围绕一个可执行的tracker.exe,它扫描.tlog文件以找出项目的输出文件是什么.可能还有更多,如果你环顾四周,你可能会得到更多关于此的信息.
但问题是你真的不需要了解它的每一个细节:在检查内置的CustomBuildStep如何工作并将其应用于你的案例时,你可以找到一个简单的用法示例.我将简要解释一下我是如何做到这一点的,因为我认为它对你和处理像这样的msbuild问题一样有用.
如果你添加
<ItemDefinitionGroup>
<CustomBuildStep>
<Command>echo foo > $(OutDir)\foo.txt</Command>
<Outputs>$(OutDir)\foo.txt</Outputs>
</CustomBuildStep>
</ItemDefinitionGroup>
Run Code Online (Sandbox Code Playgroud)
无论是手动还是通过项目的自定义构建步骤的属性页面,您都会看到beahviour正是您所需要的:如果删除了foo.txt,则构建将开始,而构建将被标记为最新(如果不是)(好吧,当其余的输出也是最新的时候).
因此,关键是要完成CustomBuildStep的工作,并确定这只是使用您选择的工具在C:\ Program Files(x86)\ MSBuild\Microsoft下的所有文件中搜索所有出现的CustomBuildStep的问题. Cpp\v4.0\V120(调整所用平台/ VS版本的路径).
这将我们引向Microsoft.CppCommon.Targets,其中命名的目标CustomBuildStep(请注意,与上面ItemDefinitionGroup中的条目名称相同)调用实际的CustomBuildStep命令.它也有这个特别有趣的一点:
<!-- Appended tlog to track custom build events -->
<WriteLinesToFile Encoding="Unicode"
File="$(TLogLocation)$(ProjectName).write.1u.tlog"
Lines="@(CustomBuildStep->'^%(Identity)');@(CustomBuildStep->MetaData('Outputs')->FullPath()->Distinct())"/>
Run Code Online (Sandbox Code Playgroud)
因此,这会将输出的路径写入跟踪器使用的目录中的.tlog文件,并使其按预期工作.根据我的经验,开头的行^只是一个注释 - 我不自己使用它,我的自定义目标工作正常,这里说的相同.
tl; dr使用WriteLinesToFile将目标输出的完整路径追加到$(TLogLocation)$(ProjectName).write.1u.tlog等文件中.我说是因为write.tlog,write.u.tlog等也有效.
小智 6
Visual Studio 使用称为 Visual Studio 通用项目系统 (CPS) ( https://github.com/Microsoft/VSProjectSystem ) (VS 2017) 的东西来管理项目,包括构建过程。
在 CPS 中,任何实现 IBuildUpToDateCheckProvider 接口的东西都可以用作项目的“UpToDateChecker”。在调用 MsBuild 之前调用“UpToDateChecker”。它的主要目的是确定是否调用 MsBuild 来构建项目,或者将项目标记为“最新”并一直跳过 msbuild。
这个“UpToDateChecker”正是打印到诊断构建输出中的内容:
1>------最新检查:项目:“ProjectName”,配置:调试x86------项目不是最新的:构建输入'header.h'被修改后构建输出'a.out'。输入时间:12/27/2018 4:43:08 PM,输出时间:1/1/0001 2:00:00 AM
至于 C++ 项目,对于 VS 2017,其默认的“UpToDateChecker”是 VCProjectBuildUpToDateCheck ( Microsoft.VisualStudio.Project.VisualC.VCProjectEngine.dll )。首先,它会查看 tlogs 目录(通常类似于 Debug\x86\.tlog)中的这些文件:
实际上还有更多的检查,但是在检查这 4 种类型时大多数都失败了
| 归档时间: |
|
| 查看次数: |
1754 次 |
| 最近记录: |