Skip to content

Use PortableRuntimeIdentifierGraph in ToolPackage#55046

Open
am11 wants to merge 2 commits into
dotnet:mainfrom
am11:patch-7
Open

Use PortableRuntimeIdentifierGraph in ToolPackage#55046
am11 wants to merge 2 commits into
dotnet:mainfrom
am11:patch-7

Conversation

@am11

@am11 am11 commented Jun 27, 2026

Copy link
Copy Markdown
Member

The legacy graph is frozen since .NET 8 and we are supposed to use portable graph for new platforms. However, after building OpenBSD, I found that "dotnet tool" fails as it ends up using the legacy graph.

@jkotas

jkotas commented Jun 27, 2026

Copy link
Copy Markdown
Member

I found that "dotnet tool" fails as it ends up using the legacy graph.

Where does it end up using it?

@am11

am11 commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

<Copy SourceFiles="$(NuGetPackageRoot)/microsoft.netcore.platforms/$(MicrosoftNETCorePlatformsPackageVersion)/runtime.json"
DestinationFiles="$(OutputPath)RuntimeIdentifierGraph.json"
SkipUnchangedFiles="true" />

It copies runtime.json (legacy graph) as RuntimeIdentifier.json which ends up at .dotnet/sdk/11.0.100-preview.7.26327.199/RuntimeIdentifierGraph.json (next to .dotnet/sdk/11.0.100-preview.7.26327.199/PortableRuntimeIdentifierGraph.json). At that point, it has self-referencing entry:

    "openbsd-x64": {
      "#import": [
        "openbsd-x64"
      ]
    }

(without the proper hierarchy)

It's added by https://github.com/dotnet/runtime/blob/8207ad3ca9ad1f77606f27150c3c26ca47812f86/src/libraries/Microsoft.NETCore.Platforms/src/UpdateRuntimeIdentifierGraph.cs#L44.

@am11

am11 commented Jun 27, 2026

Copy link
Copy Markdown
Member Author

I published openbsd-x64 sdk via GA workflow https://github.com/am11/dotnet-riscv/releases/tag/11.0.100-preview.7.26327.199, if you extract the tar, you will find both files under that location.

@jkotas

jkotas commented Jun 28, 2026

Copy link
Copy Markdown
Member

self-referencing entry

That sounds like a bug at https://github.com/dotnet/runtime/blob/567a079a3f45e2e217815b49e1e09fa76ab72f11/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj#L29C46-L29C55 . This line will introduce the self-reference when TargetRid == PortableTargetRid .

@am11

am11 commented Jun 28, 2026

Copy link
Copy Markdown
Member Author

@jkotas, I have tested with this PR and can confirm that dotnet tool install/restore works which was failing before. I think we wanted to move on from legacy RID graph, so it makes sense to use PortableRuntimeIdentifierGraph (unlikely that people are using non-portable RID for tools, because it builds the shim using the executing SDK regardless of its portability).

If it makes sense then this PR switching to portable graph (when available; not available in <.NET8 TFMs) can move forward.

dotnet/runtime#129929 is optional; it only makes sense if this PR is not accepted, or if we want to support <UseRidGraph>true (https://github.com/dotnet/docs/blob/51e9afa6123259b9e505e2bc80d53865336b5ab6/docs/core/tools/sdk-errors/netsdk1206.md) for newly on-boarded platforms (which I doubt is interesting at all for openbsd).

That sounds like a bug at dotnet/runtime@567a079/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj#L29C46-L29C55 . This line will introduce the self-reference when TargetRid == PortableTargetRid .

Correctness fix is in dotnet/runtime#129944 (i.e. it is unrelated to dotnet tool restore fix).

Comment thread src/Cli/dotnet/ToolPackage/ToolPackageDownloaderBase.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates dotnet tool’s RID graph lookup to use the portable runtime identifier graph so newer platforms (e.g., OpenBSD) can resolve RID-specific tool packages correctly, aligning tool behavior with post-.NET 8 RID-graph expectations.

Changes:

  • Switch default runtime graph file from RuntimeIdentifierGraph.json (legacy/frozen) to PortableRuntimeIdentifierGraph.json for tool package operations.

Comment thread src/Cli/dotnet/ToolPackage/ToolPackageDownloaderBase.cs

@jkotas jkotas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Migrating away from the legacy RID graph for tools looks good to me.

I will leave this for the tools area owners to sign off.

@am11

am11 commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

@baronfel could you (or refer someone to) review this patch? Thanks! :)

@baronfel baronfel requested a review from dsplaisted June 29, 2026 15:04

@baronfel baronfel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - though we should log this as a breaking change in the .NET 11 tools since any tools that use platform identifiers that are not in the new portable graph would no longer to be able to be installed.

