Compartir a través de


Crear herramientas .NET específicas de RID, autónomas y AOT

Este artículo se aplica a: ✔️ SDK de .NET 10 y versiones posteriores

Empaquetar herramientas de .NET para plataformas y arquitecturas específicas para que pueda distribuir aplicaciones nativas, rápidas y recortadas. Esta funcionalidad facilita la distribución de aplicaciones optimizadas para herramientas de línea de comandos como servidores MCP u otras utilidades específicas de la plataforma.

Información general

A partir del SDK de .NET 10, puede crear herramientas de .NET destinadas a entornos de sistema operativo específicos (representados por identificadores en tiempo de ejecución (RID)). Estas herramientas pueden ser:

  • Específico de RID: compilado para determinados sistemas operativos y arquitecturas.
  • Independiente: incluya el entorno de ejecución de .NET y no requiera una instalación independiente de .NET.
  • AOT nativo: use la compilación anticipada para un inicio más rápido y una superficie de memoria más pequeña.

Los usuarios no observan ninguna diferencia cuando instalan la herramienta. La CLI de .NET selecciona e instala automáticamente el mejor paquete para su plataforma.

Optar por el paquete específico de RID

Para crear una herramienta específica de RID, configure el proyecto con una de las siguientes propiedades de MSBuild:

Propiedad RuntimeIdentifiers

Use RuntimeIdentifiers para especificar las plataformas que admite la herramienta:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <PackAsTool>true</PackAsTool>
    <ToolCommandName>mytool</ToolCommandName>
    <RuntimeIdentifiers>win-x64;linux-x64;osx-arm64</RuntimeIdentifiers>
  </PropertyGroup>
</Project>

Propiedad ToolPackageRuntimeIdentifiers

Como alternativa, use ToolPackageRuntimeIdentifiers para configuración de RID específica de herramientas.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <PackAsTool>true</PackAsTool>
    <PublishAot>true</PublishAot>
    <ToolCommandName>mytool</ToolCommandName>
    <ToolPackageRuntimeIdentifiers>win-x64;linux-x64;osx-arm64</ToolPackageRuntimeIdentifiers>
  </PropertyGroup>
</Project>

Use una lista delimitada por punto y coma de valores RID. Para obtener una lista de identificadores en tiempo de ejecución, consulte el catálogo rid.

Cuándo usar RuntimeIdentifiers frente a ToolPackageRuntimeIdentifiers

Tanto RuntimeIdentifiers como ToolPackageRuntimeIdentifiers hacen que su herramienta se integre en un empaquetado específico de RID, pero sirven a propósitos ligeramente diferentes.

Utiliza RuntimeIdentifiers si:

  • Quiere que el proyecto compile y publique aplicaciones específicas de RID en general (no solo como una herramienta).
  • Tiene como destino CoreCLR (no AOT) o quiere el comportamiento estándar del SDK en el que un solo dotnet pack genera varios paquetes específicos de RID.
  • Puede condicionalizar PublishAot para un subconjunto de RID, pero desea un paquete basado en CoreCLR para cada RID de RuntimeIdentifiers.

Utiliza ToolPackageRuntimeIdentifiers si:

  • Desea definir el comportamiento específico de RID solo para el empaquetado de herramientas, sin cambiar la forma en que se compila el proyecto para otros escenarios de implementación.
  • Está usando AOT nativo y planea compilar manualmente archivos binarios de AOT por RID con dotnet pack -r <RID>.
  • Quiere un modelo híbrido en el que algunos RID reciben AOT nativo y otros vuelven a una implementación portátil de CoreCLR.

Notes:

  • El paquete de puntero de nivel superior especifica los paquetes específicos de RID disponibles. Si especifica ToolPackageRuntimeIdentifiers, determina los identificadores de ejecución (RID) de la herramienta; de lo contrario, se usa RuntimeIdentifiers.
  • ToolPackageRuntimeIdentifiers debe ser igual o ser un subconjunto de los RIDs en RuntimeIdentifiers
  • Cuando PublishAot=true, los paquetes específicos de RID solo se generan cuando se empaqueta para un RID específico (por ejemplo, dotnet pack -r linux-x64).
  • Las compilaciones AOT nativas (PublishAot=true) solo se admiten cuando coinciden el sistema operativo de compilación y el sistema operativo de destino.

Empaquetar la herramienta

El proceso de empaquetado difiere en función de si se usa la compilación AOT. Para compilar un paquete NuGet o un archivo .nupkg desde el proyecto, ejecute el comando dotnet pack .

