From 6f2226758a106b6f94f58f2261ac6ab1e89d4396 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:37:28 +0000 Subject: [PATCH 1/6] Initial plan From 95b4e13b02de76428c4d32fc9aa28ee97073c5a9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 12 Nov 2025 23:43:39 +0000 Subject: [PATCH 2/6] Add RID-specific and AOT .NET tools documentation Co-authored-by: meaghanlewis <10103121+meaghanlewis@users.noreply.github.com> --- docs/core/tools/global-tools-how-to-create.md | 4 + docs/core/tools/global-tools.md | 1 + docs/core/tools/rid-specific-tools.md | 214 ++++++++++++++++++ 3 files changed, 219 insertions(+) create mode 100644 docs/core/tools/rid-specific-tools.md diff --git a/docs/core/tools/global-tools-how-to-create.md b/docs/core/tools/global-tools-how-to-create.md index 5b01fc341b93e..ae335a37f589c 100644 --- a/docs/core/tools/global-tools-how-to-create.md +++ b/docs/core/tools/global-tools-how-to-create.md @@ -226,3 +226,7 @@ If you prefer, you can skip the global tools tutorial and go directly to the loc > [!div class="nextstepaction"] > [Install and use a local tool](local-tools-how-to-use.md) + +## See also + +- [Create RID-specific and AOT .NET tools](rid-specific-tools.md) diff --git a/docs/core/tools/global-tools.md b/docs/core/tools/global-tools.md index ba085ac04867c..1000627d9b92b 100644 --- a/docs/core/tools/global-tools.md +++ b/docs/core/tools/global-tools.md @@ -300,3 +300,4 @@ dotnet --help * [Tutorial: Create a .NET tool using the .NET CLI](global-tools-how-to-create.md) * [Tutorial: Install and use a .NET global tool using the .NET CLI](global-tools-how-to-use.md) * [Tutorial: Install and use a .NET local tool using the .NET CLI](local-tools-how-to-use.md) +* [Create RID-specific and AOT .NET tools](rid-specific-tools.md) diff --git a/docs/core/tools/rid-specific-tools.md b/docs/core/tools/rid-specific-tools.md new file mode 100644 index 0000000000000..0613a37f90408 --- /dev/null +++ b/docs/core/tools/rid-specific-tools.md @@ -0,0 +1,214 @@ +--- +title: Create RID-specific and AOT .NET tools +description: Learn how to create and package RID-specific and AOT-enabled .NET tools for platform-specific distribution. +ms.topic: how-to +ms.date: 11/12/2025 +ai-usage: ai-assisted +--- + +# Create RID-specific and AOT .NET tools + +**This article applies to:** ✔️ .NET SDK 10.0.100-preview.6 and later versions + +.NET tools can be packaged for specific platforms and architectures, enabling distribution of native, fast, and trimmed applications. This capability is useful for creating high-performance command-line tools like MCP servers or other platform-specific utilities. + +## Overview + +Starting with .NET SDK 10.0.100-preview.6, you can create .NET tools that target specific Runtime Identifiers (RIDs). These tools can be: + +- **RID-specific**: Compiled for particular operating systems and architectures. +- **Self-contained**: Include the .NET runtime and don't require a separate .NET installation. +- **AOT-compiled**: Use Ahead-of-Time compilation for faster startup and smaller memory footprint. + +When users install a RID-specific tool, the .NET CLI automatically selects and installs the appropriate package for their platform. + +## Opt in to RID-specific packaging + +To create a RID-specific tool, configure your project with one of the following MSBuild properties: + +### RuntimeIdentifiers property + +Use `RuntimeIdentifiers` to specify the platforms your tool supports: + +```xml + + + Exe + net9.0 + true + mytool + win-x64;linux-x64;osx-arm64 + + +``` + +### ToolPackageRuntimeIdentifiers property + +Alternatively, use `ToolPackageRuntimeIdentifiers` for tool-specific RID configuration: + +```xml + + + Exe + net9.0 + true + mytool + win-x64;linux-x64;osx-arm64 + + +``` + +Use a semicolon-delimited list of RID values. For a list of Runtime Identifiers, see the [RID catalog](../rid-catalog.md). + +## Package your tool + +The packaging process differs depending on whether you're using AOT compilation. + +### Non-AOT tools + +For tools without AOT compilation, run `dotnet pack` once: + +```dotnetcli +dotnet pack +``` + +This command creates multiple NuGet packages: + +- One package for each RID: `...nupkg` + - Example: `mytool.win-x64.1.0.0.nupkg` + - Example: `mytool.linux-x64.1.0.0.nupkg` + - Example: `mytool.osx-arm64.1.0.0.nupkg` +- One RID-agnostic pointer package: `..nupkg` + - Example: `mytool.1.0.0.nupkg` + +### AOT tools + +For tools with AOT compilation (`true`), you must pack separately for each platform: + +1. Pack the top-level package once (on any platform): + + ```dotnetcli + dotnet pack + ``` + +2. Pack for each specific RID on the corresponding platform: + + ```dotnetcli + dotnet pack -r win-x64 + dotnet pack -r linux-x64 + dotnet pack -r osx-arm64 + ``` + + You must run each RID-specific pack command on the matching platform because AOT compilation produces native binaries. + +## Package structure + +### Package types + +RID-specific tool packages use two package types: + +- **DotnetTool**: The top-level package that contains metadata +- **DotnetToolRidPackage**: The RID-specific packages that contain the actual tool binaries + +### Package metadata + +The top-level package includes metadata that signals it's a RID-specific tool and lists the available RID-specific packages. When you run `dotnet tool install`, the CLI reads this metadata to determine which RID-specific package to install for the current platform. + +## Publish your tool + +Publish all packages to NuGet.org or your package feed: + +```dotnetcli +dotnet nuget push mytool.1.0.0.nupkg +dotnet nuget push mytool.win-x64.1.0.0.nupkg +dotnet nuget push mytool.linux-x64.1.0.0.nupkg +dotnet nuget push mytool.osx-arm64.1.0.0.nupkg +``` + +## Install a RID-specific tool + +Users install RID-specific tools the same way as regular tools: + +```dotnetcli +dotnet tool install -g mytool +``` + +The CLI automatically: + +1. Downloads the top-level package +2. Reads the RID-specific metadata +3. Identifies the most appropriate package for the current platform +4. Downloads and installs the RID-specific package + +## Example: Create an AOT tool + +Here's a complete example of creating an AOT-compiled RID-specific tool: + +1. Create a new console application: + + ```dotnetcli + dotnet new console -n MyFastTool + cd MyFastTool + ``` + +2. Update the project file to enable AOT and RID-specific packaging: + + ```xml + + + Exe + net9.0 + true + myfasttool + win-x64;linux-x64;osx-arm64 + true + MyFastTool + 1.0.0 + Your Name + A fast AOT-compiled tool + + + ``` + +3. Add your application code in `Program.cs`: + + ```csharp + Console.WriteLine("Hello from MyFastTool!"); + Console.WriteLine($"Running on {Environment.OSVersion}"); + ``` + +4. Pack the top-level package: + + ```dotnetcli + dotnet pack + ``` + +5. Pack for each specific RID (on the corresponding platform): + + On Windows: + + ```dotnetcli + dotnet pack -r win-x64 + ``` + + On Linux: + + ```dotnetcli + dotnet pack -r linux-x64 + ``` + + On macOS: + + ```dotnetcli + dotnet pack -r osx-arm64 + ``` + +6. Publish all packages to NuGet.org. + +## See also + +- [Tutorial: Create a .NET tool](global-tools-how-to-create.md) +- [.NET tools overview](global-tools.md) +- [dotnet pack command](dotnet-pack.md) +- [RID catalog](../rid-catalog.md) +- [Native AOT deployment](../deploying/native-aot/index.md) From dba04035583adbc6aaf2953fff8a1ddefde36326 Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Thu, 13 Nov 2025 15:52:50 -0800 Subject: [PATCH 3/6] article updates --- docs/core/tools/rid-specific-tools.md | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/core/tools/rid-specific-tools.md b/docs/core/tools/rid-specific-tools.md index 0613a37f90408..aa702553d5a96 100644 --- a/docs/core/tools/rid-specific-tools.md +++ b/docs/core/tools/rid-specific-tools.md @@ -1,20 +1,20 @@ --- -title: Create RID-specific and AOT .NET tools -description: Learn how to create and package RID-specific and AOT-enabled .NET tools for platform-specific distribution. +title: Create RID-specific, self-contained, and AOT .NET tools +description: Learn how to create and package RID-specific, self-contained and AOT .NET tools for platform-specific distribution. ms.topic: how-to ms.date: 11/12/2025 ai-usage: ai-assisted --- -# Create RID-specific and AOT .NET tools +# Create RID-specific, self-contained, and AOT .NET tools -**This article applies to:** ✔️ .NET SDK 10.0.100-preview.6 and later versions +**This article applies to:** ✔️ .NET SDK 10 and later versions -.NET tools can be packaged for specific platforms and architectures, enabling distribution of native, fast, and trimmed applications. This capability is useful for creating high-performance command-line tools like MCP servers or other platform-specific utilities. +.NET tools can be packaged for specific platforms and architectures, enabling distribution of native, fast, and trimmed applications. This capability makes it easier to distribute native, fast, trimmed .NET applications for command-line tools like MCP servers or other platform-specific utilities. ## Overview -Starting with .NET SDK 10.0.100-preview.6, you can create .NET tools that target specific Runtime Identifiers (RIDs). These tools can be: +Starting with .NET SDK 10, you can create .NET tools that target specific Runtime Identifiers (RIDs). These tools can be: - **RID-specific**: Compiled for particular operating systems and architectures. - **Self-contained**: Include the .NET runtime and don't require a separate .NET installation. @@ -26,9 +26,9 @@ When users install a RID-specific tool, the .NET CLI automatically selects and i To create a RID-specific tool, configure your project with one of the following MSBuild properties: -### RuntimeIdentifiers property +### RuntimeIdentifier property -Use `RuntimeIdentifiers` to specify the platforms your tool supports: +Use `RuntimeIdentifier` to specify the platforms your tool supports: ```xml @@ -37,14 +37,14 @@ Use `RuntimeIdentifiers` to specify the platforms your tool supports: net9.0 true mytool - win-x64;linux-x64;osx-arm64 + win-x64;linux-x64;osx-arm64 ``` -### ToolPackageRuntimeIdentifiers property +### ToolPackageRuntimeIdentifier property -Alternatively, use `ToolPackageRuntimeIdentifiers` for tool-specific RID configuration: +Alternatively, use `ToolPackageRuntimeIdentifier` for tool-specific RID configuration: ```xml @@ -53,7 +53,7 @@ Alternatively, use `ToolPackageRuntimeIdentifiers` for tool-specific RID configu net9.0 true mytool - win-x64;linux-x64;osx-arm64 + win-x64;linux-x64;osx-arm64 ``` @@ -112,7 +112,7 @@ RID-specific tool packages use two package types: ### Package metadata -The top-level package includes metadata that signals it's a RID-specific tool and lists the available RID-specific packages. When you run `dotnet tool install`, the CLI reads this metadata to determine which RID-specific package to install for the current platform. +The top-level package includes metadata that signals it's a RID-specific tool and lists the RID-specific packages. When you run `dotnet tool install`, the CLI reads this metadata to determine which RID-specific package to install for the current platform. ## Publish your tool @@ -135,10 +135,10 @@ dotnet tool install -g mytool The CLI automatically: -1. Downloads the top-level package -2. Reads the RID-specific metadata -3. Identifies the most appropriate package for the current platform -4. Downloads and installs the RID-specific package +1. Downloads the top-level package. +1. Reads the RID-specific metadata. +1. Identifies the most appropriate package for the current platform. +1. Downloads and installs the RID-specific package. ## Example: Create an AOT tool From 8c65aa8b47438a5084fc5e3b5449b6cfb40a238e Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Thu, 13 Nov 2025 15:53:00 -0800 Subject: [PATCH 4/6] add article to TOC --- docs/navigate/tools-diagnostics/toc.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/navigate/tools-diagnostics/toc.yml b/docs/navigate/tools-diagnostics/toc.yml index ef7767c738afb..8c8a1b83f5e46 100644 --- a/docs/navigate/tools-diagnostics/toc.yml +++ b/docs/navigate/tools-diagnostics/toc.yml @@ -314,6 +314,9 @@ items: - name: Manage tools displayName: global tool,local tool href: ../../core/tools/global-tools.md + - name: RID-specific, self-contained, and AOT tools + displayName: rid-specific tool,self-contained tool,aot tool + href: ../../core/tools/rid-specific-tools.md - name: Troubleshoot tools displayName: global tool troubleshooting,local tool troubleshooting, href: ../../core/tools/troubleshoot-usage-issues.md From ba84d0dc549befdb2a0d85bc2fee47b90d2d7a66 Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Fri, 14 Nov 2025 14:45:01 -0800 Subject: [PATCH 5/6] edit pass --- docs/core/tools/rid-specific-tools.md | 48 +++++++++++++-------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/docs/core/tools/rid-specific-tools.md b/docs/core/tools/rid-specific-tools.md index aa702553d5a96..ad6c4a96db6b1 100644 --- a/docs/core/tools/rid-specific-tools.md +++ b/docs/core/tools/rid-specific-tools.md @@ -1,6 +1,6 @@ --- title: Create RID-specific, self-contained, and AOT .NET tools -description: Learn how to create and package RID-specific, self-contained and AOT .NET tools for platform-specific distribution. +description: Learn how to create and package RID-specific, self-contained, and AOT .NET tools for platform-specific distribution. ms.topic: how-to ms.date: 11/12/2025 ai-usage: ai-assisted @@ -10,7 +10,7 @@ ai-usage: ai-assisted **This article applies to:** ✔️ .NET SDK 10 and later versions -.NET tools can be packaged for specific platforms and architectures, enabling distribution of native, fast, and trimmed applications. This capability makes it easier to distribute native, fast, trimmed .NET applications for command-line tools like MCP servers or other platform-specific utilities. +Package .NET tools for specific platforms and architectures so you can distribute native, fast, and trimmed applications. This capability makes it easier to distribute native, fast, trimmed .NET applications for command-line tools like MCP servers or other platform-specific utilities. ## Overview @@ -18,7 +18,7 @@ Starting with .NET SDK 10, you can create .NET tools that target specific Runtim - **RID-specific**: Compiled for particular operating systems and architectures. - **Self-contained**: Include the .NET runtime and don't require a separate .NET installation. -- **AOT-compiled**: Use Ahead-of-Time compilation for faster startup and smaller memory footprint. +- **Native AOT**: Use Ahead-of-Time compilation for faster startup and smaller memory footprint. When users install a RID-specific tool, the .NET CLI automatically selects and installs the appropriate package for their platform. @@ -26,34 +26,34 @@ When users install a RID-specific tool, the .NET CLI automatically selects and i To create a RID-specific tool, configure your project with one of the following MSBuild properties: -### RuntimeIdentifier property +### RuntimeIdentifiers property -Use `RuntimeIdentifier` to specify the platforms your tool supports: +Use `RuntimeIdentifiers` to specify the platforms your tool supports: ```xml Exe - net9.0 + net10.0 true mytool - win-x64;linux-x64;osx-arm64 + win-x64;linux-x64;osx-arm64 ``` -### ToolPackageRuntimeIdentifier property +### ToolPackageRuntimeIdentifiers property -Alternatively, use `ToolPackageRuntimeIdentifier` for tool-specific RID configuration: +Alternatively, use `ToolPackageRuntimeIdentifiers` for tool-specific RID configuration: ```xml Exe - net9.0 + net10.0 true mytool - win-x64;linux-x64;osx-arm64 + win-x64;linux-x64;osx-arm64 ``` @@ -62,9 +62,9 @@ Use a semicolon-delimited list of RID values. For a list of Runtime Identifiers, ## Package your tool -The packaging process differs depending on whether you're using AOT compilation. +The packaging process differs depending on whether you're using AOT compilation. To build a NuGet package, or *.nupkg* file from the project, run the [dotnet pack](dotnet/core/tools/dotnet-pack) command. -### Non-AOT tools +### RID-specific and self-contained tools For tools without AOT compilation, run `dotnet pack` once: @@ -85,13 +85,13 @@ This command creates multiple NuGet packages: For tools with AOT compilation (`true`), you must pack separately for each platform: -1. Pack the top-level package once (on any platform): +- Pack the top-level package once (on any platform): ```dotnetcli dotnet pack ``` -2. Pack for each specific RID on the corresponding platform: +- Pack for each specific RID on the corresponding platform: ```dotnetcli dotnet pack -r win-x64 @@ -107,8 +107,8 @@ For tools with AOT compilation (`true`), you must pack RID-specific tool packages use two package types: -- **DotnetTool**: The top-level package that contains metadata -- **DotnetToolRidPackage**: The RID-specific packages that contain the actual tool binaries +- **DotnetTool**: The top-level package that contains metadata. +- **DotnetToolRidPackage**: The RID-specific packages that contain the actual tool binaries. ### Package metadata @@ -116,7 +116,7 @@ The top-level package includes metadata that signals it's a RID-specific tool an ## Publish your tool -Publish all packages to NuGet.org or your package feed: +Publish all packages to NuGet.org or your package feed by using [dotnet nuget push](/dotnet/core/tools/dotnet-nuget-push): ```dotnetcli dotnet nuget push mytool.1.0.0.nupkg @@ -151,13 +151,13 @@ Here's a complete example of creating an AOT-compiled RID-specific tool: cd MyFastTool ``` -2. Update the project file to enable AOT and RID-specific packaging: +1. Update the project file to enable AOT and RID-specific packaging: ```xml Exe - net9.0 + net10.0 true myfasttool win-x64;linux-x64;osx-arm64 @@ -170,20 +170,20 @@ Here's a complete example of creating an AOT-compiled RID-specific tool: ``` -3. Add your application code in `Program.cs`: +1. Add your application code in `Program.cs`: ```csharp Console.WriteLine("Hello from MyFastTool!"); Console.WriteLine($"Running on {Environment.OSVersion}"); ``` -4. Pack the top-level package: +1. Pack the top-level package: ```dotnetcli dotnet pack ``` -5. Pack for each specific RID (on the corresponding platform): +1. Pack for each specific RID (on the corresponding platform): On Windows: @@ -203,7 +203,7 @@ Here's a complete example of creating an AOT-compiled RID-specific tool: dotnet pack -r osx-arm64 ``` -6. Publish all packages to NuGet.org. +1. Publish all packages to NuGet.org by using the [dotnet nuget push](/dotnet/core/tools/dotnet-nuget-push) command. ## See also From ab9fe4f349e8c0b3799b1005ba342c374a2d842a Mon Sep 17 00:00:00 2001 From: Meaghan Osagie Date: Fri, 14 Nov 2025 14:52:46 -0800 Subject: [PATCH 6/6] fix broken link --- docs/core/tools/rid-specific-tools.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/core/tools/rid-specific-tools.md b/docs/core/tools/rid-specific-tools.md index ad6c4a96db6b1..fe6c983aa1bfa 100644 --- a/docs/core/tools/rid-specific-tools.md +++ b/docs/core/tools/rid-specific-tools.md @@ -62,7 +62,7 @@ Use a semicolon-delimited list of RID values. For a list of Runtime Identifiers, ## Package your tool -The packaging process differs depending on whether you're using AOT compilation. To build a NuGet package, or *.nupkg* file from the project, run the [dotnet pack](dotnet/core/tools/dotnet-pack) command. +The packaging process differs depending on whether you're using AOT compilation. To build a NuGet package, or *.nupkg* file from the project, run the [dotnet pack](dotnet-pack.md) command. ### RID-specific and self-contained tools @@ -116,7 +116,7 @@ The top-level package includes metadata that signals it's a RID-specific tool an ## Publish your tool -Publish all packages to NuGet.org or your package feed by using [dotnet nuget push](/dotnet/core/tools/dotnet-nuget-push): +Publish all packages to NuGet.org or your package feed by using [dotnet nuget push](dotnet-nuget-push.md): ```dotnetcli dotnet nuget push mytool.1.0.0.nupkg @@ -203,7 +203,7 @@ Here's a complete example of creating an AOT-compiled RID-specific tool: dotnet pack -r osx-arm64 ``` -1. Publish all packages to NuGet.org by using the [dotnet nuget push](/dotnet/core/tools/dotnet-nuget-push) command. +1. Publish all packages to NuGet.org by using the [dotnet nuget push](dotnet-nuget-push.md) command. ## See also