@baronfel baronfel added breaking-change Using this label will notify dotnet/compat and trigger a request to file a compat bug needs-breaking-change-doc-created labels Jun 29, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Added needs-breaking-change-doc-created label because this PR has the breaking-change label.

When you commit this breaking change:

  1. Create and link to this PR and the issue a matching issue in the dotnet/docs repo using the breaking change documentation template, then remove this needs-breaking-change-doc-created label.
  2. Ask a committer to mail the .NET SDK Breaking Change Notification email list.

You can refer to the .NET SDK breaking change guidelines

@am11

am11 commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

@baronfel, it's a breaking change, in theory, but not in the way the "portable" vs. non-portable distinction might initially suggest.

Before: it uses the full RuntimeIdentifierGraph (for example, fedora.37-x64 -> fedora-x64 -> linux-x64 -> linux).

After: it uses PortableRuntimeIdentifierGraph. At first glance, it may seem like it loses the fedora.37-x64 -> fedora-x64 part, but in fact we process both graphs and add the build TargetRid here:

https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/src/Microsoft.NETCore.Platforms.csproj#L59-L65

This effectively produces fedora.37-x64 -> linux-x64 -> linux.

That missing fedora-x64 link is essentially unnecessary. We could hypothetically create a Fedora-wide package, but in practice the distro use case was: "I want to build binaries within my distro namespace and resolve runtime dependencies (libunwind etc.) from system packages rather than in-tree copies". Since each distro version ships different dependency versions, a generic fedora-x64 layer does not represent a meaningful requirement boundary in practice.

@am11

am11 commented Jun 29, 2026

Copy link
Copy Markdown
Member Author

To wit:

$ docker run --rm fedora bash -c 'dnf install -y dotnet-sdk-10.0 &>/dev/null &&
    tail -10 /usr/lib64/dotnet/sdk/*/PortableRuntimeIdentifierGraph.json'

        "win"
      ]
    },
    "fedora.44-arm64": {
      "#import": [
        "linux-arm64"
      ]
    }
  }

@dsplaisted

Copy link
Copy Markdown
Member

WRT the breaking change, is a tool targeting something like win7-x64 a case that would break?

@am11

am11 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

WRT the breaking change, is a tool targeting something like win7-x64 a case that would break?

If SDK was built with build.cmd -rid win7-x64 (VMR's top-level script), then tool published with win7-x64 RID will work, as this explicitly RID will be present in PortableRuntimeIdentifierGraph.json after UpdateRuntimeIdentifierGraph post-processing, and it won't break.

If SDK was built with build.cmd -rid win-x64, then tool published with win7-x64 RID won't work after this change. This is the same breaking change made in .NET 8 for nuget packages dotnet/docs#36527, I think tools not included in that change was just an oversight rather than a deliberate decision.

@dsplaisted

Copy link
Copy Markdown
Member

If SDK was built with build.cmd -rid win-x64, then tool published with win7-x64 RID won't work after this change. This is the same breaking change made in .NET 8 for nuget packages dotnet/docs#36527, I think tools not included in that change was just an oversight rather than a deliberate decision.

We have a build property you can set to use the older graph during build, in order to consume older packages that use the old RIDs. We don't currently have anything like that for tool packages.

Can we do an analysis of how many tool packages use RIDs that aren't in the portable graph? @baronfel @nkolev92

If there are such tool packages, we might want to change the logic for tools to try to use the portable graph, and if that fails fall back to the old RID graph.

@am11

am11 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

We don't currently have anything like that for tool packages.

We can add an explicit switch --use-legacy-rid-graph to dotnet tool install command because it ends up calling this https://github.com/dotnet/dotnet/blob/e68331ec7757ddc52ab64e813fa7235be0d33b2d/src/nuget-client/src/NuGet.Core/NuGet.Packaging/ContentModel/ManagedCodeConventions.cs#L79. I'm not sure if there is any tool package which has {ToolPath}/tools/netX.0/any/runtimes/win7 but not {ToolPath}/tools/net8.0/any/runtimes/win dir, but would be good to find out what analysis shows. (I'd be genuinely surprised if there is a single such package on nuget.org)

@baronfel

baronfel commented Jul 2, 2026

Copy link
Copy Markdown
Member

I went spelunking in the NuGet package telemetry for the latest versions of all tool packages on NuGet.org, and inspected their listed files to determine the TFMs and RIDs (if any) supported by those tools.

No tool packages had any RIDs that were only on the old graph - so I feel pretty confident in making this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Tools breaking-change Using this label will notify dotnet/compat and trigger a request to file a compat bug needs-breaking-change-doc-created

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants