我过去为C ++项目做过很多MSBuild定制。 MSBuild目标的输入和输出属性用于确定是否必须执行目标。此外,Visual Studio使用.tlog文件(位于中间目录中)来确定是否必须调用MSBuild。
现在我正在开发一个C#项目。我写了一个简单的MSBuild目标,它将文件复制到输出目录:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="CopyMyFile" BeforeTargets="AfterBuild" Inputs="$(ProjectDir)File.dat" Outputs="$(TargetDir)FileRenamed.dat">
<Copy SourceFiles="$(ProjectDir)File.dat" DestinationFiles="$(TargetDir)FileRenamed.dat" OverwriteReadOnlyFiles="true">
</Copy>
</Target>
</Project>
如果通过MSBuild.exe调用构建,目标将按预期工作。如果目标文件不存在或源文件已被修改,则复制该文件。
如果我在Visual Studio中调用构建,它将无法按预期工作。如果从输出目录中删除该文件,Visual Studio不会调用MSBuild。另一方面,即使没有进行其他更改,每次在修改源文件后构建项目时都会调用MSBuild。
Visual Studio似乎只是将项目中的每个文件与输出文件(.exe,.dll或.pdb)进行比较。如果项目中的任何文件比输出文件新,则调用MSBuild。在我的情况下,MSBuild不会更新.exe文件,因此会一次又一次地调用MSBuild。
在C ++项目中,此行为由.tlog文件控制。 C#项目中有类似的内容吗?
非常感谢!
答案 0 :(得分:0)
答案可能是 no,与tlog机制没什么相似之处。我不是百分百肯定,也是因为奇怪的是你不能做一些非常基本的事情,因为这意味着MS基本上抛弃了C#(和类似的)项目的跟踪器东西,但没有用可以挂钩的东西替换它用户。
使用procmon你可以看到VS获取输出和输入文件的时间戳,但是我找不到干扰它作为输入和输出文件处理的内容的方法。看起来VS看起来直接包含在项目文件中的所有内容列表(即VS中显示的Reference / Content / Compile / ..项目组),而不是Taget的输入/输出中列出的内容,并且在开始时构建比较那些项目的timstamps。如果所有内容(好的,考虑到VS的所有内容)都是最新的,则不会为构建启动msbuild进程。
有一种解决方法,虽然不是很好:如果你添加一个'虚拟'内容项(例如右击项目 - >添加新项目 - >文本文件)并将其设置为始终被复制(右 - clik文本文件刚添加 - &gt;属性 - &gt;复制到输出目录 - &gt;总是复制)然后VS将始终启动构建,因此检查目标的输入与输出并运行,如果你删除了FileRenamed.dat。
答案 1 :(得分:0)
看来这是文献记载很少。 This site显示您可以轻松地连接命令行工具,同时利用tlog文件的增量功能。
为确保信息不会丢失,我将仅复制他们的用例,但是考虑到这一点,我认为很容易转变为您的需求。每次dcx
都可以用例如data
.xml
文件ItemType
ContentType
链接到ItemType
FileExtension
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">
<!-- Associate DXCShader item type with .hlsl files -->
<ItemType Name="DXCShader" DisplayName="DXC Shader" />
<ContentType Name="DXCShader" ItemType="DXCShader" DisplayName="DXC Shader" />
<FileExtension Name=".hlsl" ContentType="DXCShader" />
</ProjectSchemaDefinitions>
.targets
文件.xml
定义文件Target
(此处为ClCompile
)ItemGroup
,将其用作CustomBuild
的参数。 Message
,Command
,AdditionalInputs
和Output
是相关的元属性。CustomBuild
和MinimalRebuildFromTracking="true"
调用TrackerLogDirectory
以包含tlog
文件。 这部分是神奇的成分,如果您的依赖项是最新的,则使MSBuild跳过构建。<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<!-- Include definitions from dxc.xml, which defines the DXCShader item. -->
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)dxc.xml" />
<!-- Hook up DXCShader items to be built by the DXC target. -->
<AvailableItemName Include="DXCShader">
<Targets>DXC</Targets>
</AvailableItemName>
</ItemGroup>
<Target
Name="DXC"
Condition="'@(DXCShader)' != ''"
BeforeTargets="ClCompile">
<Message Importance="High" Text="Building shaders!!!" />
<!-- Find all shader headers (.hlsli files) -->
<ItemGroup>
<ShaderHeader Include="*.hlsli" />
</ItemGroup>
<PropertyGroup>
<ShaderHeaders>@(ShaderHeader)</ShaderHeaders>
</PropertyGroup>
<!-- Setup metadata for custom build tool -->
<ItemGroup>
<DXCShader>
<Message>%(Filename)%(Extension)</Message>
<Command>
"$(WDKBinRoot)\x86\dxc.exe" -T vs_6_0 -E vs_main %(Identity) -Fh %(Filename).vs.h -Vn %(Filename)_vs
"$(WDKBinRoot)\x86\dxc.exe" -T ps_6_0 -E ps_main %(Identity) -Fh %(Filename).ps.h -Vn %(Filename)_ps
</Command>
<AdditionalInputs>$(ShaderHeaders)</AdditionalInputs>
<Outputs>%(Filename).vs.h;%(Filename).ps.h</Outputs>
</DXCShader>
</ItemGroup>
<!-- Compile by forwarding to the Custom Build Tool infrastructure,
so it will take care of .tlogs and error/warning parsing -->
<CustomBuild
Sources="@(DXCShader)"
MinimalRebuildFromTracking="true"
TrackerLogDirectory="$(TLogLocation)"
ErrorListRegex="(?'FILENAME'.+):(?'LINE'\d+):(?'COLUMN'\d+): (?'CATEGORY'error|warning): (?'TEXT'.*)" />
</Target>
</Project>