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.

jonathanpeppers pushed a commit to dotnet/android that referenced this issue Jan 10, 2025
Context: dotnet/msbuild#11237

In .NET 10, we noticed there is a bug if a project contains `(` or `)` in the path.

We had various tests that were not using `TestName` to sanitize the path.

We have existing tests that do test `(` and `)` characters, which we have left in place.
jonpryor pushed a commit to dotnet/android that referenced this issue Jan 10, 2025
Changes: dotnet/sdk@5b9d9d4...a93a592

	% git diff --shortstat 5b9d9d4677...a93a592ce9
	 2336 files changed, 57809 insertions(+), 28665 deletions(-)

Changes: dotnet/runtime@226c034...4b02c51

	% git diff --shortstat 226c0347b9...4b02c51f71
	 6343 files changed, 214693 insertions(+), 177501 deletions(-)

Changes: dotnet/emsdk@8e660ff...953fd74

	% git diff --shortstat 8e660ff41e...953fd74cd2
	 44 files changed, 844 insertions(+), 521 deletions(-)

Changes: dotnet/cecil@9c94433...9e8bd52

	% git diff --shortstat 9c9443396f8...9e8bd520939
	 20 files changed, 317 insertions(+), 205 deletions(-)

Changes: a8cd27e...4b20432

	% git diff --shortstat a8cd27e...4b20432
	 1522 files changed, 302553 insertions(+), 40811 deletions(-)

Context: dotnet/msbuild#11237
Context: dotnet/roslyn-analyzers#7525
Context: dotnet/maui#27040

Bump to:

  * .NET SDK 10.0.100-alpha.1.25056.1
  * .NET Runtime 10.0.0-alpha.1.25056.1
  * .NET Android 35.0.24

Note that the `Xamarin.Android-PR (MAUI Tests MAUI Integration)`
lane will fail with:

> Workload installation failed: Could not find workload 'microsoft-net-runtime-android-net9'
> extended by workload 'android' in manifest 'microsoft.net.sdk.android'

until we get dotnet/maui on .NET 10 (see e.g. dotnet/maui#27040).

Regressions discovered:

  * MSBuild: dotnet/msbuild#11237
  * Roslyn analyzers: dotnet/roslyn-analyzers#7525

I temporarily disabled tests that hit these issues, with a code
comment to restore them in the future.

Other changes:

  * Add the `dotnet10` NuGet feeds.

  * `$(DotNetTargetFramework)` is `net10.0`

  * Update project templates to say `net10.0-android`.

  * Update `WorkloadManifest.json` to support .NET 10 and able to
    build `net9.0-android` projects.

  * Replace the contents of `AutoImports.props`, so we shouldn't need
    to modify this file each year.

  * Various tests should target `net9.0-android` for the "previous"
    .NET Android version and `net10.0-android` for the current.

  * `workload-dependencies.csproj` needs `$(RollForward)=Major` to
    allow it to run on a .NET 10 runtime.

Co-authored-by: dotnet-maestro[bot] <dotnet-maestro[bot]@users.noreply.github.com>
Co-authored-by: Jonathan Peppers <jonathan.peppers@microsoft.com>
Co-authored-by: Jonathan Pobst <jonathan.pobst@microsoft.com>
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