Condividi tramite


Creare strumenti specifici per RID, autonomi e AOT .NET

Questo articolo si applica a: ✔️ .NET SDK 10 e versioni successive

Creare un pacchetto di strumenti .NET per piattaforme e architetture specifiche in modo da poter distribuire applicazioni native, veloci e tagliate. Questa funzionalità semplifica la distribuzione di applicazioni ottimizzate per strumenti da riga di comando come server MCP o altre utilità specifiche della piattaforma.

Informazioni generali

A partire da .NET SDK 10, è possibile creare strumenti .NET destinati a ambienti specifici del sistema operativo (rappresentati da identificatori di runtime)). Questi strumenti possono essere:

  • Specifico del RID: compilato per sistemi operativi e architetture particolari.
  • Indipendente: includere il runtime .NET e non richiedere un'installazione .NET separata.
  • AOT nativo: usare la compilazione anticipata per velocizzare l'avvio e il footprint di memoria inferiore.

Gli utenti non notano una differenza quando installano lo strumento. L'interfaccia della riga di comando di .NET seleziona e installa automaticamente il pacchetto migliore per la piattaforma.

Acconsentire esplicitamente alla creazione di pacchetti specifici per RID

Per creare uno strumento specifico di RID, configurare il progetto con una delle proprietà MSBuild seguenti:

Proprietà RuntimeIdentifiers

Usare RuntimeIdentifiers per specificare le piattaforme supportate dallo strumento:

<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>

ToolPackageRuntimeIdentifiers - proprietà

In alternativa, usare ToolPackageRuntimeIdentifiers per la configurazione RID specifica dello strumento:

<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>

Usare un elenco delimitato da punto e virgola di valori RID. Per un elenco degli identificatori di runtime, vedere il catalogo RID.

Specificare una versione dipendente dal framework

Quando si opta per la creazione di pacchetti di strumenti specifici per RID, .NET SDK crea pacchetti autonomi per ogni RID specificato. Tuttavia, si perde il pacchetto dipendente dal framework predefinito che funziona su qualsiasi piattaforma con il runtime .NET installato.

Per fornire una versione dipendente dal framework insieme a pacchetti specifici di RID, aggiungere any all'elenco ToolPackageRuntimeIdentifiers :

<PropertyGroup>
  <PublishTrimmed>true</PublishTrimmed>
  <ToolPackageRuntimeIdentifiers>win-x64;osx-arm64;linux-x64;any</ToolPackageRuntimeIdentifiers>
</PropertyGroup>

Questa configurazione crea cinque pacchetti:

  • Un pacchetto puntatore di primo livello che elenca tutti i pacchetti secondari disponibili.
  • Tre pacchetti specifici di RID (win-x64, osx-arm64, linux-x64) che sono autonomi e tagliati.
  • Un pacchetto RID-indipendente (any) che dipende dal framework e richiede che il runtime .NET sia installato.

Quando gli utenti installano lo strumento:

  • Nei sistemi win-x64, osx-arm64 o linux-x64, i pacchetti autonomi ridotti vengono scaricati ed eseguiti.
  • In qualsiasi altro sistema operativo o architettura viene usato il pacchetto dipendente dal any framework.

Questo approccio fornisce file binari ottimizzati e autonomi per piattaforme comuni, mantenendo al tempo stesso la compatibilità con piattaforme meno comuni tramite il fallback dipendente dal framework.

Quando usare RuntimeIdentifiers vs ToolPackageRuntimeIdentifiers

Sia RuntimeIdentifiers sia ToolPackageRuntimeIdentifiers consentono allo strumento di essere incluso in un pacchetto specifico del RID, ma servono scopi leggermente diversi:

Usare RuntimeIdentifiers quando:

  • Si vuole che il progetto crei e pubblica app specifiche di RID in generale (non solo come strumento).
  • Si usa principalmente CoreCLR (non AOT) o si vuole il comportamento standard dell'SDK in cui un singolo dotnet pack produce più pacchetti specifici di RID.
  • È possibile condizionalizzare PublishAot per un subset di RID, ma si vuole comunque un pacchetto basato su CoreCLR per ogni RID in RuntimeIdentifiers.

Usare ToolPackageRuntimeIdentifiers quando:

  • Si vuole definire un comportamento specifico del RID solo per la creazione di pacchetti degli strumenti, senza modificare la modalità di compilazione del progetto per altri scenari di distribuzione.
  • Si usa Native AOT e si prevede di compilare manualmente file binari AOT per RID con dotnet pack -r <RID>.
  • Si desidera un modello ibrido in cui alcuni RID ottengono AOT nativo e altri eseguono un fallback su un'implementazione CoreCLR portabile.

