Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid that Visual Studio incremental build does not run when files outside <Compile> and <EmbeddedResource> are changed?

I have a VS2017 csharp project and the .csproj file looks like the following:

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

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.0</TargetFramework>
    </PropertyGroup>
  
    <ItemGroup>
        <MyItem Include="file.dat" />
    </ItemGroup>

    <PropertyGroup>
        <PrepareResourcesDependsOn>
            $(PrepareResourcesDependsOn);
            MyCompileTarget
         </PrepareResourcesDependsOn>
        <CoreCompileDependsOn>
            $(CoreCompileDependsOn);
            MyCompileTarget
        </CoreCompileDependsOn>
    </PropertyGroup>

    <Target Name="MyCompileTarget" Inputs="@(MyItem)" Outputs="@(MyItem->'%(FileName).out')">
    ...
    </Target>
 </Project>

Where MyCompileTarget is a target that generates the file.out from file.dat (in the actual code the incremental build target and properties are in a target file automatically included via a NuGet package).

The issue is that if I change file.dat and press on Build, no target is executed at all, (but MyTarget is correctly executed with Rebuild or when running with msbuild). I would expect the MyCompileTarget to be executed so that the file.out file is updated.

The same issue occurs if I use BeforeBuild or AfterBuild instead of PrepareResourcesDependsOn etc.

It seems that Visual Studio incremental build won't start unless some file in @(Compile) or @(EmbeddedResource) is changed. Indeed, if I add the following

<EmbeddedResource>file.dat</EmbeddedResource>

the incremental build works as expected (but clearly I do not want to embeed the file.dat into the generated assembly).

Is it possible to force Visual Studio to enable incremental build if file.dat is modified, and if the corresponding generated file is older than file.dat or it does not exist?

Note: the same issue occurs using VS2015, with .NET CORE or .NET FRAMEWORK. Also, incremental build will be triggered if I change a csharp file, and it will therefore trigger MyTask, but only if file.dat is newer than the generated file (as expected).

Thanks in advance, Fabio.

like image 619
Fabio Strocco Avatar asked Apr 25 '18 15:04

Fabio Strocco


People also ask

How does incremental builds work?

The incremental build model is a method of software development where the product is designed, implemented and tested incrementally (a little more is added each time) until the product is finished. It involves both development and maintenance.

What is target file in Visual Studio?

targets files that contain items, properties, targets, and tasks for common scenarios. These files are automatically imported into most Visual Studio project files to simplify maintenance and readability. Projects typically import one or more . targets files to define their build process.

What is target in MSBuild?

A target element can have both Inputs and Outputs attributes, indicating what items the target expects as input, and what items it produces as output. If all output items are up-to-date, MSBuild skips the target, which significantly improves the build speed. This is called an incremental build of the target.

What is incremental build in Jenkins?

For a large Maven project, you can tell Jenkins to do incremental builds. In this mode, Jenkins will only build those modules that are affected by new commits. For example, if someone makes a change to moduleA/src/main/java/Foo.


1 Answers

Is it possible to force Visual Studio to enable incremental build if file.dat is modified

You can set the property DisableFastUpToDateCheck to true in the project file to disable FastUpToDateCheck for Visual Studio build manager:

<PropertyGroup>
    <DisableFastUpToDateCheck>True</DisableFastUpToDateCheck>
</PropertyGroup>

Check MSDN about DisableFastUpToDateCheck:

A boolean value that applies to Visual Studio only. The Visual Studio build manager uses a process called FastUpToDateCheck to determine whether a project must be rebuilt to be up to date. This process is faster than using MSBuild to determine this. Setting the DisableFastUpToDateCheck property to true lets you bypass the Visual Studio build manager and force it to use MSBuild to determine whether the project is up to date

Update:

Also, we can set the UpToDateCheckInput to the item:

<UpToDateCheckInput Include="file.dat" />
like image 120
Leo Liu-MSFT Avatar answered Nov 10 '22 14:11

Leo Liu-MSFT