Pacote de distribuição do .NET

À medida que o .NET 5 (e o .NET Core) e versões posteriores ficam disponíveis em cada vez mais plataformas, é útil saber como empacotar, nomear e controlar a versão dos aplicativos e das bibliotecas que o usam. Dessa forma, os mantenedores do pacote podem ajudar a garantir uma experiência consistente, independentemente de onde os usuários escolhem executar o .NET. Este artigo é útil para usuários que estão:

  • Tentando criar o .NET com base na origem.
  • Querendo fazer alterações nas CLI do .NET que poderiam afetar o layout resultante ou os pacotes produzidos.

Layout de disco

Quando instalado, o .NET consiste em vários componentes que são dispostos da seguinte maneira no sistema de arquivos:

{dotnet_root}                    (0)              (*)
├── dotnet                       (1)
├── LICENSE.txt                  (8)
├── ThirdPartyNotices.txt        (8)
├── host                                          (*)
│   └── fxr                                       (*)
│       └── <fxr version>        (2)
├── sdk                                           (*)
│   └── <sdk version>            (3)
├── sdk-manifests                (4)              (*)
│   └── <sdk feature band version>
├── library-packs                (4)              (*)
├── metadata                     (4)              (*)
│   └── workloads
│       └── <sdk feature band version>
├── template-packs               (4)              (*)
├── packs                                         (*)
│   ├── Microsoft.AspNetCore.App.Ref              (*)
│   │   └── <aspnetcore ref version>     (11)
│   ├── Microsoft.NETCore.App.Ref                 (*)
│   │   └── <netcore ref version>        (12)
│   ├── Microsoft.NETCore.App.Host.<rid>          (*)
│   │   └── <apphost version>            (13)
│   ├── Microsoft.WindowsDesktop.App.Ref          (*)
│   │   └── <desktop ref version>        (14)
│   ├── NETStandard.Library.Ref                   (*)
│   │   └── <netstandard version>        (15)
│   ├── Microsoft.NETCore.App.Runtime.<rid>       (*)
│   │   └── <runtime version>            (18)
│   └── Microsoft.AspNetCore.App.Runtime.<rid>    (*)
│       └── <aspnetcore version>         (18)
├── shared                                        (*)
│   ├── Microsoft.NETCore.App                     (*)
│   │   └── <runtime version>     (5)
│   ├── Microsoft.AspNetCore.App                  (*)
│   │   └── <aspnetcore version>  (6)
│   ├── Microsoft.AspNetCore.All                  (*)
│   │   └── <aspnetcore version>  (6)
│   └── Microsoft.WindowsDesktop.App              (*)
│       └── <desktop app version> (7)
└── templates                                     (*)
│   └── <templates version>      (17)
/
├── etc/dotnet
│       └── install_location     (16)
├── usr/share/man/man1
│       └── dotnet.1.gz          (9)
└── usr/bin
        └── dotnet               (10)
  • (0) {dotnet_root} é uma raiz compartilhada para todas as versões principais e secundárias do .NET. Se vários runtimes forem instalados, eles compartilharão a pasta {dotnet_root}, por exemplo, {dotnet_root}/shared/Microsoft.NETCore.App/6.0.11 e {dotnet_root}/shared/Microsoft.NETCore.App/7.0.0. O nome da pasta {dotnet_root} deve ser independente da versão, ou seja, simplesmente dotnet.

  • (1) dotnet O host (também conhecido como o "muxer") tem duas funções distintas: ativar um runtime para iniciar um aplicativo e ativar um SDK para enviar comandos a ele. O host é um executável nativo (dotnet.exe).

Embora haja um único host, a maioria dos outros componentes está em diretórios com controle de versão (2,3,5,6). Isso significa que várias versões podem estar presentes no sistema, pois são instaladas lado a lado.

  • (2) O host/fxr/<fxr version> contém a lógica de resolução do framework usada pelo host. O host usa o hostfxr mais recente instalado. O hostfxr é responsável por selecionar o runtime apropriado ao executar um aplicativo .NET. Por exemplo, um aplicativo criado para o .NET 7.0.0 usa o runtime 7.0.5 quando ele está disponível. Da mesma forma, o hostfxr seleciona o SDK adequado durante o desenvolvimento.

  • (3) sdk/<sdk version> O SDK (também conhecido como "as ferramentas") é um conjunto de ferramentas gerenciadas, usado para gravar e compilar aplicativos e bibliotecas do .NET. O SDK inclui a CLI do .NET, os compiladores de linguagens gerenciadas, o MSBuild e as tarefas e os destinos de compilação associados, o NuGet, novos modelos de projeto e assim por diante.

  • (4) sdk-manifests/<sdk feature band version> Os nomes e as versões dos ativos exigidos por uma instalação de carga de trabalho opcional são mantidos nos manifestos de carga de trabalho armazenados nesta pasta. O nome da pasta é a versão da banda de recursos do SDK. Portanto, para uma versão do SDK como 7.0.102, essa pasta ainda seria nomeada como 7.0.100. Quando uma carga de trabalho é instalada, as seguintes pastas são criadas conforme necessário para os ativos da carga de trabalho: pacotes de biblioteca, metadados e pacotes de modelo. Uma distribuição pode criar um arquivo /metadata/workloads/<sdkfeatureband>/userlocal, caso as cargas de trabalho devam ser instaladas em um caminho de usuário e não na pasta dotnet. Para obter mais informações, confira o problema do GitHub dotnet/docs #12104.

A pasta compartilhada contém estruturas. Uma estrutura compartilhada fornece um conjunto de bibliotecas em um local central para que elas possam ser usadas por aplicativos diferentes.

  • (5) shared/Microsoft.NETCore.App/<runtime version> Essa estrutura contém o runtime do .NET Core e as respectivas bibliotecas gerenciadas compatíveis.

  • (6) shared/Microsoft.AspNetCore.{App,All}/<aspnetcore version> contém as bibliotecas do ASP.NET Core. As bibliotecas em Microsoft.AspNetCore.App são desenvolvidas e têm suporte como parte do projeto .NET. As bibliotecas em Microsoft.AspNetCore.All são um superconjunto que também contém bibliotecas de terceiros.

  • (7) shared/Microsoft.Desktop.App/<desktop app version> contém as bibliotecas da área de trabalho do Windows. Isso não está incluído nas plataformas que não são do Windows.

  • (8) LICENSE.txt,ThirdPartyNotices.txt correspondem à licença do .NET e às licenças de bibliotecas de terceiros usadas no .NET, respectivamente.

  • (9,10) dotnet.1.gz, dotnetdotnet.1.gz é a página de manual do dotnet. dotnet é um symlink ao host(1) dotnet. Esses arquivos são instalados em locais bem conhecidos para a integração do sistema.

  • (11,12) Microsoft.NETCore.App.Ref,Microsoft.AspNetCore.App.Ref descrevem a API de uma versão x.y do .NET e do ASP.NET Core, respectivamente. Esses pacotes são usados ao compilar essas versões de destino.

  • (13) Microsoft.NETCore.App.Host.<rid> contém um binário nativo para a plataforma rid. Esse binário é um modelo ao compilar um aplicativo .NET em um binário nativo para essa plataforma.

  • (14) Microsoft.WindowsDesktop.App.Ref descreve a API da versão x.y dos aplicativos da Área de Trabalho do Windows. Esses arquivos são usados ao compilar para esse destino. Isso não está incluído nas plataformas que não são do Windows.

  • (15) NETStandard.Library.Ref descreve a API x.y do netstandard. Esses arquivos são usados ao compilar para esse destino.

  • (16) /etc/dotnet/install_location é um arquivo que contém o caminho completo para {dotnet_root}. O caminho pode terminar com uma nova linha. Não será necessário adicionar esse arquivo quando a raiz for /usr/share/dotnet.

  • (17) Os modelos contêm os modelos usados pelo SDK. Por exemplo, dotnet new localiza os modelos de projeto aqui.

  • (18) Microsoft.NETCore.App.Runtime.<rid>/<runtime version>,Microsoft.AspNetCore.App.Runtime.<rid>/<aspnetcore version> Esses arquivos permitem a criação de aplicativos autocontidos. Esses diretórios contêm links simbólicos para arquivos em (2), (5) e (6).

As pastas marcadas com (*) são usadas por vários pacotes. Alguns formatos de pacote (por exemplo, rpm) exigem o tratamento especial dessas pastas. O responsável pelos pacotes deve cuidar disso.

O controle de versão do .NET é baseado nos números de versão [major].[minor] do componente de runtime. A versão do SDK usa o mesmo [major].[minor] e tem um [patch] independente que combina as semânticas de recurso e de patch para o SDK. Por exemplo: o SDK versão 7.0.302 é a segunda versão de patch da terceira versão do recurso do SDK que dá suporte ao runtime 7.0. Para obter mais informações sobre como o controle de versão funciona, confira Visão geral do controle de versão do .NET.

Alguns pacotes incluem parte do número de versão no nome deles. Isso permite que você instale uma versão específica. O restante da versão não está incluído no nome da versão. Isso permite ao gerenciador de pacotes de SO atualize os pacotes (por exemplo, instalando automaticamente correções de segurança). Gerenciadores de pacotes com suporte são específicos do Linux.

Veja a seguir uma lista de pacotes recomendados:

  • dotnet-sdk-[major].[minor] – Instala o SDK mais recente do runtime específico

    • Versão:< versão do SDK>
    • Exemplo: dotnet-sdk-7.0
    • Contém: (3), (4), (18)
    • Dependências:dotnet-runtime-[major].[minor], aspnetcore-runtime-[major].[minor], dotnet-targeting-pack-[major].[minor], aspnetcore-targeting-pack-[major].[minor], netstandard-targeting-pack-[netstandard_major].[netstandard_minor], dotnet-apphost-pack-[major].[minor], dotnet-templates-[major].[minor]
  • aspnetcore-runtime-[major].[minor] – Instala um runtime do ASP.NET Core específico

    • Versão:< versão de runtime do aspnetcore>
    • Exemplo: aspnetcore-runtime-7.0
    • Contém: (6)
    • Dependências:dotnet-runtime-[major].[minor]
  • dotnet-runtime-deps-[major].[minor](Opcional) – instala as dependências para executar aplicativos autônomos

    • Versão:< versão de runtime>
    • Exemplo: dotnet-runtime-deps-7.0
    • Dependências:dependências específicas da distribuição
  • dotnet-runtime-[major].[minor] – Instala um runtime específico

    • Versão:< versão de runtime>
    • Exemplo: dotnet-runtime-7.0
    • Contém: (5)
    • Dependências:dotnet-hostfxr-[major].[minor], dotnet-runtime-deps-[major].[minor]
  • dotnet-hostfxr-[major].[minor] – dependência

    • Versão:< versão de runtime>
    • Exemplo: dotnet-hostfxr-7.0
    • Contém: (2)
    • Dependências:dotnet-host
  • dotnet-host – dependência

    • Versão:< versão de runtime>
    • Exemplo: dotnet-host
    • Contém: (1),(8),(9),(10),(16)
  • dotnet-apphost-pack-[major].[minor] – dependência

    • Versão:< versão de runtime>
    • Contém: (13)
  • dotnet-targeting-pack-[major].[minor] – Permite direcionar um runtime que não é o mais recente

    • Versão:< versão de runtime>
    • Contém: (12)
  • aspnetcore-targeting-pack-[major].[minor] – Permite direcionar um runtime que não é o mais recente

    • Versão:< versão de runtime do aspnetcore>
    • Contém: (11)
  • netstandard-targeting-pack-[netstandard_major].[netstandard_minor] – Permite direcionar uma versão do netstandard

    • Versão:< versão do SDK>
    • Contém: (15)
  • dotnet-templates-[major].[minor]

    • Versão:< versão do SDK>
    • Contém: (17)

Os dois metapacotes a seguir são opcionais. Eles agregam valor para os usuários finais, pois abstraem o pacote de nível superior (dotnet-sdk), o que simplifica a instalação do conjunto completo de pacotes .NET. Esses metapacotes fazem referência a uma versão específica do SDK do .NET.

  • dotnet[major] – Instala a versão especificada do SDK

    • Versão:< versão do SDK>
    • Exemplo: dotnet7
    • Dependências:dotnet-sdk-[major].[minor]
  • dotnet – Instala uma versão específica do SDK determinada por distribuições como a versão primária, geralmente a mais recente disponível

    • Versão:< versão do SDK>
    • Exemplo: dotnet
    • Dependências:dotnet-sdk-[major].[minor]

O dotnet-runtime-deps-[major].[minor] exige a compreensão das dependências específicas da distribuição. Como o sistema de compilação de distribuição pode calcular isso automaticamente, o pacote é opcional. Nesse caso, essas dependências são adicionadas diretamente ao pacote dotnet-runtime-[major].[minor].

Quando o conteúdo do pacote está em uma pasta com controle de versão, o nome do pacote [major].[minor] corresponde ao nome da pasta com controle de versão. Para todos os pacotes, exceto o netstandard-targeting-pack-[netstandard_major].[netstandard_minor], isso também corresponde à versão do .NET.

As dependências entre pacotes devem seguir um requisito de versão de igual ou maior que. Por exemplo, o dotnet-sdk-7.0:7.0.401 requer aspnetcore-runtime-7.0 >= 7.0.6. Isso possibilita que o usuário atualize a instalação por meio de um pacote raiz (por exemplo, dnf update dotnet-sdk-7.0).

A maioria das distribuições exigem que todos os artefatos sejam compilados da origem. Isso tem algum impacto nos pacotes:

  • As bibliotecas de terceiros em shared/Microsoft.AspNetCore.All não podem ser criadas facilmente usando o código-fonte. Portanto, essa pasta é omitida do pacote aspnetcore-runtime.

  • O NuGetFallbackFolder é populado usando os artefatos binários de nuget.org. Ele deve permanecer vazio.

Vários pacotes dotnet-sdk podem fornecer os mesmos arquivos para o NuGetFallbackFolder. Para evitar problemas com o gerenciador de pacotes, esses arquivos devem ser idênticos (soma de verificação, data de modificação e assim por diante).

Pacotes de depuração

O conteúdo de depuração deve ser empacotado em pacotes nomeados por depuração que seguem a divisão de pacotes .NET descrita anteriormente neste artigo. Por exemplo, o conteúdo de depuração do pacote dotnet-sdk-[major].[minor] deve ser incluído em um pacote chamado dotnet-sdk-dbg-[major].[minor]. Você deve instalar o conteúdo de depuração no mesmo local que os binários.

Aqui estão alguns exemplos binários:

No diretório {dotnet_root}/sdk/<sdk version>, são esperados os dois arquivos a seguir:

  • dotnet.dll - instalado com dotnet-sdk-[major].[minor] pacote
  • dotnet.pdb - instalado com dotnet-sdk-dbg-[major].[minor] pacote

No diretório {dotnet_root}/shared/Microsoft.NETCore.App/<runtime version>, são esperados os dois arquivos a seguir:

  • System.Text.Json.dll - instalado com dotnet-runtime-[major].[minor] pacote
  • System.Text.Json.pdb - instalado com dotnet-runtime-dbg-[major].[minor] pacote

No diretório {dotnet_root/shared/Microsoft.AspNetCore.App/<aspnetcore version>, são esperados os dois arquivos a seguir:

  • Microsoft.AspNetCore.Routing.dll - instalado com aspnetcore-runtime-[major].[minor] pacotes
  • Microsoft.AspNetCore.Routing.pdb - instalado com aspnetcore-runtime-dbg-[major].[minor] pacotes

Iniciando com o .NET 8.0, todo o conteúdo de depuração do .NET (arquivos PDB), produzido pela criação da origem, está disponível em um tarball chamado dotnet-symbols-sdk-<version>-<rid>.tar.gz. Esse arquivo contém PDBs em subdiretórios que correspondem à estrutura de diretórios do tarball do SDK do .NET – dotnet-sdk-<version>-<rid>.tar.gz.

Embora todo o conteúdo de depuração esteja disponível no tarball de depuração, nem todo o conteúdo de depuração é igualmente importante. Os usuários finais estão mais interessados no conteúdo dos diretórios shared/Microsoft.AspNetCore.App/<aspnetcore version> e shared/Microsoft.NETCore.App/<runtime version>.

O conteúdo do SDK em sdk/<sdk version> é útil para depurar os conjuntos de ferramentas do SDK do .NET.

Os pacotes a seguir são os pacotes de depuração recomendados:

  • aspnetcore-runtime-dbg-[major].[minor]: instala o conteúdo de depuração para um runtime específico do ASP.NET Core

    • Versão:< versão de runtime do aspnetcore>
    • Exemplo: aspnetcore-runtime-dbg-8.0
    • Contém: o conteúdo de depuração para (6)
    • Dependências:aspnetcore-runtime-[major].[minor]
  • dotnet-runtime-dbg-[major].[minor]: instala o conteúdo de depuração para um runtime específico

    • Versão:< versão de runtime>
    • Exemplo: dotnet-runtime-dbg-8.0
    • Contém: o conteúdo de depuração para (5)
    • Dependências:dotnet-runtime-[major].[minor]

O pacote de depuração a seguir é opcional:

  • dotnet-sdk-dbg-[major].[minor]: instala o conteúdo de depuração para uma versão específica do SDK
    • Versão:< versão do SDK>
    • Exemplo: dotnet-sdk-dbg-8.0
    • Contém: o conteúdo de depuração para (3),(4),(18)
    • Dependências:dotnet-sdk-[major].[minor]

O tarball de depuração também contém algum conteúdo de depuração em packs, que representa cópias do conteúdo em shared. No layout .NET, o diretório packs é usado para criação de aplicativos .NET. Não existem cenários de depuração, portanto, você não deve empacotar o conteúdo de depuração em packs no tarball de depuração.

Compilando pacotes

O repositório dotnet/source-build fornece instruções sobre como compilar um tarball de origem do SDK do .NET e todos os seus componentes. A saída do repositório de build de origem corresponde o layout descrito na primeira seção deste artigo.