Skip to content

Clarify RID-specific .NET tools packaging and add hybrid pattern guidance#51297

Merged
richlander merged 18 commits intomainfrom
copilot/update-rid-specific-tools-docs
Jan 23, 2026
Merged

Clarify RID-specific .NET tools packaging and add hybrid pattern guidance#51297
richlander merged 18 commits intomainfrom
copilot/update-rid-specific-tools-docs

Conversation

Copy link
Contributor

Copilot AI commented Jan 23, 2026

  • Add platform requirements section for Native AOT
  • Clarify that SDK can cross-compile for architecture but not OS
  • Document build options: local machine, containers, or federated builds
  • Explain that RID-specific packages don't need to be built on same machine/time
  • Reorganize AOT tools section with clearer subheadings
Original prompt

Update the Learn article docs/core/tools/rid-specific-tools.md in the dotnet/docs repo to reflect clarified guidance on RID-specific .NET tools packaging, especially around RuntimeIdentifiers, ToolPackageRuntimeIdentifiers, and PublishAot, and to add the dotnet10-hybrid-tool sample.

Context:

Required changes to docs/core/tools/rid-specific-tools.md:

  1. Clarify when to use RuntimeIdentifiers vs ToolPackageRuntimeIdentifiers

    • Under “Opt in to RID-specific packaging”, after the existing RuntimeIdentifiers and ToolPackageRuntimeIdentifiers subsections, add a new subsection:
    ### When to use `RuntimeIdentifiers` vs `ToolPackageRuntimeIdentifiers`
    
    Both `RuntimeIdentifiers` and `ToolPackageRuntimeIdentifiers` opt your tool into RID-specific packaging, but they serve slightly different purposes:
    
    - Use **`RuntimeIdentifiers`** when:
      - You want the project to **build and publish RID-specific apps in general** (not just as a tool).
      - You are primarily targeting **CoreCLR** (non-AOT) or you want the standard SDK behavior where a single `dotnet pack` can produce RID-specific packages.
      - You may conditionalize `PublishAot` for a subset of RIDs, but you still want a CoreCLR-based package for every RID in `RuntimeIdentifiers`.
    
    - Use **`ToolPackageRuntimeIdentifiers`** when:
      - You want to define **RID-specific behavior only for the tool packaging**, without changing how the project builds for other deployment scenarios.
      - You’re using **Native AOT** and plan to **manually build** AOT binaries per RID with `dotnet pack -r <RID>`.
      - You want a **hybrid model** where some RIDs get Native AOT and others fall back to a portable CoreCLR implementation.
    
    In all cases where `PublishAot` is **not** set, the set of RIDs in `ToolPackageRuntimeIdentifiers` should be equal to or a subset of the RIDs in `RuntimeIdentifiers`. When `PublishAot` is enabled, RID-specific packages are generated only when you build for a specific RID (for example, `dotnet pack -r linux-x64`).
    
    The top-level pointer package is informed by `ToolPackageRuntimeIdentifiers` or `RuntimeIdentifiers`, in that precedence order: if `ToolPackageRuntimeIdentifiers` is specified, it determines the tool RIDs; otherwise, `RuntimeIdentifiers` is used.
  2. Make PublishAot behavior explicit in the AOT tools section

    • In the “AOT tools” section (after the existing bullets explaining dotnet pack and dotnet pack -r), add:
    When you set `<PublishAot>true</PublishAot>`, the packing behavior changes:
    
    - A regular `dotnet pack` with `PublishAot=true`:
      - Produces the **top-level pointer package** (package type `DotnetTool`).
      - Does **not** automatically produce RID-specific packages, because Native AOT requires building on (or for) a specific platform.
    
    - RID-specific AOT packages are produced only when you explicitly pass `-r <RID>`:
      - `dotnet pack -r linux-x64`
      - `dotnet pack -r osx-arm64`
      - and so on.
    
    With `PublishAot=true`:
    
    - `RuntimeIdentifiers` or `ToolPackageRuntimeIdentifiers` describe the set of RIDs your tool intends to support.
    - You are responsible for invoking `dotnet pack -r <RID>` for each of those RIDs on the appropriate build environment (for example, on Windows for `win-x64`).
  3. Add a “Hybrid AOT + CoreCLR packaging pattern (example)” subsection

    • Still under “AOT tools”, after the explanation above, add a new subsection that explains the pattern and references the demo repo, with this content:
    ### Hybrid AOT + CoreCLR packaging pattern (example)
    
    Some tools want the best of both worlds:
    
    - **Native AOT** for a subset of high-priority platforms (for example, Linux and macOS).
    - A **portable CoreCLR fallback** that works on any platform, including those without an AOT build (for example, Windows when no AOT build is produced).
    
    You can achieve this “hybrid” model with the following pattern:
    
    1. **Configure the tool for Native AOT and tool-specific RIDs**
    
       In your project file, use `ToolPackageRuntimeIdentifiers` and enable `PublishAot`:
    
       ```xml
       <Project Sdk="Microsoft.NET.Sdk">
         <PropertyGroup>
           <OutputType>Exe</OutputType>
           <TargetFramework>net10.0</TargetFramework>
           <PackAsTool>true</PackAsTool>
           <ToolCommandName>yourtool</ToolCommandName>
    
           <!--...
    

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.


Internal previews

📄 File 🔗 Preview link
docs/core/tools/rid-specific-tools.md Create RID-specific, self-contained, and AOT .NET tools

… and clarifications

Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Copilot AI changed the title [WIP] Update RID-specific tools article with clarified guidance Clarify RID-specific .NET tools packaging with hybrid AOT pattern Jan 23, 2026
Copilot AI requested a review from richlander January 23, 2026 06:07
Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Copilot AI changed the title Clarify RID-specific .NET tools packaging with hybrid AOT pattern Clarify RID-specific packaging is transparent to users Jan 23, 2026
Copilot AI requested a review from richlander January 23, 2026 06:17
Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Copilot AI changed the title Clarify RID-specific packaging is transparent to users Clarify RID-specific .NET tools packaging guidance Jan 23, 2026
Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Copilot AI changed the title Clarify RID-specific .NET tools packaging guidance Clarify RID-specific .NET tools packaging and remove redundancy Jan 23, 2026
Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Copilot AI changed the title Clarify RID-specific .NET tools packaging and remove redundancy Clarify RID-specific .NET tools packaging and add hybrid pattern guidance Jan 23, 2026
@richlander richlander marked this pull request as ready for review January 23, 2026 06:38
Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com>
@richlander
Copy link
Member

Thanks for the fixes @gewarren!

richlander and others added 2 commits January 23, 2026 09:01
Co-authored-by: Andy (Steve) De George <67293991+adegeo@users.noreply.github.com>
Updated the instructions for AOT tools to remove redundant commands and clarify RID-specific packing.
…s for AOT

Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
Co-authored-by: richlander <2608468+richlander@users.noreply.github.com>
@richlander richlander enabled auto-merge (squash) January 23, 2026 19:35
@richlander richlander merged commit 32658e4 into main Jan 23, 2026
11 checks passed
@richlander richlander deleted the copilot/update-rid-specific-tools-docs branch January 23, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants