Packen einer Verteilung von .NET

Da .NET 5 (und .NET Core) und höhere Versionen auf mehr und mehr Plattformen verfügbar sind, ist es hilfreich zu erfahren, wie Sie Anwendungen und Bibliotheken, die diese verwenden, packen, benennen und mit einer Versionsnummer versehen. Auf diese Weise kann mithilfe von Paketverwaltern eine konsistente Benutzererfahrung sichergestellt werden, unabhängig davon, wo Benutzer .NET ausführen. Dieser Artikel ist für Benutzer hilfreich, die

  • versuchen, .NET von der Quelle aus zu erstellen.
  • Änderungen an der .NET-CLI vornehmen möchten, die sich auf das resultierende Layout oder die erzeugten Pakete auswirken könnten.

Datenträgerlayout

.NET besteht aus mehreren Komponenten, die im Dateisystem folgendermaßen angeordnet sind:

{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} ist ein gemeinsam genutzter Stamm für alle Haupt- und Nebenversionen von .NET. Wenn mehrere Runtimes installiert sind, nutzen sie den {dotnet_root}-Ordner gemeinsam, z. B. {dotnet_root}/shared/Microsoft.NETCore.App/6.0.11 und {dotnet_root}/shared/Microsoft.NETCore.App/7.0.0. Der Name des {dotnet_root}-Ordners sollte versionsunabhängig sein, also einfach dotnet lauten.

  • (1) dotnet: Der Host (auch bekannt als „Muxer“) führt zwei unterschiedliche Rollen aus: das Aktivieren einer Runtime, um eine Anwendung zu starten, und das Aktivieren eines SDK, um Befehle an dieses weiterzuleiten. Der Host ist eine native ausführbare Datei (dotnet.exe).

Es gibt nur einen Host, die meisten anderen Komponenten befinden sich jedoch in Verzeichnissen mit Versionsangabe (2, 3, 5, 6). Das bedeutet, dass auf dem System mehrere Versionen vorhanden sein können, da sie nebeneinander installiert werden können.

  • (2) host/fxr/<fxr version> enthält die vom Host verwendete Framework-Auflösungslogik. Der Host verwendet die neueste installierte hostfxr-Version. „hostfxr“ ist für die Auswahl der geeigneten Runtime beim Ausführen einer .NET-Anwendung zuständig. Eine Anwendung, die für .NET 7.0.0 erstellt wurde, verwendet beispielsweise die Runtime 7.0.5, wenn sie verfügbar ist. Ebenso wählt „hostfxr“ während der Entwicklung das geeignete SDK aus.

  • (3) sdk/<sdk version>: Das SDK (auch bekannt als „die Tools“) ist ein Satz verwalteter Tools, die zum Schreiben und Erstellen von .NET-Bibliotheken und -Anwendungen verwendet werden. Das SDK enthält die .NET-CLI, die verwalteten Sprachcompiler, MSBuild und zugehörige Buildtasks und -ziele, NuGet, neue Projektvorlagen usw.

  • (4) sdk-manifests/<sdk feature band version>: Die Namen und Versionen der Ressourcen, die für eine optionale Workloadinstallation erforderlich sind, werden in Workloadmanifesten verwaltet, die in diesem Ordner gespeichert sind. Der Ordnername ist die Featurebandversion des SDK. Für eine SDK-Version wie 7.0.102 würde dieser Ordner also weiterhin 7.0.100 heißen. Beim Installieren einer Workload werden nach Bedarf die folgenden Ordner für die Ressourcen der Workload erstellt: library-packs, metadata und template-packs. Eine Distribution kann eine leere /metadata/workloads/<sdkfeatureband>/userlocal-Datei erstellen, wenn die Workloads statt im dotnet-Ordner in einem Benutzerpfad installiert werden sollen. Weitere Informationen finden Sie im GitHub-Issue dotnet/installer#12104.

Der Ordner shared enthält Frameworks. Ein gemeinsames (shared) Framework stellt einen Satz Bibliotheken an einem zentralen Speicherort bereit, sodass diese von verschiedenen Anwendungen verwendet werden können.

  • (5) shared/Microsoft.NETCore.App/<runtime version>: Dieses Framework enthält die .NET-Runtime und die unterstützenden verwalteten Bibliotheken.

  • (6) shared/Microsoft.AspNetCore.{App,All}/<aspnetcore version> enthält die ASP.NET Core-Bibliotheken. Die Bibliotheken unter Microsoft.AspNetCore.App werden im Rahmen des .NET-Projekts entwickelt und unterstützt. Die Bibliotheken unter Microsoft.AspNetCore.All sind ein übergeordnetes Set, das auch Drittanbieterbibliotheken enthält.

  • (7) shared/Microsoft.Desktop.App/<desktop app version> enthält die Windows-Desktopbibliotheken. Dies ist nur in Windows enthalten, und nicht in anderen Plattformen.

  • (8) LICENSE.txt,ThirdPartyNotices.txt: Dies sind die .NET-Lizenzen und die Lizenzen von Drittanbieterbibliotheken, die in .NET verwendet werden.

  • (9, 10) dotnet.1.gz, dotnet: dotnet.1.gz ist die Dotnet-Handbuchseite. dotnet ist eine symbolische Verknüpfung mit dem Dotnet-Host (1). Diese Dateien werden zur Systemintegration an bekannten Speicherorten installiert.

  • (11,12) Microsoft.NETCore.App.Ref,Microsoft.AspNetCore.App.Ref beschreibt jeweils die API einer x.y-Version von .NET und ASP.NET Core. Diese Pakete werden bei der Kompilierung für diese Zielversionen verwendet.

  • (13) Microsoft.NETCore.App.Host.<rid> enthält eine native Binärdatei für die Plattform rid. Diese Binärdatei ist eine Vorlage für das Kompilieren einer .NET-Anwendung in eine native Binärdatei für diese Plattform.

  • (14) Microsoft.WindowsDesktop.App.Ref beschreibt die API der x.y-Version von Windows-Desktopanwendungen. Diese Dateien werden beim Kompilieren für dieses Ziel verwendet. Dies wird nur unter Windows bereitgestellt, und nicht für andere Plattformen.

  • (15) NETStandard.Library.Ref beschreibt die NetStandard-API x.y. Diese Dateien werden beim Kompilieren für dieses Ziel verwendet.

  • (16) /etc/dotnet/install_location ist eine Datei, die den vollständigen Pfad für {dotnet_root} enthält. Der Pfad kann mit einem Zeilenvorschubzeichen enden. Es ist nicht erforderlich, diese Datei hinzuzufügen, wenn /usr/share/dotnet das Stammverzeichnis ist.

  • (17) templates enthält die Vorlagen, die vom SDK verwendet werden. Beispielsweise ermittelt dotnet new Projektvorlagen in diesem Ordner.

  • (18) Microsoft.NETCore.App.Runtime.<rid>/<runtime version,Microsoft.AspNetCore.App.Runtime>.<rid>/<aspnetcore Version> Diese Dateien ermöglichen das Erstellen eigenständiger Anwendungen. Diese Verzeichnisse enthalten symbolische Verknüpfungen zu Dateien in (2), (5) und (6).

Die mit (*) markierten Ordner werden von mehreren Paketen verwendet. Einige Paketformate (z.B. rpm) erfordern eine besondere Verarbeitung solcher Ordner. Der Paketmaintainer muss dafür Sorge tragen.

Die .NET-Versionsverwaltung basiert auf dem Versionsnummernmuster [major].[minor] der Runtimekomponente. Die SDK-Version verwendet das gleiche [major].[minor]-Muster und weist eine unabhängige [patch]-Zeichenfolge auf, die die Feature- und Patchsemantik für das SDK kombiniert. Beispiel: Die SDK-Version 7.0.302 ist das zweite Patchrelease des dritten Featurerelease des SDK, das die Runtimeversion 7.0 unterstützt. Weitere Informationen zur Funktionsweise der Versionsverwaltung finden Sie unter .NET-Versionskontrolle: Übersicht.

Einige Pakete enthalten einen Teil der Versionsnummer im Namen. Dies ermöglicht Ihnen, eine bestimmte Version zu installieren. Der Rest der Version ist im Versionsnamen nicht enthalten. Dies ermöglicht dem Paket-Manager des Betriebssystems, die Pakete zu aktualisieren (z.B. durch automatisches Installieren von Sicherheitsfixes). Unterstützte Paket-Manager sind Linux-spezifisch.

