msbuild icon indicating copy to clipboard operation
msbuild copied to clipboard

Unexpected duplicate items

Open JVimes opened this issue 3 years ago • 4 comments

Issue Description

In the Dependency target below, OutFiles is what I expect. But its content is duplicated when accessed in the Primary target.

The issue goes away if I remove the Input and Output attributes.

Issue.targets:

<Project DefaultTargets="Primary">

    <ItemGroup>
        <InFiles Include="A.in;B.in" />
    </ItemGroup>

    <Target Name="Primary"
            DependsOnTargets="Dependency">
        <Message Text="In Primary target.    OutFiles: @(OutFiles)" Importance="high" />
    </Target>

    <Target Name="Dependency"
            Inputs="@(InFiles)"
            Outputs="@(InFiles->'%(filename).out')">
        <ItemGroup>
            <OutFiles Include="*.out" />
        </ItemGroup>
        <Message Text="In Dependency target. OutFiles: @(OutFiles)" Importance="high" />
    </Target>

</Project>

Output:

PS> dotnet build Issue.targets --nologo

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

Steps to Reproduce

Here's a working example, since it may depend on file time stamps:
MSBuildIssue.zip

Unzip and run dotnet build Issue.targets.

Expected Behavior

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out

Actual Behavior

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

Versions & Configurations

msbuild.exe

  • Microsoft (R) Build Engine version 17.3.0-preview-22277-01+f1dae6ab6 for .NET Framework
    17.3.0.27701

dotnet.exe

  • 6.0.400-preview.22301.10

JVimes avatar Jun 17 '22 22:06 JVimes

Team triage: this is a super weird bug with a great repro, thank you!

It looks like you can work around by specifying

Outputs="@(InFiles->'%(Directory)%(FileName).out')"

but we're not totally sure why yet.

We initially thought that something was erroneously causing MSBuild to interpret the item transform expression in your Outputs as a batch operation, so the entire target was running for each InFiles item. But that's not the case; the list is only ever doubled, even when there are more InFiles items, and we don't see the log message from inside Dependency more than once.

rainersigwald avatar Jun 23 '22 16:06 rainersigwald

Try

<OutFiles Include="@(InFiles->'%(FileName).out')" />

We can rule out globbing if this also produces similar output!

~~Also, I only have v17.2.5 and this doesn't happen on that version so something must have changed in-between!~~

Nirmal4G avatar Jun 29 '22 14:06 Nirmal4G

Also, I only have v17.2.5 and this doesn't happen on that version so something must have changed in-between!

I repro on 17.2:

❯ msbuild .\Issue.targets -v:m
Microsoft (R) Build Engine version 17.2.1+52cd2da31 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

And older:

❯ msbuild Issue.targets -v:m
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

Edit: and even older:

> C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe Issue.targets -v:m
Microsoft (R) Build Engine version 4.8.4161.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

rainersigwald avatar Jun 29 '22 14:06 rainersigwald

With <OutFiles Include="@(InFiles->'%(FileName).out')" />, it produces

❯ msbuild Issue.targets -v:m
Microsoft (R) Build Engine version 4.8.9032.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: B.out
  In Primary target.    OutFiles: A.out;B.out

Is this expected output?


By directly specifying the file, it also duplicates the items:

❯ msbuild Issue.targets -v:m
Microsoft (R) Build Engine version 4.8.9032.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: A.out;B.out
  In Primary target.    OutFiles: A.out;B.out;A.out;B.out

When I included the extra item, as expected with your repro, it also duplicates further.

❯ msbuild Issue.targets -v:m
Microsoft (R) Build Engine version 4.8.9032.0
[Microsoft .NET Framework, version 4.0.30319.42000]
Copyright (C) Microsoft Corporation. All rights reserved.

  In Dependency target. OutFiles: A.out;B.out;A.out
  In Primary target.    OutFiles: A.out;B.out;A.out;A.out;B.out;A.out

So, I think no globbing is involved!

Nirmal4G avatar Jun 29 '22 14:06 Nirmal4G