Herramientas específicas de RID y autocontenidas

Ejecute dotnet pack una vez:

dotnet pack

Este comando crea varios paquetes NuGet:

  • Un paquete para cada RID: <packageName>.<RID>.<packageVersion>.nupkg
    • Ejemplo: mytool.win-x64.1.0.0.nupkg
    • Ejemplo: mytool.linux-x64.1.0.0.nupkg
    • Ejemplo: mytool.osx-arm64.1.0.0.nupkg
  • Un paquete de puntero independiente de RID: <packageName>.<packageVersion>.nupkg
    • Ejemplo: mytool.1.0.0.nupkg

Herramientas de AOT

Para las herramientas con compilación AOT (<PublishAot>true</PublishAot>), deberá paquetizar por separado para cada plataforma.

Requisitos de plataforma para AOT nativo

La compilación AOT nativa requiere que la parte del sistema operativo (SO) del SDK coincida con el sistema operativo del RID de destino. El SDK puede compilar de forma cruzada para diferentes arquitecturas (por ejemplo, x64 a ARM64), pero no a través de sistemas operativos (por ejemplo, Windows a Linux).

Esto significa que tiene varias opciones para compilar paquetes AOT nativos:

  • Compilar solo para la máquina de desarrollo: El soporte de AOT nativo está disponible solo para el sistema operativo en el que estás desarrollando.
  • Uso de contenedores para compilaciones de Linux: si está en macOS o Windows, utilice contenedores para compilar de forma cruzada para Linux. Por ejemplo, use imágenes de contenedor mcr.microsoft.com/dotnet/sdk:10.0-noble-aot.
  • Federa tu compilación entre máquinas: usa sistemas de CI/CD como GitHub Actions o Azure DevOps Pipelines para compilar en diferentes sistemas operativos.

No es necesario compilar todos los paquetes específicos de RID en el mismo equipo o al mismo tiempo. Solo tiene que compilarlos y publicarlos antes de publicar el paquete de nivel superior.

Empaquetar herramientas de AOT nativas

Empaquetar el paquete de nivel superior una vez (en cualquier plataforma):

dotnet pack

Debe empaquetarse para cada RID específico en la plataforma correspondiente, por ejemplo:

dotnet pack -r linux-x64

Debe ejecutar cada comando de paquete específico del RID en una plataforma donde el sistema operativo coincida con el sistema operativo del RID de destino. Para obtener más información sobre los requisitos previos para la compilación AOT nativa, consulte Implementación de AOT nativa.

Cuando configuras PublishAot en true, el comportamiento de empaquetado cambia:

  • dotnet pack genera el paquete de puntero de nivel superior (paquete de tipo DotnetTool).
  • Los paquetes AOT específicos de RID solo se generan cuando se pasa -r <RID> explícitamente, por ejemplo, dotnet pack -r linux-x64 o dotnet pack -r osx-arm64.

Patrón de empaquetado AOT + CoreCLR híbrido (ejemplo)

Algunas herramientas quieren lo mejor de ambos mundos:

  • AOT nativo para un subconjunto de plataformas de alta prioridad (dependiendo de la herramienta).
  • Una alternativa portátil de CoreCLR que funciona en plataformas no dirigidas por las compilaciones nativas de AOT.

Puede lograr este modelo "híbrido" con el siguiente patrón:

  1. Configure la herramienta para AOT nativos y RID específicos de herramientas.

    En el archivo del proyecto, use ToolPackageRuntimeIdentifiers y habilite PublishAot.

    Por ejemplo:

    <ToolPackageRuntimeIdentifiers>osx-arm64;linux-arm64;linux-x64;any</ToolPackageRuntimeIdentifiers>
    <PublishAot>true</PublishAot>
    
  2. Cree el paquete de puntero.

    Ejecute dotnet pack una vez (en cualquier plataforma) para compilar el paquete de nivel superior que apunta a los paquetes específicos de RID:

    dotnet pack
    
  3. Compile paquetes AOT nativos para los RID seleccionados.

    La compilación AOT nativa debe realizarse en la plataforma de destino. Construya cada paquete RID habilitado para AOT en la plataforma correspondiente mediante dotnet pack -r <RID>.

Por ejemplo:

dotnet pack -r linux-x64
  1. Cree un paquete de respaldo de CoreCLR.

    Para proporcionar una alternativa universal, el paquete any RID sin AOT:

    dotnet pack -r any -p:PublishAot=false
    

    Esto genera un paquete CoreCLR portátil (por ejemplo, yourtool.any.<version>.nupkg) que se puede ejecutar en plataformas que no tienen una compilación AOT dedicada.

