Упаковка дистрибутивов .NET

Поскольку .NET 5 (и .NET Core) и более поздних версий становится доступным на все большем количестве платформ, полезно знать, как создавать пакеты, присваивать им имена и управлять их версиями. Таким образом издатели пакетов смогут обеспечить согласованную работу независимо от платформы, выбранной пользователями для запуска .NET. Эта статья пригодится пользователям, которые:

  • выполняют сборку .NET из исходного кода;
  • хотят внести в .NET CLI изменения, способные повлиять на итоговый макет или создаваемые пакеты.

Разметка диска

Установка .NET включает несколько компонентов, которые располагаются в файловой системе следующим образом:

{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} — это общий корневой каталог для всех основных и дополнительных версий .NET. Если установлены несколько сред выполнения, они совместно используют папку {dotnet_root} , например {dotnet_root}/shared/Microsoft.NETCore.App/6.0.11 и {dotnet_root}/shared/Microsoft.NETCore.App/7.0.0. Имя {dotnet_root} папки должно быть не зависит от версии, то есть dotnetпросто.

  • (1) dotnet: основное приложение (также называется "мультиплексором") выполняет две функции: активирует среду выполнения для запуска приложения и активирует пакет SDK для отправки в него команд. Основное приложение представляет собой исполняемый файл в машинном коде (dotnet.exe).

Хотя основное приложение одно, большинство остальных компонентов хранятся в каталогах версий (2, 3, 5, 6). Это значит, что в системе могут быть представлены сразу несколько версий, поскольку разные версии компонентов устанавливаются параллельно.

  • (2) версия узла/fxr/<fxr> содержит логику разрешения платформы, используемую узлом. Основное приложение использует новейшую установленную версию hostfxr. Hostfxr отвечает за выбор необходимой среды выполнения при запуске приложения .NET. Например, приложение, созданное для .NET 7.0.0,0, использует среду выполнения 7.0.5, когда она доступна. Аналогично hostfxr выбирает соответствующую версию SDK во время разработки.

  • (3) пакет SDK или< пакет SDK версии> пакета SDK (также известный как "инструментирование") — это набор управляемых средств, используемых для записи и сборки библиотек и приложений .NET. Пакет SDK содержит .NET CLI, компиляторы языков с управляемым кодом, MSBuild, а также соответствующие задачи и целевые объекты сборки, NuGet, новые шаблоны проектов и т. д.

  • (4) sdk-manifests/<sdk feature band версии> имен и версий ресурсов, необходимых для необязательной установки рабочей нагрузки, сохраняются в манифестах рабочей нагрузки, хранящихся в этой папке. Имя папки — это версия пакета SDK для группы компонентов. Поэтому для версии пакета SDK, например 7.0.102, эта папка по-прежнему будет называться 7.0.100. При установке рабочей нагрузки для ресурсов рабочей нагрузки создаются следующие папки: пакеты библиотек, метаданные и пакеты шаблонов. Распределение может создать пустой файл /metadata/workloads/<sdkfeatureband>/userlocal , если рабочие нагрузки должны быть установлены в пользовательском пути, а не в папке dotnet . Дополнительные сведения см. в статье GitHub issue dotnet/installer#12104.