Im Folgenden werden die empfohlenen Pakete aufgeführt:

  • dotnet-sdk-[major].[minor]: installiert das neueste SDK für eine spezifische Runtime.

    • Version: <sdk version>
    • Beispiel: dotnet-sdk-7.0
    • Enthält: (3),(4),(18)
    • Abhängigkeiten: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]: installiert eine spezifische ASP.NET Core-Runtime.

    • Version: <aspnetcore runtimeversion>
    • Beispiel: aspnetcore-runtime-7.0
    • Enthält: (6)
    • Abhängigkeiten:dotnet-runtime-[major].[minor]
  • dotnet-runtime-deps-[major].[minor](Optional): installiert die Abhängigkeiten zum Ausführen eigenständiger Anwendungen.

    • Version: <runtimeversion>
    • Beispiel: dotnet-runtime-deps-7.0
    • Abhängigkeiten:Verteilungsspezifische Abhängigkeiten
  • dotnet-runtime-[major].[minor]: installiert eine spezifische Runtime

    • Version: <runtimeversion>
    • Beispiel: dotnet-runtime-7.0
    • Enthält: (5)
    • Abhängigkeiten:dotnet-hostfxr-[major].[minor], dotnet-runtime-deps-[major].[minor]
  • dotnet-hostfxr-[major].[minor]: Abhängigkeit

    • Version: <runtimeversion>
    • Beispiel: dotnet-hostfxr-7.0
    • Enthält: (2)
    • Abhängigkeiten:dotnet-host
  • dotnet-host: Abhängigkeit

    • Version: <runtimeversion>
    • Beispiel: dotnet-host
    • Enthält: (1),(8),(9),(10),(16)
  • dotnet-apphost-pack-[major].[minor]: Abhängigkeit

    • Version: <runtimeversion>
    • Enthält: (13)
  • dotnet-targeting-pack-[major].[minor]: ermöglicht eine ältere Runtime als Ziel.

    • Version: <runtimeversion>
    • Enthält: (12)
  • aspnetcore-targeting-pack-[major].[minor]: ermöglicht eine ältere Runtime als Ziel.

    • Version: <aspnetcore runtimeversion>
    • Enthält: (11)
  • netstandard-targeting-pack-[netstandard_major].[netstandard_minor]: ermöglicht eine NetStandard-Zielversion

    • Version: <sdk version>
    • Enthält: (15)
  • dotnet-templates-[major].[minor]

    • Version: <sdk version>
    • Enthält: (17)

Die folgenden beiden Metapakete sind optional. Sie sind hilfreich für Endbenutzer, da sie das Paket der obersten Ebene (dotnet-sdk) abstrahieren, wodurch die Installation des vollständigen Satzes an .NET-Paketen vereinfacht wird. Diese Metapakete verweisen auf eine bestimmte .NET SDK-Version.

  • dotnet[major]: Installiert die angegebene SDK-Version.

    • Version: <sdk version>
    • Beispiel: dotnet7
    • Abhängigkeiten:dotnet-sdk-[major].[minor]
  • dotnet: Installiert eine bestimmte SDK-Version, die von den Distributionen als primäre Version festgelegt wird – dies ist in der Regel die neueste verfügbare Version.

    • Version: <sdk version>
    • Beispiel: dotnet
    • Abhängigkeiten:dotnet-sdk-[major].[minor]

Für dotnet-runtime-deps-[major].[minor] ist ein Verständnis der distributionsspezifischen Abhängigkeiten erforderlich. Da das Buildsystem der Verteilung dies möglicherweise automatisch ableiten kann, ist das Paket optional. In diesem Falle werden diese Abhängigkeiten direkt zum dotnet-runtime-[major].[minor]-Paket hinzugefügt.

Wenn Paketinhalte sich in einem Ordner mit Versionsangabe befinden, stimmt der Paketname [major].[minor] mit der Ordnernamen mit Versionsangabe überein. Für alle Pakete (außer netstandard-targeting-pack-[netstandard_major].[netstandard_minor]) stimmt dieser auch mit der .NET-Version überein.

Abhängigkeiten zwischen Paketen sollten eine identische oder höhere erforderliche Version verwenden. dotnet-sdk-7.0:7.0.401 erfordert beispielsweise aspnetcore-runtime-7.0 >= 7.0.6. Dies ermöglicht es dem Benutzer, für seine Installation ein Upgrade mithilfe eines Stammpakets (z.B. dnf update dotnet-sdk-7.0) durchzuführen.

Für die meisten Verteilungen müssen alle Artefakte aus der Quelle erstellt werden. Dies wirkt sich auf die Pakete aus:

  • Die Drittanbieterbibliotheken unter shared/Microsoft.AspNetCore.All können nicht einfach aus der Quelle erstellt werden. Daher ist dieser Ordner im aspnetcore-runtime-Paket nicht enthalten.

  • Der NuGetFallbackFolder wird mithilfe von binären Artefakten aus nuget.org aufgefüllt. Der Ordner sollte leer bleiben.

Möglicherweise stellen mehrere dotnet-sdk-Pakete die gleichen Dateien für den NuGetFallbackFolder bereit. Um Probleme mit dem Paket-Manager zu vermeiden, sollten diese Dateien identisch sein (Prüfsumme, Änderungsdatum usw.).