Nota:

También puede usar las .NET SDK 10.0-noble-aot imágenes de contenedor para compilar y empaquetar herramientas AOT nativas de Linux desde cualquier host que admita contenedores de Linux. Por ejemplo:

  • mcr.microsoft.com/dotnet/sdk:10.0-noble-aot

Esto resulta útil cuando la máquina de desarrollo no ejecuta Linux de forma nativa.

En esta configuración híbrida:

  • El paquete de puntero (yourtool.<version>.nupkg) hace referencia a ambos:
    • Paquetes AOT nativos específicos de RID (por ejemplo, yourtool.osx-arm64, yourtool.linux-x64).
    • El any paquete CoreCLR como alternativa.
  • La CLI de .NET elige automáticamente el paquete más adecuado para la plataforma del usuario cuando se ejecuta dotnet tool install o dnx.

Ejemplo: dotnet10-hybrid-tool

El dotnet10-hybrid-tool repositorio muestra este patrón de empaquetado híbrido con paquetes AOT nativos para osx-arm64, linux-arm64y linux-x64, además de un paquete de reserva coreCLR para el any RID (se usa, por ejemplo, en Windows cuando no hay ninguna compilación AOT disponible).

Puede instalar e probar la herramienta usted mismo:

dotnet tool install -g dotnet10-hybrid-tool
dotnet10-hybrid-tool

La herramienta informa de su descripción del marco de ejecución, el identificador en tiempo de ejecución (RID) y el modo de compilación (AOT nativo o CoreCLR).

Salida de ejemplo en una plataforma con AOT nativo:

Hi, I'm a 'DotNetCliTool v2' tool!
Yes, I'm quite fancy.

Version: .NET 10.0.2
RID: osx-arm64
Mode: Native AOT

Salida de ejemplo en una plataforma mediante el mecanismo de reserva de CoreCLR:

Hi, I'm a 'DotNetCliTool v2' tool!
Yes, I'm quite fancy.

Version: .NET 10.0.2
RID: win-x64
Mode: CoreCLR

Se convierte en una forma útil de experimentar con herramientas específicas de RID y compiladas con AOT y el comportamiento alternativo de CoreCLR.

Publicación de la herramienta

Al publicar paquetes de herramientas específicos de RID, la CLI de .NET usa el número de versión del paquete de nivel superior para seleccionar los paquetes específicos de RID coincidentes. Esto significa lo siguiente:

  • Todos los paquetes específicos de RID deben tener exactamente la misma versión que el paquete de nivel superior.
  • Todos los paquetes deben publicarse en el feed antes de que esté disponible el paquete de nivel superior.

Para garantizar un proceso de publicación sin problemas:

  1. Publique primero todos los paquetes específicos de RID:

    dotnet nuget push yourtool.win-x64.1.0.0.nupkg
    dotnet nuget push yourtool.linux-x64.1.0.0.nupkg
    dotnet nuget push yourtool.osx-arm64.1.0.0.nupkg
    dotnet nuget push yourtool.any.1.0.0.nupkg
    
  2. Publique el paquete de nivel superior por última vez:

    dotnet nuget push yourtool.1.0.0.nupkg
    

La publicación del paquete de nivel superior garantiza que todos los paquetes específicos de RID a los que se hace referencia estén disponibles cuando los usuarios instalen la herramienta. Si un usuario instala la herramienta antes de que se publiquen todos los paquetes rid, se producirá un error en la instalación.

Instalación y ejecución de herramientas

Si una herramienta usa el empaquetado específico de RID es un detalle de implementación transparente para los usuarios. Instale y ejecute herramientas de la misma manera, independientemente de si el desarrollador de herramientas optó por el empaquetado específico de RID.

Para instalar una herramienta globalmente:

dotnet tool install -g mytool

Una vez instalado, puede invocarlo directamente:

mytool

También puede usar el dnx asistente, que se comporta de forma similar a npx en el ecosistema de Node.js: descarga e inicia una herramienta en un solo gesto si aún no está presente:

dnx mytool

Cuando una herramienta usa el empaquetado específico de RID, la CLI de .NET selecciona automáticamente el paquete correcto para la plataforma. No es necesario especificar un RID: la CLI lo deduce del sistema y descarga el paquete específico del RID adecuado.

Consulte también