Incremental Build of Nuget Packages

爱⌒轻易说出口 提交于 2019-12-25 07:43:41

问题


I want to execute an msbuild project which uses batching to determine that one or more csproj projects have been freshly-built, and therefore require fresh nuget packaging. The script I've made so far seems like a reasonable start, but it the incremental-build mechanism isn't working. The MainBuild target executes every time, no matter what.

Here is what I have:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="MainBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)'=='' ">Debug</Configuration>
    <Content>content\plugins\</Content>
  </PropertyGroup>
  <ItemGroup>
    <Nuspec Include="$(MSBuildProjectDirectory)\plugins\*\*.nuspec" />
  </ItemGroup>

<Target Name="MainBuild"
        Inputs="%(Nuspec.RootDir)%(Nuspec.Directory)bin\$(Configuration)\*.dll"
        Outputs="%(Nuspec.RootDir)%(Nuspec.Directory)%(FileName).pkg" >
  <ItemGroup>
    <Inputs Include="%(Nuspec.RootDir)%(Nuspec.Directory)bin\$(Configuration)\*.dll" />
    <Outputs Include="%(Nuspec.RootDir)%(Nuspec.Directory)%(FileName).pkg" />
  </ItemGroup>
  <Message Text="INPUTS: %(Inputs.FullPath)" />
  <Message Text="OUTPUTS: @(Outputs->'%(FullPath)')" />

  <Copy SourceFiles="@(Inputs)" DestinationFiles="@(Outputs->'%(FullPath)')" />

</Target>
</Project>

The Copy task is just a debugging placeholder for calling-out to nuget and creating a new package.

The idea is that if any files in the bin\Debug directory are newer than the corresponding .nuspec file (found two folders above bin\Debug), then the MainBuild target should execute.

Any ideas?

p.s. The Inputs and Outputs attributes of the Target presumably each create an item. I think it strange that the items created can't be referenced inside the target. In the above example, I had to make a target-interna dynamic ItemGroup to re-create the items, just so that I could access them. Is there a way around that?


回答1:


I read this in the MSBuild Batching documentation

If a task inside of a target uses batching, MSBuild needs to determine if the inputs and outputs for each batch of items is up-to-date. Otherwise, the target is executed every time it is hit.

Which may be the cuprit. Try changing your copy target to use batching instead of an ite transform (I don't think using item metadata in an item group satisfies the above requirement).

<Target Name="MainBuild"
        Inputs="%(Nuspec.RootDir)%(Nuspec.Directory)bin\$(Configuration)\*.dll"
        Outputs="%(Nuspec.RootDir)%(Nuspec.Directory)%(FileName).pkg" >
    <ItemGroup>
        <Inputs Include="%(Nuspec.RootDir)%(Nuspec.Directory)bin\$(Configuration)\*.dll" />
        <Outputs Include="%(Nuspec.RootDir)%(Nuspec.Directory)%(FileName).pkg" />
    </ItemGroup>
    <Message Text="INPUTS: %(Inputs.FullPath)" />
    <Message Text="OUTPUTS: @(Outputs->'%(FullPath)')" />

    <Copy SourceFiles="@(Inputs)" DestinationFiles="%(Outputs.FullPath)" />

</Target>

It looks like the number of inputs may be different than the number of outputs (I suspect there is more than one .dll files in the output directory for each project), which will also cause the target to execute.



来源:https://stackoverflow.com/questions/14130628/incremental-build-of-nuget-packages

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!