Инкрементная сборка в .NET Core & Visual Studio - PullRequest
0 голосов
/ 22 февраля 2019

Этот игрушечный проект не имеет работающей инкрементной сборки:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <Timestamp>$([System.DateTime]::Now.ToString("yyyy-MM-dd\THHmmss"))</Timestamp>
  </PropertyGroup>

  <ItemGroup>
    <MyInputs Include="myinput.txt" />
    <MyOutput Include="myoutput.txt" />
  </ItemGroup>

  <Target
    Name="test_BeforeTargets_BeforeBuild"
    BeforeTargets="BeforeBuild"
    Inputs="@(MyInputs)"
    Outputs="@(MyOutput)"
  >
    <Message Text="test_BeforeTargets_BeforeBuild" Importance="high" />
    <WriteLinestoFile File="myoutput.txt" Lines="$(Timestamp)" Overwrite="true" />
  </Target>
</Project>

В Visual Studio я заметил 3 результата сборки:

  1. Когдаmyinput.txt и .csproj файлы изменены, я получаю желаемый результат:

    1>Target "test_BeforeTargets_BeforeBuild" in file "C:\Users\dan\source\repos\TestMSBuild\TestMSBuild.csproj":
    1>  Building target "test_BeforeTargets_BeforeBuild" completely.
    1>  Input file "myinput.txt" is newer than output file "myoutput.txt".
    1>  Task "Message"
    1>    Task Parameter:Text=test_BeforeTargets_BeforeBuild
    1>    Task Parameter:Importance=high
    1>    test_BeforeTargets_BeforeBuild
    1>  Done executing task "Message".
    1>  Task "WriteLinestoFile"
    1>    Task Parameter:File=myoutput.txt
    1>    Task Parameter:Lines=2019-02-21T163909
    1>    Task Parameter:Overwrite=True
    1>  Done executing task "WriteLinestoFile".
    1>Done building target "test_BeforeTargets_BeforeBuild" in project "TestMSBuild.csproj".
    
  2. Когда myinput.txt не изменен, но .csproj есть.Я получаю ожидаемое пропускание цели:

    1>Target "test_BeforeTargets_BeforeBuild" in file "C:\Users\dan\source\repos\TestMSBuild\TestMSBuild.csproj":
    1>  Skipping target "test_BeforeTargets_BeforeBuild" because all output files are up-to-date with respect to the input files.
    1>  Input files: myinput.txt
    1>  Output files: myoutput.txt
    1>Done building target "test_BeforeTargets_BeforeBuild" in project "TestMSBuild.csproj".
    
  3. Если я строю дважды, ничего не изменяя, то изменяю только myinput.txt, я получаю вывод в одну строку, независимо от того, какЯ много раз пытался построить:

    ========== Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped ==========
    

Я ожидал, что когда я изменю только myinput.txt, цель не будет пропущена.В настоящее время это верно только в том случае, если я одновременно изменю файл .csproj.

Были испробованы следующие варианты BeforeTargets & AfterTargets, но безрезультатно:

BeforeTargets="BeforeBuild" (as above)
BeforeTargets="Build"
AfterTargets="BeforeBuild"
AfterTargets="Build"

Iпробовал только проекты .NET-Core (Microsoft.NET.Sdk) и ASP.NET-Core (Microsoft.NET.Sdk.Razor & Microsoft.NET.Sdk.Web), но оба имеют одинаковый результат.

Вопрос:

Как я могу заставить этот игрушечный проект работать?

1 Ответ

0 голосов
/ 22 февраля 2019

Несмотря на то, что актуальная проверка на основе MSBuild работает должным образом, существует также дополнительная актуальная проверка, выполняемая Visual Studio, чтобы определить, должен ли он вызывать MSBuild или нет.Поскольку он не знает о вашем входном файле, он определяет, что нет необходимости запускать MSBuild для этого проекта.

Это можно изменить, сообщив об этом VS, используя элементы UpToDateCheckInput и UpToDateCheckOutputчто система проекта использует для этой проверки:

<ItemGroup>
  <UpToDateCheckInput Include="@(MyInputs)" />
  <UpToDateCheckOutput Include="@(MyOutputs)" />
</ItemGroup>
...