Visual Studio如何确定是否必须启动MSBuild?

问题描述 投票:2回答:2

我以前为我的C ++项目做了很多MSBuild定制。 MSBuild目标的Input和Output属性用于确定是否必须执行目标。此外,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#项目中有类似的东西吗?

非常感谢!

c# visual-studio msbuild
2个回答
0
投票

答案可能是否定的,与tlog机制没什么相似之处。我不是百分百肯定,也是因为奇怪的是你不能做一些非常基本的事情,因为这意味着MS基本上抛弃了C#(和类似的)项目的跟踪器东西,但没有用可以挂钩的东西替换它由用户。

使用procmon你可以看到VS获取输出和输入文件的时间戳,但是我找不到一种方法来干扰它作为输入和输出文件的处理方式。看起来VS看起来直接包含在项目文件中的所有内容列表(即VS中显示的Reference / Content / Compile / ..项目组),而不是Taget的输入/输出中列出的内容,并且在开始时构建比较那些项目的timstamps。如果所有内容(以及考虑到VS的所有内容)都是最新的,则不会为构建启动msbuild进程。

有一个解决方法,虽然不是很好:如果你添加一个'虚拟'内容项(例如右键单击项目 - >添加新项目 - >文本文件)并将其设置为始终被复制(刚刚添加的右clik文本文件) - >属性 - >复制到输出目录 - >始终复制)然后VS将始终启动构建,因此检查目标的输入与输出,如果删除了FileRenamed.dat则运行。


0
投票

看起来这个文档很难记录。 This site显示您可以轻松地连接命令行工具,同时提升tlog文件的增量功能。

为了确保信息不会丢失,我只是复制他们的用例,但看着它,我认为很容易转化为您的需求。每次出现的dcx都可以被替换为例如data

1. Create a definition .xml file

  • 定义一个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>

2. Create a .targets file

  • 包括.xml定义文件
  • 创建一个依赖于你的一个构建钩子的Target(这里:ClCompile
  • 在你的目标中创建一个ItemGroup,它将作为你的CustomBuild的参数。 MessageCommandAdditionalInputsOutput是相关的元属性。
  • CustomBuildMinimalRebuildFromTracking="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>
© www.soinside.com 2019 - 2024. All rights reserved.