Папка shared содержит платформы. Общая платформа предоставляет набор библиотек в центральном расположении таким образом, что они могут использоваться другими приложениями.

  • (5) shared/Microsoft.NETCore.App/<runtime version> This framework содержит среду выполнения .NET и вспомогательные управляемые библиотеки.

  • (6) shared/Microsoft.AspNetCore.{ Версия App,All}/<aspnetcore> содержит библиотеки ASP.NET Core. Библиотеки в каталоге Microsoft.AspNetCore.App разрабатываются и поддерживаются как часть проекта .NET. Библиотеки в каталоге Microsoft.AspNetCore.All представляют собой подмножество, которое также содержит сторонние библиотеки.

  • (7) Shared/Microsoft.Desktop.App/<desktop app versions> содержит классические библиотеки Windows. Не используется на платформах, отличных от Windows.

  • (8) LICENSE.txt,ThirdPartyNotices.txt — тексты лицензий .NET и лицензий библиотек сторонних производителей, используемых в .NET, соответственно.

  • (9, 10) dotnet.1.gz, dotnetdotnet.1.gz — это страница руководства по dotnet. dotnet представляет собой символическую ссылку на основное приложение dotnet (1). Эти файлы устанавливаются в типичные расположения для системной интеграции.

  • (11,12) Microsoft.NETCore.App.Ref,Microsoft.AspNetCore.App.Ref описывают API версии x.y .NET и ASP.NET соответственно. Эти пакеты используются при компиляции для этих целевых версий.

  • (13) Microsoft.NETCore.App.Host.<rid> содержит собственный двоичный файл для платформы rid. Этот двоичный файл представляет собой шаблон, используемый при компиляции приложения .NET в собственный двоичный файл для этой платформы.

  • (14) Microsoft.WindowsDesktop.App.Ref описывает API версии x.y для классических приложений Windows. Эти файлы используются при компиляции для этого целевого объекта. Не используется на платформах, отличных от Windows.

  • (15) NETStandard.Library.Ref описывает API x.y netstandard. Эти файлы используются при компиляции для этого целевого объекта.

  • (16) /etc/dotnet/install_location — это файл, содержащий полный путь для {dotnet_root}. Путь может заканчиваться новой строкой. Если корневым элементом является /usr/share/dotnet, добавлять этот файл не нужно.

  • (17) templates содержат шаблоны, используемые пакетом SDK. Например, dotnet new находит шаблоны проектов.

  • (18) Microsoft.NETCore.App.Runtime.<версия rid>/<runtime,Microsoft.AspNetCore.App.Runtime>.<Версия rid>/<aspnetcore> Эти файлы позволяют создавать автономные приложения. Эти каталоги содержат символьные ссылки на файлы (2), (5) и (6).

Папки, помеченные (*), используются несколькими пакетами. Для некоторых форматов пакетов (например, rpm) требуется специальная обработка таких папок. Этим должен заниматься специалист по обслуживанию пакетов.

Управление версиями .NET основано на номерах версий компонентов среды выполнения вида [major].[minor]. Версия пакета SDK использует тот же [major].[minor] и имеет независимый номер [patch], отражающий функцию и номер исправления для пакета SDK. Например, пакет SDK версии 7.0.302 является вторым выпуском исправлений для третьего выпуска пакета SDK, поддерживающего среду выполнения 7.0. Дополнительные сведения о принципах управления версиями см. в разделе Общие сведения об управлении версиями .NET.

Некоторые пакеты содержат часть номера версии в своем имени. Это позволяет устанавливать определенную версию. Остальная часть версии в имя версии не включается. Это позволяет диспетчеру пакетов операционной системы обновлять пакеты (например, автоматически устанавливать исправления безопасности). Поддерживаемые диспетчеры пакетов рассчитаны на Linux.

Далее перечислены рекомендуемые пакеты.

  • dotnet-sdk-[major].[minor] — устанавливает последний пакет SDK для определенной среды выполнения

    • Версия:<sdk>
    • Пример: dotnet-sdk-7.0
    • Содержит: (3),(4),(18)
    • Зависимости: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] — устанавливает конкретную среду выполнения ASP.NET Core

    • Версия:<aspnetcore runtime version>
    • Пример: aspnetcore-runtime-7.0
    • Содержит: (6)
    • Зависимостиdotnet-runtime-[major].[minor]:
  • dotnet-runtime-deps-[major].[minor](Необязательно) — устанавливает зависимости для запуска автономных приложений

    • Версия:<runtime>
    • Пример: dotnet-runtime-deps-7.0
    • Зависимости:зависимости, зависящие от распространения
  • dotnet-runtime-[major].[minor] — устанавливает конкретную среду выполнения

    • Версия:<runtime>
    • Пример: dotnet-runtime-7.0
    • Содержит: (5)
    • Зависимости:dotnet-hostfxr-[major].[minor], dotnet-runtime-deps-[major].[minor]
  • dotnet-hostfxr-[major].[minor] — зависимость

    • Версия:<runtime>
    • Пример: dotnet-hostfxr-7.0
    • Содержит: (2)
    • Зависимостиdotnet-host:
  • dotnet-host — зависимость

    • Версия:<runtime>
    • Пример: dotnet-host
    • Содержит: (1),(8),(9),(10),(16)
  • dotnet-apphost-pack-[major].[minor] — зависимость

    • Версия:<runtime>
    • Содержит: (13)
  • dotnet-targeting-pack-[major].[minor] — нацеливание на непоследнюю среду выполнения

    • Версия:<runtime>
    • Содержит: (12)
  • aspnetcore-targeting-pack-[major].[minor] — нацеливание на непоследнюю среду выполнения

    • Версия:<aspnetcore runtime version>
    • Содержит: (11)
  • netstandard-targeting-pack-[netstandard_major].[netstandard_minor] — нацеливание на версию netstandard

    • Версия:<sdk>
    • Содержит: (15)
  • dotnet-templates-[major].[minor]

    • Версия:<sdk>
    • Содержит: (17)

Следующие два метапакета являются необязательными. Они приносят значение конечным пользователям в том, что они абстрагируют пакет верхнего уровня (dotnet-sdk), что упрощает установку полного набора пакетов .NET. Эти метапакеты ссылались на определенную версию пакета SDK для .NET.

  • dotnet[major] — устанавливает указанную версию пакета SDK

    • Версия:<sdk>
    • Пример: dotnet7
    • Зависимостиdotnet-sdk-[major].[minor]:
  • dotnet — устанавливает определенную версию пакета SDK, определяемую дистрибутивами, основной версией— обычно последней доступной.

    • Версия:<sdk>
    • Пример: dotnet
    • Зависимостиdotnet-sdk-[major].[minor]:

Для использования dotnet-runtime-deps-[major].[minor] необходимо понимать зависимости для конкретных дистрибутивов. Так как система сборки дистрибутива может наследовать этот пакет автоматически, он является необязательным. В этом случае эти зависимости добавляются прямо в пакет dotnet-runtime-[major].[minor].

Если содержимое пакета находится в папке, которой присвоена версия, имя пакета [major].[minor] совпадает с именем этой папки. Для всех пакетов, кроме netstandard-targeting-pack-[netstandard_major].[netstandard_minor], также обязательно совпадение версий .NET.

Для зависимостей между пакетами должно действовать следующее применимое к версиям правило: больше или равно. Например, для dotnet-sdk-7.0:7.0.401 требуется aspnetcore-runtime-7.0 >= 7.0.6. В этом случае пользователь может обновить свою установку с помощью корневого пакета (например, dnf update dotnet-sdk-7.0).

Большинство дистрибутивов требуют построения из источника всех артефактов. Это определенным образом влияет на пакеты:

  • Сторонние библиотеки в каталоге shared/Microsoft.AspNetCore.All нельзя собрать из исходного хода. Поэтому эта папка исключена из пакета aspnetcore-runtime.

  • Папка NuGetFallbackFolder заполняется двоичными артефактами с сайта nuget.org. Она должна оставаться пустой.

Несколько пакетов dotnet-sdk могут предоставлять одни и те же файлы для каталога NuGetFallbackFolder. Чтобы не возникали проблемы с диспетчером пакетов, эти файлы (контрольная сумма, дата изменения и т. д.) должны быть идентичны.

Отладка пакетов

Содержимое отладки следует упаковать в отладочные пакеты с именем, которые следуют разделите пакет .NET, описанный ранее в этой статье. Например, содержимое dotnet-sdk-[major].[minor] отладки для пакета должно быть включено в пакет с именем dotnet-sdk-dbg-[major].[minor]. Необходимо установить отладочное содержимое в то же расположение, что и двоичные файлы.

Ниже приведены несколько двоичных примеров:

В каталоге {dotnet_root}/sdk/<sdk version> ожидаются следующие два файла:

  • dotnet.dll— установлен с пакетом dotnet-sdk-[major].[minor]
  • dotnet.pdb— установлен с пакетом dotnet-sdk-dbg-[major].[minor]

В каталоге {dotnet_root}/shared/Microsoft.NETCore.App/<runtime version> ожидаются следующие два файла:

  • System.Text.Json.dll— установлен с пакетом dotnet-runtime-[major].[minor]
  • System.Text.Json.pdb— установлен с пакетом dotnet-runtime-dbg-[major].[minor]

В каталоге {dotnet_root/shared/Microsoft.AspNetCore.App/<aspnetcore version> ожидаются следующие два файла:

  • Microsoft.AspNetCore.Routing.dll— установлен с пакетами aspnetcore-runtime-[major].[minor]
  • Microsoft.AspNetCore.Routing.pdb— установлен с пакетами aspnetcore-runtime-dbg-[major].[minor]

Начиная с .NET 8.0, все файлы отладки .NET (PDB), созданные в исходной сборке, доступны в tarball с именем dotnet-symbols-sdk-<version>-<rid>.tar.gz. Этот архив содержит PDF-файлы в подкаталогах, которые соответствуют структуре каталогов тарбола dotnet-sdk-<version>-<rid>.tar.gzпакета SDK для .NET.

Хотя все содержимое отладки доступно в отладочном tarball, не все отладочное содержимое равно важно. Конечные пользователи в основном заинтересованы в содержимом shared/Microsoft.AspNetCore.App/<aspnetcore version> каталогов и shared/Microsoft.NETCore.App/<runtime version> каталогов.

Содержимое sdk/<sdk version> пакета SDK полезно для отладки наборов инструментов пакета SDK для .NET.

Ниже перечислены рекомендуемые пакеты отладки:

  • aspnetcore-runtime-dbg-[major].[minor] — устанавливает отладочное содержимое для определенной среды выполнения ASP.NET Core

    • Версия:<aspnetcore runtime version>
    • Пример: aspnetcore-runtime-dbg-8.0
    • Содержит: отладочное содержимое для (6)
    • Зависимостиaspnetcore-runtime-[major].[minor]:
  • dotnet-runtime-dbg-[major].[minor] — устанавливает отладочное содержимое для определенной среды выполнения

    • Версия:<runtime>
    • Пример: dotnet-runtime-dbg-8.0
    • Содержит: отладочное содержимое для (5)
    • Зависимостиdotnet-runtime-[major].[minor]:

Следующий пакет отладки необязателен:

  • dotnet-sdk-dbg-[major].[minor] — устанавливает отладочное содержимое для определенной версии пакета SDK
    • Версия:<sdk>
    • Пример: dotnet-sdk-dbg-8.0
    • Содержит: отладочное содержимое для (3),(4),(18)
    • Зависимостиdotnet-sdk-[major].[minor]:

Отладочный tarball также содержит некоторое отладочное содержимое в разделе packs, представляющее копии содержимого в разделе shared. В макете packs .NET каталог используется для создания приложений .NET. Нет сценариев отладки, поэтому не следует упаковать содержимое packs отладки в отладочном tarball.

Построение пакетов

Репозиторий dotnet/source-build содержит инструкции по созданию архива TAR с исходным кодом пакета SDK для .NET и всех его компонентов. Выход репозитория, построенного из источника, соответствует виду, описанному в первом разделе этой статьи.