Notes:

  • Il pacchetto del puntatore di primo livello specifica i pacchetti specifici di RID disponibili. Se si specifica ToolPackageRuntimeIdentifiers, determina i RID degli strumenti; in caso contrario, RuntimeIdentifiers viene usato .
  • ToolPackageRuntimeIdentifiers deve essere uguale o un sottoinsieme dei RID in RuntimeIdentifiers
  • Quando PublishAot=true, i pacchetti specifici di RID vengono generati solo quando si crea un pacchetto per un RID specifico, ad esempio dotnet pack -r linux-x64.
  • Le build AOT native (PublishAot=true) sono supportate solo quando il sistema operativo di compilazione e il sistema operativo di destinazione corrispondono.

Impacchetta il tuo strumento

Il processo di creazione dei pacchetti varia a seconda che si stia usando la compilazione AOT. Per compilare un pacchetto NuGet o un file con estensione nupkg dal progetto, eseguire il comando dotnet pack .

Strumenti specifici e autonomi per RID

Esegui dotnet pack una sola volta:

dotnet pack

Questo comando crea più pacchetti NuGet:

  • Un pacchetto per ogni RID: <packageName>.<RID>.<packageVersion>.nupkg
    • Esempio: mytool.win-x64.1.0.0.nupkg
    • Esempio: mytool.linux-x64.1.0.0.nupkg
    • Esempio: mytool.osx-arm64.1.0.0.nupkg
  • Un pacchetto puntatore agnostico RID: <packageName>.<packageVersion>.nupkg
    • Esempio: mytool.1.0.0.nupkg

Strumenti AOT

Per gli strumenti con compilazione AOT (<PublishAot>true</PublishAot>), è necessario comprimere separatamente per ogni piattaforma.

Requisiti della piattaforma per AOT nativo

La compilazione AOT nativa richiede che la parte del sistema operativo (OS) dell'SDK RID corrisponda al sistema operativo del RID di destinazione. L'SDK può eseguire la compilazione incrociata per architetture diverse ( ad esempio, da x64 a ARM64) ma non tra sistemi operativi (ad esempio, da Windows a Linux).

Ciò significa che sono disponibili diverse opzioni per la creazione di pacchetti AOT nativi:

  • Compila solo per il tuo computer di sviluppo: supporta Native AOT solo per il sistema operativo su cui stai sviluppando.
  • Usare i contenitori per le compilazioni Linux: se si usa macOS o Windows, usare i contenitori per la compilazione incrociata per Linux. Ad esempio, usare immagini mcr.microsoft.com/dotnet/sdk:10.0-noble-aot del contenitore.
  • Federare la compilazione tra diverse macchine: usare sistemi CI/CD come GitHub Actions o Azure DevOps Pipelines per compilare su diversi sistemi operativi.

Non è necessario creare tutti i pacchetti specifici di RID nello stesso computer o contemporaneamente. È sufficiente compilarli e pubblicarli prima di pubblicare il pacchetto di primo livello.

Imballaggio degli strumenti AOT nativi

Comprimere il pacchetto di primo livello una sola volta (in qualsiasi piattaforma):

dotnet pack

Pack per ogni RID specifico sulla piattaforma corrispondente, ad esempio:

dotnet pack -r linux-x64

È necessario eseguire ogni comando pack specifico del RID in una piattaforma in cui il sistema operativo corrisponde al sistema operativo del RID di destinazione. Per altre informazioni sui prerequisiti per la compilazione AOT nativa, vedere Distribuzione AOT nativa.

Quando si imposta PublishAot su true, il comportamento di compressione cambia.

  • dotnet pack Produce il pacchetto del puntatore di primo livello (tipo di DotnetToolpacchetto).
  • I pacchetti AOT specifici per RID vengono generati solo quando si passa in modo esplicito -r <RID>, ad esempio dotnet pack -r linux-x64 o dotnet pack -r osx-arm64.

Modello di creazione di pacchetti AOT e CoreCLR ibrido (esempio)

Alcuni strumenti vogliono il meglio di entrambi i mondi:

  • AOT nativo per un subset di piattaforme ad alta priorità (a seconda dello strumento).
  • Fallback CoreCLR portatile che funziona su piattaforme non destinate alle build AOT native.