Debugpakete

Debuginhalte sollten in Debug-benannte Paketen gepackt werden, die auf die .NET-Paketteilung folgen, die zuvor in diesem Artikel beschrieben wurde. Beispiel: Debuginhalt für das dotnet-sdk-[major].[minor]-Paket sollte in ein Paket mit dem Namen dotnet-sdk-dbg-[major].[minor] eingeschlossen werden. Sie sollten Debuginhalte an demselben Speicherort wie die Binärdateien installieren.

Hier sind einige binäre Beispiele:

Im {dotnet_root}/sdk/<sdk version>-Verzeichnis werden die folgenden beiden Dateien erwartet:

  • dotnet.dll - installiert mit dem dotnet-sdk-[major].[minor]-Paket
  • dotnet.pdb - installiert mit dem dotnet-sdk-dbg-[major].[minor]-Paket

Im {dotnet_root}/shared/Microsoft.NETCore.App/<runtime version>-Verzeichnis werden die folgenden beiden Dateien erwartet:

  • System.Text.Json.dll - installiert mit dem dotnet-runtime-[major].[minor]-Paket
  • System.Text.Json.pdb - installiert mit dem dotnet-runtime-dbg-[major].[minor]-Paket

Im {dotnet_root/shared/Microsoft.AspNetCore.App/<aspnetcore version>-Verzeichnis werden die folgenden beiden Dateien erwartet:

  • Microsoft.AspNetCore.Routing.dll - installiert mit den aspnetcore-runtime-[major].[minor]-Paketen
  • Microsoft.AspNetCore.Routing.pdb - installiert mit den aspnetcore-runtime-dbg-[major].[minor]-Paketen

Ab .NET 8.0 sind alle .NET-Debuginhalte (PDB-Dateien), die von Source-Build erstellt werden, in einem Tarball mit dem Namen dotnet-symbols-sdk-<version>-<rid>.tar.gz verfügbar. Dieses Archiv enthält PDBs in Unterverzeichnissen, die der Verzeichnisstruktur des .NET SDK Tarball dotnet-sdk-<version>-<rid>.tar.gz entsprechen.

Während alle Debuginhalte im Debug-Tarball verfügbar sind, sind nicht alle Debuginhalte gleichermaßen wichtig. Endbenutzer interessieren sich hauptsächlich für den Inhalt der shared/Microsoft.AspNetCore.App/<aspnetcore version>- und shared/Microsoft.NETCore.App/<runtime version>-Verzeichnisse.

Der folgende SDK-Inhalt unter sdk/<sdk version> eignet sich zum Debuggen von .NET SDK-Toolsets.

Die folgenden Pakete sind die empfohlenen Debugpakete:

  • aspnetcore-runtime-dbg-[major].[minor]: Installiert Debuginhalte für eine bestimmte ASP.NET Core-Laufzeit

    • Version: <aspnetcore runtimeversion>
    • Beispiel: aspnetcore-runtime-dbg-8.0
    • Enthält: Debuginhalt für (6)
    • Abhängigkeiten:aspnetcore-runtime-[major].[minor]
  • dotnet-runtime-dbg-[major].[minor]: Installiert Debuginhalte für eine bestimmte Laufzeit

    • Version: <runtimeversion>
    • Beispiel: dotnet-runtime-dbg-8.0
    • Enthält: Debuginhalt für (5)
    • Abhängigkeiten:dotnet-runtime-[major].[minor]

Das folgende Debugpaket ist optional:

  • dotnet-sdk-dbg-[major].[minor]: Installiert Debuginhalte für eine bestimmte SDK-Version
    • Version: <sdk version>
    • Beispiel: dotnet-sdk-dbg-8.0
    • Enthält: Debuginhalt für (3),(4),(18)
    • Abhängigkeiten:dotnet-sdk-[major].[minor]

Der Debug-Tarball enthält auch einige Debuginhalte unter packs, die Kopien von Inhalten unter shared darstellen. Im .NET-Layout wird das packs-Verzeichnis zum Erstellen von .NET-Anwendungen verwendet. Es gibt keine Debugszenarien, daher sollten Sie den Debuginhalt nicht unter packs in dem Debug-Tarball verpacken.

Erstellen von Paketen

Das Repository dotnet/source-build stellt Anweisungen zum Erstellen eines Quell-Tarballs des .NET SDK und aller zugehörigen Komponenten bereit. Die Ausgabe des source-build-Repositorys entspricht der Anordnung, die im ersten Abschnitt dieses Artikels beschrieben wurde.