Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 10: odd <ItemGroup> behavior #11237

Open
jonathanpeppers opened this issue Jan 7, 2025 · 10 comments
Open

.NET 10: odd <ItemGroup> behavior #11237

jonathanpeppers opened this issue Jan 7, 2025 · 10 comments
Labels
needs-triage Have yet to determine what bucket this goes in. Partner request

Comments

@jonathanpeppers
Copy link
Member

jonathanpeppers commented Jan 7, 2025

Issue Description

We're trying to get on .NET 10 here:

We are currently blocked on this <ItemGroup> not working as expected:

https://github.com/dotnet/sdk/blob/e847db398b6ffcbaa94ea85dee7a84c6480d3da5/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.props#L82-L90

Which results in this value missing a %(RuntimePackLabels) item metadata, even though $(UseMonoRuntime) is true:

Image

However, if I add a log message, such as:

<_Logging Include="UseMonoRuntime=$(UseMonoRuntime);_TargetFrameworkVersionWithoutV=$(_TargetFrameworkVersionWithoutV)" />

It prints values as expected:

Image

Steps to Reproduce

I am unable to make a small repro, this example works fine:

<Project>
  <PropertyGroup>
    <_DotNetSdk>D:\dotnet-sdk-10.0.100-alpha.1.25056.1-win-x64\sdk\10.0.100-alpha.1.25056.1\</_DotNetSdk>
    <TargetFramework>net10.0</TargetFramework>
    <TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
    <_TargetFrameworkVersionWithoutV>$(TargetFrameworkVersion.TrimStart('vV'))</_TargetFrameworkVersionWithoutV>
  </PropertyGroup>
  <Import Project="$(_DotNetSdk)Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.DefaultItems.props" />
  <Target Name="Print">
    <Message Text="%(FrameworkReference.Identity) RuntimePackLabels=%(FrameworkReference.RuntimePackLabels)" Importance="High" />
  </Target>
  <PropertyGroup>
    <UseMonoRuntime>true</UseMonoRuntime>
  </PropertyGroup>
</Project>
> & "D:\dotnet-sdk-10.0.100-alpha.1.25056.1-win-x64\dotnet.exe" build foo.targets -tl:off -bl -t:Print
  Microsoft.NETCore.App RuntimePackLabels=Mono

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.05

So, it must be related to a larger build with lots of item groups?

Best repro I have, is to build an Android project on the PR above...

Expected Behavior

After project evaluation, we should have an item like:

<FrameworkReference Include="Microsoft.NETCore.App" RuntimePackLabels="Mono" />

Actual Behavior

After project evaluation, we are missing %(RuntimePackLabels) for:

<FrameworkReference Include="Microsoft.NETCore.App" />

Analysis

Here is an example .binlog, if you search for FrameworkReference:

build.zip

I made these changes in this log:

    <!-- Allow opt-in to Mono runtime pack for .NET 6.0 or higher -->
    <FrameworkReference Update="Microsoft.NETCore.App"
                        RuntimePackLabels="Mono"
--                      Condition="'$(UseMonoRuntime)' == 'true' And ('$(_TargetFrameworkVersionWithoutV)' != '') And ('$(_TargetFrameworkVersionWithoutV)' >= '6.0')"
                         />
++<_Logging Include="UseMonoRuntime=$(UseMonoRuntime);_TargetFrameworkVersionWithoutV=$(_TargetFrameworkVersionWithoutV)" />

Versions & Configurations

We've seen this behavior with the following .NET SDKs:

  • 10.0.100-alpha.1.25056.1
  • 10.0.100-alpha.1.24573.1

On both Windows and macOS, local and CI.

@Forgind
Copy link
Member

Forgind commented Jan 8, 2025

I'm not sure how to verify this from the binlog, but I suspect it's doing a string comparison with this condition:
('$(_TargetFrameworkVersionWithoutV)' >= '6.0')

And 10.0 < 6.0 because 1 < 6.

I'll try to reproduce this as described then see if I can figure out how to modify your code to use the version comparison function built into MSBuild and see if it starts working.

/cc: @akoeplinger as he mentioned this being a blocker for a PR that I want in 🙂

@Forgind
Copy link
Member

Forgind commented Jan 9, 2025

Actually, since the first condition (including that it was > 3.0) was true, I think I was probably wrong.

@Forgind Forgind added the needs-triage Have yet to determine what bucket this goes in. label Jan 9, 2025
@akoeplinger
Copy link
Member

Yeah that's unrelated. In the binlog from @jonathanpeppers you can see that the condition was removed completely, yet it still didn't work so somehow Update is broken.

@rmarinho
Copy link
Member

rmarinho commented Jan 9, 2025

this is holding Android, and holding MAUI, do we have a workaround or something that Android can use to get builds flowing to other repos?

@jonathanpeppers
Copy link
Member Author

@akoeplinger discovered something odd about the issue, if we move the project directory from:

  • bin\TestDebug\temp\CheckSignApk(True,True)

To:

  • bin\TestDebug\temp\CheckSignApkTrueTrue

Then this problem goes away.

Trying this out on CI, but we might still have other failures in integration tests that specifically use characters like ( and ).

@akoeplinger
Copy link
Member

akoeplinger commented Jan 9, 2025

@Forgind I reduced it down to this sample project:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <UseMonoRuntime>true</UseMonoRuntime>
  </PropertyGroup>

  <Target Name="Foo" BeforeTargets="Build">
    <Message Text="Labels: @(FrameworkReference->Metadata('RuntimePackLabels'))" Importance="High" />
  </Target>

</Project>

Run this with dotnet build -tl:off and it will print

Labels: Mono

Run it in a directory that has parenthesis and it will print:

Labels:

@Forgind
Copy link
Member

Forgind commented Jan 9, 2025

I managed to get it to not need the mono runtime and gave the Item we're looking for a more pointed description.

Apparently it has nothing to do with Update or Metadata, either, as I was able to reproduce the same problem with just Include.

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Itezfz Include="Program.cs" />
  </ItemGroup>

  <Target Name="Foo" BeforeTargets="Build">
    <Message Text="Labels: @(Itezfz)" Importance="High" />
  </Target>

</Project>

@Forgind
Copy link
Member

Forgind commented Jan 9, 2025

It isn't even showing up in the binlog, nor is it throwing an exception:
Image

@Forgind
Copy link
Member

Forgind commented Jan 10, 2025

I found that the LazyItemEvaluator.IncludeOperation was being created and added to a list of operations to eventually evaluate properly. Inspecting it at that point, it looked right/similar to other operations. I then tried to find it when it actually evaluated the operations, and it was mysteriously missing (or my debugger failed to break on my conditional breakpoint when it showed up, at least). All this happened without any user-visible errors.

@Forgind
Copy link
Member

Forgind commented Jan 10, 2025

Also, just one parenthesis suffices in the path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-triage Have yet to determine what bucket this goes in. Partner request
Projects
None yet
Development

No branches or pull requests

4 participants