È possibile ottenere questo modello "ibrido" con il modello seguente:

  1. Configurare lo strumento per AOT nativo e RID specifici degli strumenti.

    Nel file di progetto usare ToolPackageRuntimeIdentifiers e abilitare PublishAot.

    Per esempio:

    <ToolPackageRuntimeIdentifiers>osx-arm64;linux-arm64;linux-x64;any</ToolPackageRuntimeIdentifiers>
    <PublishAot>true</PublishAot>
    
  2. Creare il pacchetto del puntatore.

    Eseguire dotnet pack una sola volta (in qualsiasi piattaforma) per compilare il pacchetto di primo livello che punta ai pacchetti specifici di RID:

    dotnet pack
    
  3. Compilare pacchetti AOT nativi per i RID selezionati.

    La compilazione AOT nativa richiede la compilazione sulla piattaforma di destinazione. Compilare ogni pacchetto RID abilitato per AOT nella piattaforma corrispondente usando dotnet pack -r <RID>.

Per esempio:

dotnet pack -r linux-x64
  1. Creare un pacchetto di fallback CoreCLR.

    Per fornire un fallback universale, comprimere il any RID senza AOT:

    dotnet pack -r any -p:PublishAot=false
    

    Questo produce un pacchetto CoreCLR portabile (ad esempio, yourtool.any.<version>.nupkg) che può essere eseguito su piattaforme che non hanno una build AOT dedicata.

Annotazioni

È anche possibile usare le immagini del .NET SDK 10.0-noble-aot contenitore per compilare e creare pacchetti di strumenti AOT nativi linux da qualsiasi host che supporta contenitori Linux. Per esempio:

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

Ciò è utile quando il computer di sviluppo non esegue Linux in modo nativo.

In questa configurazione ibrida:

  • Il pacchetto puntatore (yourtool.<version>.nupkg) fa riferimento a entrambi:
    • Pacchetti nativi AOT specifici per RID (ad esempio, yourtool.osx-arm64, yourtool.linux-x64).
    • Il pacchetto any CoreCLR come fallback.
  • L'interfaccia della riga di comando di .NET seleziona automaticamente il pacchetto più appropriato per la piattaforma dell'utente quando esegue dotnet tool install o dnx.

Esempio: dotnet10-hybrid-tool

Il dotnet10-hybrid-tool repository illustra questo modello di creazione di pacchetti ibridi con pacchetti AOT nativi per osx-arm64, linux-arm64e linux-x64, oltre a un pacchetto di fallback CoreCLR per il any RID (usato, ad esempio, in Windows quando non è disponibile alcuna compilazione AOT).

È possibile installare e provare lo strumento manualmente:

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

Lo strumento segnala la descrizione del framework di runtime, l'identificatore di runtime (RID) e la modalità di compilazione (AOT nativo o CoreCLR).

Output di esempio in una piattaforma 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

Output di esempio in una piattaforma con il fallback CoreCLR:

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

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

In questo modo risulta utile sperimentare strumenti specifici per RID, compilati con AOT, e il comportamento di fallback di CoreCLR.

Pubblicare lo strumento

Quando si pubblicano pacchetti di strumenti specifici di RID, l'interfaccia della riga di comando di .NET usa il numero di versione del pacchetto di primo livello per selezionare i pacchetti specifici di RID corrispondenti. Ciò significa:

  • Tutti i pacchetti specifici di RID devono avere la stessa versione del pacchetto di primo livello.
  • Tutti i pacchetti devono essere pubblicati nel feed prima che il pacchetto di primo livello diventi disponibile.

Per garantire un processo di pubblicazione uniforme:

  1. Pubblicare prima tutti i pacchetti specifici di 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. Pubblicare il pacchetto di primo livello per ultimo:

    dotnet nuget push yourtool.1.0.0.nupkg
    

La pubblicazione del pacchetto di primo livello garantisce che tutti i pacchetti specifici di RID a cui si fa riferimento siano disponibili quando gli utenti installano lo strumento. Se un utente installa lo strumento prima della pubblicazione di tutti i pacchetti RID, l'installazione avrà esito negativo.

Installare ed eseguire strumenti

Se uno strumento usa pacchetti specifici di RID è un dettaglio di implementazione trasparente per gli utenti. Gli strumenti vengono installati ed eseguiti nello stesso modo, indipendentemente dal fatto che lo sviluppatore di strumenti abbia scelto la creazione di pacchetti specifici per RID.

Per installare uno strumento a livello globale:

dotnet tool install -g mytool

Una volta installato, è possibile richiamarlo direttamente:

mytool

È anche possibile usare l'helper dnx , che si comporta in modo analogo all'ecosistema npx di Node.js: scarica e avvia uno strumento in un singolo movimento, se non è già presente:

dnx mytool

Quando uno strumento usa pacchetti specifici di RID, l'interfaccia della riga di comando di .NET seleziona automaticamente il pacchetto corretto per la piattaforma. Non è necessario specificare un RID. L'interfaccia della riga di comando lo deduce dal sistema e scarica il pacchetto specifico del RID appropriato.

Vedere anche