简体   繁体   中英

MSBuild Target Detecting skipped build

When MS build builds a solution, it will skip projects that are up to date. Is there a way to detect this in the subsequent targets to avoid doing additional unnecessary work?

The case example is one of my projects is creating a NuGet package after the build process targeting an AfterBuild target. If the build is skipped then we can conclude that Nuget package doesn't need to be replaced.

I've tried AfterBuild and CoreCompile

 <Target Name="DebugProps" AfterTargets="CoreCompile">
        <Message Importance="high" Text="Current Saved Properties are:"/>

Logfile output:

 CoreCompile:
       Skipping target "CoreCompile" because all output files are up-to-date with respect to the input files.
       DebugProps:
         Current Saved Properties are:

I think you could use Inputs and outputs on msbuild.

Try this:

  <Target Name="test123" BeforeTargets="CoreCompile">
        <ItemGroup>
            <File Include="$(TargetPath)"></File>
        </ItemGroup>
        <Copy SourceFiles="@(File)" DestinationFolder="$(SolutionDir)"></Copy>
        <Message Importance="high" Text="$(TargetName)"></Message>
  </Target>

  <Target Name="DebugProps" AfterTargets="Build" Inputs="$(TargetPath)" Outputs="$(SolutionDir)$(TargetFileName)">
        <Message Importance="high" Text="Current Saved Properties are:"/>
        
  </Target>

I found the most effective way to solve this problem, is set assign a special property called TargetsTriggeredByCompilation to a desired target that you want to call after core compile is complete.

Core compile is skipped with incremental builds, with that I've set separate property SkipPostBuildActions to true at the start of the build. This is then further used as condition in any targets which I want to be conditional on core compile.

Once core compile is complete, it will trigger my EnablePostBuild target, this target intern sets SkipPostBuildActions to false . This then enables subsequent build targets.

<!-- Defines Targets that should be run after Compile, but skipped if Compile doesn't take place -->
<PropertyGroup>
    <TargetsTriggeredByCompilation>
        $(TargetsTriggeredByCompilation);
        EnablePostBuild
    </TargetsTriggeredByCompilation>
</PropertyGroup>
<Target Name="EnablePostBuild">
    <!-- Disable post build actions  -->
    <PropertyGroup>
        <SkipPostBuildActions>false</SkipPostBuildActions>
    </PropertyGroup>
</Target>

An example of '$(SkipPostBuildActions)' == 'false' used on a NugetProject target:

    <!-- Creating Nuget Packages -->
    <Target Name="NugetProject" AfterTargets="PostBuild" Condition="'$(NugetProject)' == 'true' And '$(SkipPostBuildActions)' == 'false'" DependsOnTargets="GetVersion">

        <!-- Manages getting the assembly version for output folders -->
        <Message Importance="High" Text="Current Assembly Version  $(GitVersion_NuGetVersion)"/>

        <!-- Note the Exec Task needs to provide a path relative to current Project that is building -->
        <Exec Command="$(ToolsPath)NuGet.exe pack  -Version $(VersionStamp) -Symbols -SymbolPackageFormat snupkg -IncludeReferencedProjects -OutputDirectory $(LocalMachineNugetPath) -Verbosity detailed -Properties Configuration=$(Configuration)"/>
    </Target>

TargetsTriggeredByCompilation is triggered with a call target deep in the internals of the Targets graph that is pulled in with default build.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM