Freigeben über


Leitfaden für Betreuer

Dieses Dokument listet eine Reihe von Richtlinien auf, die Sie beim Hinzufügen oder Aktualisieren eines Portrezepts anwenden sollten. Es ist beabsichtigt, die Rolle von Debians Richtlinienhandbuch, Homebrews Betreuerrichtlinien und Homebrews Formula Cookbook zu erfüllen.

Allgemeine Ziele des Registrierungsentwurfs

Ports im aktuellen Basisplan müssen gleichzeitig installiert werden können

Wir möchten in der Lage sein, nachgeschaltete Benutzer von Bibliotheken in der kuratierten Registrierung anzuzeigen, dass die Kombination von Bibliotheken in einem gegebenen Basisplan, den wir veröffentlichen, getestet wurde, um zumindest in einigen Konfigurationen zusammenzuarbeiten. Durch das Zulassen, dass Ports voneinander ausgeschlossen werden, wird die Möglichkeit zum Testen solcher Konfigurationen unterbrochen, da die Anzahl der für solche Tests erforderlichen Builds größer wird.2^number_of_such_cases Darüber hinaus gilt die Installation zusätzlicher Abhängigkeiten immer als "sicher": Es gibt keine Möglichkeit, dass ein Port oder Endbenutzer bestätigt, dass eine Abhängigkeit nicht in ihren Anforderungen installiert ist.

Wenn Sie eine solche alternative Situation für Benutzer darstellen möchten, sollten Sie beschreiben, wie jemand einen Überlagerungsport erstellen kann, der das alternative Formular mit einem Kommentar portfile.cmake implementiert, anstatt zu versuchen, zusätzliche Ports hinzuzufügen, die niemals in die fortlaufende Integration der kuratierten Registrierung integriert wurden. Siehe z. B . glad@0.1.36.

Vor der Einführung von Registern haben wir mehrere nicht getestete Ports-as-Alternativen akzeptiert, z boringssl. B. die Erstellung von Überlagerungsports, die die Erstellung von Überlagerungsports vereinfachen könnten. Dies wird nicht mehr akzeptiert, da Registrierungen die Veröffentlichung dieser nicht getesteten Ports zulassen, ohne die kuratierte Registrierung zu ändern.

PR-Struktur

Erstellen separater Pullanforderungen pro Port

Trennen Sie nach Möglichkeit Änderungen in mehrere PRs. Dies erleichtert die Überprüfung und verhindert, dass Probleme mit einer Reihe von Änderungen alle anderen Änderungen beibehalten werden.

Vermeiden sie triviale Änderungen in unberührten Dateien

Vermeiden Sie beispielsweise das Neuformatieren oder Umbenennen von Variablen in Portdateien, die andernfalls keinen Grund haben, für das Problem zu ändern. Wenn Sie die Datei jedoch für den primären Zweck der PR (Aktualisieren der Bibliothek) ändern müssen, werden offensichtlich vorteilhafte Änderungen wie das Beheben von Tippfehlern geschätzt!

Überprüfen von Namen für andere Repositorys

Portnamen sollten versuchen, eindeutig zu sein, welches Paket der Port installiert. Idealerweise sollte das Durchsuchen des Portnamens in einer Suchmaschine Sie schnell zum entsprechenden Projekt führen. Ein guter Dienst, um viele Paketnamen in mehreren Repositorys gleichzeitig zu überprüfen, ist Repology.

Projekte mit Kurznamen oder benannt nach allgemeinen Wörtern erfordern möglicherweise eine Mehrdeutigkeit, insbesondere wenn keine Projekte mit einer starken Zuordnung zum angegebenen Wort vorhanden sind. Beispielsweise ist ein Port mit dem Namen ip nicht akzeptabel, da wahrscheinlich mehrere Projekte ähnlich benannt werden.

Beispiele für gute Mehrdeutigkeiten sind:

  • Der Besitzername oder die Organisation des Repositorys: google-cloud-cpp.
  • Der Name einer Suite von Bibliotheken, zu der das Projekt gehört: boost-dll.

Allgemeine Präfixe und Suffixe, die von C++- und Open Source-Projekten verwendet werden, sind ungültige Mehrdeutigkeiten, einige Beispiele sind jedoch nicht beschränkt auf:

  • cpp,
  • free,
  • lib,
  • open,
  • numbers

Wenn Sie beispielsweise die folgenden Portnamen vergleichen: ip-cpplibip , und ip5 entfernen Sie die ungültigen Mehrdeutigkeiten, werden sie alle auf denselben Stamm (ip) reduziert und daher als denselben Namen betrachtet.

Eine Ausnahme dieser Richtlinie ist für Namen, die stark mit einem einzelnen Projekt verknüpft sind. Beispiel: libpng, openssl und zlib.

Verwenden von GitHub-Entwurfs-PRs

GitHub Draft PRs sind eine großartige Möglichkeit, CI- oder menschliches Feedback zu Arbeiten zu erhalten, die noch nicht zum Zusammenführen bereit sind. Die meisten neuen PRs sollten als Entwürfe geöffnet und in normale PRs konvertiert werden, sobald die CI übergeht.

Weitere Informationen zu GitHub-Entwurfs-PRs finden Sie unter Einführung von Entwurfs-Pullanforderungen.

Portfiles

Vermeiden veralteter Hilfsfunktionen

Derzeit sind die folgenden Hilfsprogramme veraltet:

Einige der Ersatzhilfsfunktionen befinden sich in "Toolsports", damit Verbraucher ihr Verhalten an bestimmte Versionen anheften können, um das Verhalten der Helfer in einer bestimmten Version zu sperren. Toolsports "dependencies"müssen den Portports wie folgt hinzugefügt werden:

{
  "name": "vcpkg-cmake",
  "host": true
},
{
  "name": "vcpkg-cmake-config",
  "host": true
}

Vermeiden übermäßiger Kommentare in Portfiles

Im Idealfall sollten Portfiles kurz, einfach und so deklarativ wie möglich sein. Entfernen Sie alle vom create Befehl eingeführten Kesselplattenkommentare, bevor Sie eine PR übermitteln.

Ports dürfen nicht vom Pfad abhängig sein

Ports dürfen ihr Verhalten nicht basierend darauf ändern, welche Ports bereits in einem Formular installiert sind, das den Inhalt, der portiert wird, ändern würde. Angenommen, dies liegt vor:

> vcpkg install a
> vcpkg install b
> vcpkg remove a

und

> vcpkg install b

Die installierten b Dateien müssen unabhängig von der vorherigen Installation aidentisch sein. Dies bedeutet, dass Ports nicht versuchen müssen, zu erkennen, ob etwas in der installierten Struktur von einem anderen Port bereitgestellt wird, bevor sie eine Aktion ausführen. Eine bestimmte und häufige Ursache für ein solches "pfadabhängiges" Verhalten wird unten unter "Beim Definieren von Features, explizit Steuern von Abhängigkeiten" beschrieben.

Eindeutige Portzuordnungsregel

Im gesamten vcpkg-System wird davon ausgegangen, dass kein Benutzer gleichzeitig verwendet wird, dass er dieselbe Datei bereitstellt. Wenn ein Port versucht, eine Datei zu installieren, die bereits von einer anderen Datei bereitgestellt wurde, schlägt die Installation fehl. Wenn ein Port z. B. einen extrem allgemeinen Namen für eine Kopfzeile verwenden möchte, sollte er diese Kopfzeilen in einem Unterverzeichnis statt in include.

Diese Eigenschaft wird regelmäßig durch fortlaufende Integration überprüft, die versuchen, alle Ports in der Registrierung zu installieren, was fehlschlägt FILE_CONFLICTS , wenn zwei Ports dieselbe Datei bereitstellen.

Hinzufügen von CMake-Exporten in einem inoffiziellen Namespace

Ein Kerndesign ideal für vcpkg ist das Erstellen von "Lock-In" für Benutzer. Im Buildsystem sollte es keinen Unterschied zwischen einer Bibliothek vom System und je nach Bibliothek von vcpkg geben. Zu diesem Zweck vermeiden wir das Hinzufügen von CMake-Exporten oder -Zielen zu vorhandenen Bibliotheken mit "dem offensichtlichen Namen", damit upstreams ihre eigenen offiziellen CMake-Exporte ohne Konflikte mit vcpkg hinzufügen können.

Zu diesem Zweck sollten alle CMake-Konfigurationen, die der Port exportiert, die sich nicht in der Upstreambibliothek befinden, als Präfix aufweisen unofficial- . Alle zusätzlichen Ziele sollten sich im unofficial::<port>:: Namespace befinden.

Dies bedeutet, dass der Benutzer Folgendes sehen sollte:

  • find_package(unofficial-<port> CONFIG) als Weg zum einmaligen Zu-vcpkg-Paket
  • unofficial::<port>::<target> als exportiertes Ziel aus diesem Port.

Beispiele:

  • brotli erstellt das unofficial-brotli Paket, das Ziel unofficial::brotli::brotlierzeugt.

Jeder Port muss eine Im Ordner ${CURRENT_PACKAGES_DIR}/share/${PORT}benannte copyright Datei bereitstellen. Wenn der Lizenzinhalt eines Pakets in seinen Quelldateien verfügbar ist, sollte diese Datei durch einen Aufruf vcpkg_install_copyright()erstellt werden. vcpkg_install_copyright Bündelt bei Bedarf auch mehrere Copyright-Dateien.

vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")

Eine ältere Methode zum manuellen Erstellen dieser Datei ist mit dem integrierten file Befehl von CMake. Dies wird zugunsten neuer vcpkg_install_copyright Ports abgeraten, ist aber weiterhin zulässig.

file(INSTALL "${SOURCE_PATH}/LICENSE" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)

Wenn sich der Lizenzinhalt in den Upstreamquelldateien nicht in Textform befindet (z. B. eine PDF-Datei), copyright sollte eine Erläuterung enthalten, wie ein Benutzer die Lizenzanforderungen finden kann. Wenn möglich, sollte es auch einen Link zu den ursprünglichen Quelldateien enthalten, die dies angeben, damit Benutzer überprüfen können, ob es auf dem neuesten Stand ist.

file(WRITE "${CURRENT_PACKAGES_DIR}/share/${PORT}/copyright" [[As of 2023-07-25, according to
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/README.md#end-user-license-agreement
this software is bound by the "SOFTWARE DEVELOPMENT KIT LICENSE AGREEMENT" PDF located at
https://github.com/GPUOpen-LibrariesAndSDKs/display-library/blob/master/Public-Documents/ADL%20SDK%20EULA.pdf
]])

Versionsbeschränkungen in Ports

Versionsbeschränkungen innerhalb von Ports sollten im Allgemeinen vermieden werden, da sie die unabhängige Entwicklung von Projekten behindern können. Das Hinzufügen solcher Einschränkungen ist nur zulässig, wenn eine gut dokumentierte Begründung vorhanden ist, z. B. nachgewiesene Inkompatibilität mit bestimmten früheren Versionen. Diese Einschränkungen sollten nicht nur verwendet werden, um die Parität mit unabhängigen Projekten aufrechtzuerhalten.

Features

Verwenden Sie keine Features, um Alternativen zu implementieren

Features müssen als additive Funktionalität behandelt werden. Wenn port[featureA] installationen und port[featureB] installiert werden, müssen Sie port[featureA,featureB] es installieren. Wenn ein zweiter Port von und einem dritten Port abhängig ist [featureA] [featureB], sollte außerdem die Installation der zweiten und der dritten Ports ihre Abhängigkeiten erfüllen.

Bibliotheken in dieser Situation müssen eine der verfügbaren Optionen auswählen, wie in vcpkg ausgedrückt, und Benutzer, die eine andere Einstellung benötigen, müssen zu diesem Zeitpunkt Überlagerungsports verwenden.

Vorhandene Beispiele, die wir heute nicht akzeptieren würden, um Abwärtskompatibilität zu gewährleisten:

  • libgit2, libzipopen62541 alle verfügen über Features zum Auswählen eines TLS- oder Krypto-Back-End. curl hat verschiedene Krypto-Back-End-Optionen, ermöglicht aber die Auswahl zwischen ihnen zur Laufzeit, was bedeutet, dass der obige Tenet beibehalten wird.
  • darknet verfügt opencv2über , opencv3Features, um zu steuern, welche Version von opencv für seine Abhängigkeiten verwendet werden soll.

Ein Feature kann vorschau- oder Betafunktionen aktivieren

Ungeachtet der oben genannten, wenn es eine Vorschauverzweigung gibt oder ähnlich ist, bei der die Vorschaufunktion eine hohe Wahrscheinlichkeit hat, die Nichtvorschaufunktion nicht zu stören (z. B. keine API-Entfernungen), ist ein Feature akzeptabel, um diese Einstellung zu modellieren.

Beispiele:

  • Die Azure-SDKs (des Formulars azure-Xxx) weisen ein public-preview Feature auf.
  • imgui verfügt über ein experimental-docking Feature, das ihre Vorschau-Docking-Verzweigung verwendet, die einen Zusammenführungs-Commit verwendet, der an jede ihrer öffentlichen nummerierten Versionen angefügt ist.

Standardfeatures dürfen keine APIs hinzufügen

Standardfeatures sollen sicherstellen, dass ein vernünftig funktionsfähiger Build einer Bibliothek für Kunden installiert wird, die nicht wissen, dass sie sie verwenden. Wenn sie nicht wissen, dass sie eine Bibliothek verwenden, können sie die Features nicht auflisten. Stellt beispielsweise Features zur Verfügung, libarchive die Komprimierungsalgorithmen für eine vorhandene generische Schnittstelle aktivieren. Wenn sie ohne solche Features erstellt wurde, verfügt die Bibliothek möglicherweise nicht über ein Hilfsprogramm.

Man muss sorgfältig überlegen, ob ein Feature standardmäßig aktiviert sein soll, da das Deaktivieren von Standardfeatures komplex ist.

Das Deaktivieren eines Standardfeatures als "transitive" Consumer erfordert Folgendes:

  • Alle Kunden deaktivieren standardfeatures explizit über "default-features": false oder einschließen [core] in die Featureliste in der Befehlszeile.
  • Benennen der transitiven Abhängigkeit von der vcpkg install Befehlszeile oder als direkte Abhängigkeit im Manifest der obersten Ebene

Wenn das Feature in der kuratierten Registrierung von vcpkg zusätzliche APIs, ausführbare Dateien oder andere Binärdateien hinzufügt, muss sie standardmäßig deaktiviert sein. Markieren Sie im Zweifelsfall kein Feature als Standard.

Verwenden Sie keine Features, um Alternativen in veröffentlichten Schnittstellen zu steuern

Wenn ein Verbraucher eines Ports nur von der Kernfunktionalität dieses Ports abhängt, dürfen sie mit hoher Wahrscheinlichkeit nicht durch Aktivieren des Features unterbrochen werden. Dies ist noch wichtiger, wenn die Alternative nicht direkt vom Verbraucher gesteuert wird, sondern durch Compilereinstellungen wie /std:c++17 / -std=c++17.

Vorhandene Beispiele, die wir heute nicht akzeptieren würden, um Abwärtskompatibilität zu gewährleisten:

  • redis-plus-plus[cxx17] steuert ein Polyfill, backt die Einstellung aber nicht in der installierten Struktur.
  • ace[wchar]ändert alle APIs, die const char*nicht akzeptiert const wchar_t* werden sollen.

Ein Feature kann Polyfills durch Aliase ersetzen, sofern der Ersatz in die installierte Struktur integriert ist.

Ungeachtet der oben genannten Funktionen können Ports Polyfills mit einem Feature entfernen, sofern:

  1. Durch Aktivieren des Features werden die Polyfills in Aliase der polyfilled-Entität geändert.
  2. Der Zustand des Polyfill wird in die installierten Header integriert, sodass ABI-Laufzeitfehler "unmöglich" unwahrscheinlich sind.
  3. Es ist möglich, dass ein Verbraucher des Ports Code schreiben kann, der in beiden Modi funktioniert, z. B. mithilfe einer Typedef, die entweder polyausfüllt ist oder nicht.

Beispiel:

  • abseil[cxx17] änderungen absl::string_view an einem Ersatz oder std::string_view; der Patch implementiert die Backanforderung.

Wenn es wichtig ist, die zugrunde liegenden Alternativen verfügbar zu machen, empfehlen wir, nachrichten zur Erstellungszeit bereitzustellen, um dem Benutzer anzuweisen, wie der Port in eine private Überlagerung kopiert wird:

set(USING_DOG 0)
message(STATUS "This version of LibContoso uses the Kittens backend. To use the Dog backend instead, create an overlay port of this with USING_DOG set to 1 and the `kittens` dependency replaced with `dog`.")
message(STATUS "This recipe is at ${CMAKE_CURRENT_LIST_DIR}")
message(STATUS "See the overlay ports documentation at https://github.com/microsoft/vcpkg/blob/master/docs/specifications/ports-overlay.md")

Buildtechniken

Keine anbieterbezogenen Abhängigkeiten verwenden

Verwenden Sie keine eingebetteten Kopien von Bibliotheken. Alle Abhängigkeiten sollten separat aufgeteilt und verpackt werden, damit sie aktualisiert und verwaltet werden können.

Bevorzugen Sie die Verwendung von CMake

Wenn mehrere Buildsysteme verfügbar sind, verwenden Sie lieber CMake. Darüber hinaus kann es bei Bedarf einfacher und benutzerfreundlicher sein, alternative Buildsysteme mithilfe von file(GLOB) Direktiven in CMake umzuschreiben.

Beispiele: abseil

Auswählen von statischen oder freigegebenen Binärdateien

Beim Erstellen von CMake-Bibliotheken wird der richtige Wert BUILD_SHARED_LIBS übergeben, vcpkg_cmake_configure() der auf der angeforderten Variante des Benutzers basiert.

Sie können alternative Konfigurationsparameter mithilfe von string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" ...).

# portfile.cmake

string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" KEYSTONE_BUILD_STATIC)
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" KEYSTONE_BUILD_SHARED)

vcpkg_cmake_configure(
    SOURCE_PATH ${SOURCE_PATH}
    OPTIONS
        -DKEYSTONE_BUILD_STATIC=${KEYSTONE_BUILD_STATIC}
        -DKEYSTONE_BUILD_SHARED=${KEYSTONE_BUILD_SHARED}
)

Wenn eine Bibliothek keine Konfigurationsoptionen zum Auswählen der Buildvariante bietet, muss der Build gepatcht werden. Beim Patchen eines Builds sollten Sie immer versuchen, die zukünftige Wartung des Ports zu maximieren. Dies bedeutet in der Regel, die Anzahl der Zeilen zu minimieren, die berührt werden müssen, um das Problem zu beheben.

Beispiel: Patchen einer CMake-Bibliothek, um unerwünschte Varianten zu vermeiden

Wenn Sie z. B. eine CMake-basierte Bibliothek patchen, reicht es möglicherweise aus, um unerwünschte Ziele hinzuzufügen EXCLUDE_FROM_ALL und den install(TARGETS ...) Aufruf in einem if(BUILD_SHARED_LIBS). Dies ist kürzer als das Umschließen oder Löschen jeder Zeile, die die unerwünschte Variante erwähnt.

Für ein Projekt CMakeLists.txt mit folgendem Inhalt:

add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)

install(TARGETS contoso contoso_static EXPORT ContosoTargets)

install(EXPORT ContosoTargets
  FILE ContosoTargets
  NAMESPACE contoso::
  DESTINATION share/contoso)

Nur die install(TARGETS) Linie muss gepatcht werden.

add_library(contoso SHARED contoso.c)
add_library(contoso_static STATIC contoso.c)

if(BUILD_SHARED_LIBS)
  set_target_properties(contoso_static PROPERTIES EXCLUDE_FROM_ALL 1)
  install(TARGETS contoso EXPORT ContosoTargets)
else()
  set_target_properties(contoso PROPERTIES EXCLUDE_FROM_ALL 1)
  install(TARGETS contoso_static EXPORT ContosoTargets)
endif()

install(EXPORT ContosoTargets
  FILE ContosoTargets
  NAMESPACE contoso::
  DESTINATION share/contoso)

Wenn Sie Features definieren, steuern Sie explizit Abhängigkeiten

Stellen Sie beim Definieren eines Features, das eine optionale Abhängigkeit erfasst, sicher, dass die Abhängigkeit nicht versehentlich verwendet wird, wenn das Feature nicht explizit aktiviert ist.

set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB ON)
set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB OFF)
if ("zlib" IN_LIST FEATURES)
  set(CMAKE_DISABLE_FIND_PACKAGE_ZLIB OFF)
  set(CMAKE_REQUIRE_FIND_PACKAGE_ZLIB ON)
endif()

vcpkg_cmake_configure(
  SOURCE_PATH ${SOURCE_PATH}
  OPTIONS
    -DCMAKE_DISABLE_FIND_PACKAGE_ZLIB=${CMAKE_DISABLE_FIND_PACKAGE_ZLIB}
    -DCMAKE_REQUIRE_FIND_PACKAGE_ZLIB=${CMAKE_REQUIRE_FIND_PACKAGE_ZLIB}
)

Der unten verwendete vcpkg_check_features() Codeausschnitt ist gleichwertig.

vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
  FEATURES
    "zlib"    CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
  INVERTED_FEATURES
    "zlib"    CMAKE_DISABLE_FIND_PACKAGE_ZLIB
)

vcpkg_cmake_configure(
    SOURCE_PATH ${SOURCE_PATH}
    OPTIONS
      ${FEATURE_OPTIONS}
)

ZLIB im Codeausschnitt wird die Groß-/Kleinschreibung beachtet. Weitere Informationen finden Sie in der CMAKE_DISABLE_FIND_PACKAGE_<PackageName> Dokumentation CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> .

Eine Lib wird als widersprüchlich betrachtet, wenn eine der folgenden Aktionen ausgeführt wird:

  • Definieren main
  • Malloc definieren
  • Definieren von Symbolen, die auch in anderen Bibliotheken deklariert sind

Widersprüchliche Libs sind in der Regel entwurfsweise und gelten nicht als Defekt. Da einige Buildsysteme mit allem im Lib-Verzeichnis verknüpft sind, sollten diese in ein Unterverzeichnis mit dem Namen manual-linkverschoben werden.

Versionsverwaltung

Folgen allgemeiner Konventionen für das "version" Feld

Folgen Sie beim Erstellen eines neuen Ports der vom Paketautor verwendeten Versionsverwaltungskonvention. Wenn Sie den Port aktualisieren, verwenden Sie weiterhin dieselbe Konvention, es sei denn, der Upstream sagt etwas anderes. Eine vollständige Erläuterung unserer Konventionen finden Sie in unserer Versionsverwaltungsdokumentation.

Wenn upstream eine Version in einer Weile nicht veröffentlicht hat, ändern Sie nicht das Versionsverwaltungsschema des Ports, version-date um die neuesten Änderungen zu erhalten. Diese Commits können Änderungen enthalten, die nicht zur Produktion bereit sind. Bitten Sie stattdessen das Upstream-Repository, eine neue Version zu veröffentlichen.

Aktualisieren des Felds "port-version" in der Manifestdatei aller geänderten Ports

vcpkg verwendet dieses Feld, um zu bestimmen, ob ein bestimmter Port veraltet ist und wann immer sich das Verhalten des Ports ändert.

Unsere Konvention besteht darin, das "port-version" Feld für Änderungen am Port zu verwenden, die die upstream-Version nicht ändern, und den "port-version" Rücklauf auf Null zurückzusetzen, wenn ein Update auf die upstream-Version vorgenommen wird.

Beispiel:

  • Die Paketversion von Zlib ist zurzeit 1.2.1ohne explizite "port-version" (entspricht einem "port-version" von 0).
  • Sie haben festgestellt, dass die falsche Copyrightdatei bereitgestellt wurde und dies in der Portdatei behoben wurde.
  • Sie sollten das "port-version" Feld in der Manifestdatei 1auf aktualisieren.

Weitere Informationen finden Sie in der Versionsverwaltungsdokumentation .

Aktualisieren der Versionsdateien in versions/ allen geänderten Ports

vcpkg verwendet eine Reihe von Metadatendateien, um die Versionsverwaltungsfunktion zu unterstützen. Diese Dateien befinden sich an den folgenden Speicherorten:

  • ${VCPKG_ROOT}/versions/baseline.json, (diese Datei ist für alle Ports üblich) und
  • ${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json (eine pro Port).

Beispielsweise sind für zlib die relevanten Dateien:

  • ${VCPKG_ROOT}/versions/baseline.json
  • ${VCPKG_ROOT}/versions/z-/zlib.json

Wir erwarten, dass Sie bei jeder Aktualisierung eines Ports auch die Versionsdateien aktualisieren.

Die empfohlene Methode zum Aktualisieren dieser Dateien besteht darin, den x-add-version Befehl auszuführen, z. B.:

vcpkg x-add-version zlib

Wenn Sie mehrere Ports gleichzeitig aktualisieren, können Sie stattdessen Folgendes ausführen:

vcpkg x-add-version --all

um die Dateien für alle geänderten Ports gleichzeitig zu aktualisieren.

Hinweis

Für diese Befehle müssen Sie vor dem Ausführen ihrer Änderungen an den Ports ein Commit ausgeführt haben. Der Grund dafür ist, dass die Git SHA des Portverzeichnisses in diesen Versionsdateien erforderlich ist. Aber keine Sorge, der x-add-version Befehl warnt Sie, wenn Sie lokale Änderungen haben, die nicht zugesichert wurden.

Weitere Informationen finden Sie in der Versionsverwaltungsreferenz und beim Erstellen von Registrierungen.

Patching

vcpkg ist eine Verpackungslösung, nicht die ultimativen Besitzer der von uns bereitgestellten Komponenten. In einigen Fällen müssen Patches angewendet werden, um die Kompatibilität von Komponenten mit Plattformen oder die Kompatibilität von Komponenten miteinander zu verbessern.

  • Wir möchten Patches vermeiden, die:
    • Upstream würde nicht mit
    • Sicherheitsrisiken oder Abstürze verursachen
    • wir sind nicht in der Lage, über upstream-Versionsupdates hinweg zu warten.
    • sind groß genug, um die Lizenzverknügung mit dem vcpkg-Repository selbst zu verursachen

Benachrichtigen von Upstream-Besitzern für upstreamrelevante Patches

Wenn ein Patch möglicherweise von upstream nützlich sein könnte, muss der Upstream über den Inhalt des Patches benachrichtigt werden. (Patches, die vcpkg-spezifisches Verhalten anwenden, das nicht mit upstream verknüpft ist, z. B. das Entwickeln einer Abhängigkeit, erfordern keine Benachrichtigung.)

Um Situationen zu vermeiden, in denen upstream mit dem Patch nicht einverstanden ist, warten wir mindestens 30 Tage, um solche Patches anzuwenden.

Wir überspringen diesen Wartezeitszeitraum, wenn wir ein hohes Vertrauen haben, dass die Änderung korrekt ist. Beispiele für Patches mit hoher Vertrauenswürdigkeit sind unter anderem:

  • Die Akzeptanz von Upstream als Patch (z. B. das Zurückportieren einer bestimmten Änderung von einer Pullanforderung vorgelagert wurde zusammengeführt).
  • #includeFehlende s hinzufügen.
  • Kleine und offensichtliche Codefixes (z. B. Initialisieren einer nicht initialisierten Variablen).
  • Deaktivieren von irrelevanten vcpkg-Komponenten des Builds, z. B. Tests oder Beispiele.

Bevorzugen von Optionen zum Patchen

Es empfiehlt sich, Optionen in einem Aufruf festzulegen, um die Einstellungen direkt zu vcpkg_configure_xyz() patchen.

Allgemeine Optionen, mit denen Sie Patching vermeiden können:

  • [MSBUILD] <PropertyGroup> Einstellungen innerhalb der Projektdatei können über /p: Parameter überschrieben werden.
  • [CMAKE] Aufrufe in find_package(XYz) CMake-Skripts können über -DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON
  • [CMAKE] Cachevariablen (deklariert als set(VAR "value" CACHE STRING "Documentation") oder option(VAR "Documentation" "Default Value")) können überschrieben werden, indem sie einfach in der Befehlszeile -DVAR:STRING=Fooals übergeben werden. Eine wichtige Ausnahme ist, wenn der FORCE Parameter an .set() Weitere Informationen finden Sie in der CMake-Dokumentation set

Bevorzugen Sie, genehmigte Patches herunterzuladen, um sie in den Port einzuchecken.

Wenn eine genehmigte oder zusammengeführte Patchdatei aus upstream abgerufen werden kann, sollten Ports versuchen, sie herunterzuladen und anzuwenden, anstatt sie als Teil der Portdateien zu verwenden. Dieser Prozess wird bevorzugt, da er:

  • Bestätigt, dass upstream die Patchänderungen akzeptiert hat
  • Vereinfacht den Überprüfungsprozess, indem der Onus vorgelagert verschoben wird.
  • Reduziert die Größe des vcpkg-Repositorys für Benutzer, die den Patch nicht verwenden.
  • Vermeiden von Lizenzkonflikten mit dem vcpkg-Repository

Patches sollten von einem stabilen Endpunkt heruntergeladen werden, um SHA-Konflikte zu vermeiden. Beim Herunterladen von Patchdateien aus einer Pullanforderung oder einem Commit von GitHub und GitLab sollte der ?full_index=1 Parameter an die Download-URL angefügt werden.

Beispiele:

  • https://github.com/google/farmhash/pull/40.diff?full_index=1
  • https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1
  • https://gitlab.kitware.com/paraview/paraview/-/merge_requests/6375.diff?full_index=1

Bevorzugen des Patchens überschriebener VCPKG_<VARIABLE> Werte

Einige Variablen, VCPKG_<VARIABLE> die einem Äquivalent CMAKE_<VARIABLE>vorangestellt sind. Allerdings werden nicht alle an den internen Paketbuild übergeben (siehe Implementierung: Windows-Toolkette).

Betrachten Sie das folgende Beispiel:

set(VCPKG_C_FLAGS "-O2 ${VCPKG_C_FLAGS}")
set(VCPKG_CXX_FLAGS "-O2 ${VCPKG_CXX_FLAGS}")

Die verwendung vcpkgder integrierten Toolkette funktioniert, da der Wert der VCPKG_<LANG>_FLAGS Datei an die entsprechende CMAKE_LANG_FLAGS Variable weitergeleitet wird. Aber eine benutzerdefinierte Toolkette, die sich nicht der vcpkgVariablen bewusst ist, leitet sie nicht weiter.

Aus diesem Grund empfiehlt es sich, das Buildsystem direkt beim Festlegen CMAKE_<LANG>_FLAGSzu patchen.

Minimieren von Patches

Wenn Sie Änderungen an einer Bibliothek vornehmen, versuchen Sie, den endgültigen Diff zu minimieren. Dies bedeutet, dass Sie den upstream-Quellcode nicht neu formatieren sollten, wenn Sie Änderungen vornehmen, die sich auf eine Region auswirken. Wenn Sie eine bedingte Bedingung deaktivieren, empfiehlt es sich, der Bedingung eine AND FALSE oder && 0 mehrere Zeilen hinzuzufügen. Wenn ein großer Bereich deaktiviert werden muss, ist es kürzer, eine if(0) oder #if 0 mehrere Regionen hinzuzufügen, anstatt jede Zeile im Patch zu löschen.

Fügen Sie keine Patches hinzu, wenn der Port veraltet ist und das Aktualisieren des Ports auf eine neuere veröffentlichte Version dasselbe Problem lösen würde. vcpkg bevorzugt das Aktualisieren von Ports über das Patchen veralteter Versionen.

Dies hilft, die Größe des vcpkg-Repositorys nach unten zu halten und die Wahrscheinlichkeit zu verbessern, dass der Patch auf zukünftige Codeversionen angewendet wird.

Features in Patches nicht implementieren

Der Zweck des Patchings in vcpkg besteht darin, kompatibilität mit Compilern, Bibliotheken und Plattformen zu ermöglichen. Es ist nicht, neue Features anstelle des ordnungsgemäßen Open Source-Verfahrens zu implementieren (Übermitteln eines Problems/PR/etc).

Keine Tests/Dokumente/Beispiele standardmäßig erstellen

Überprüfen Sie beim Übermitteln eines neuen Ports nach optionen wie BUILD_TESTS oder WITH_TESTS stellen POCO_ENABLE_SAMPLES Sie sicher, dass die zusätzlichen Binärdateien deaktiviert sind. Dadurch werden Die Erstellungszeiten und Abhängigkeiten für den durchschnittlichen Benutzer minimiert.

Optional können Sie ein test Feature hinzufügen, das das Erstellen der Tests ermöglicht, dies sollte jedoch nicht in der Default-Features Liste enthalten sein.

Aktivieren vorhandener Benutzer der Bibliothek zum Wechseln zu vcpkg

Nicht hinzufügen CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS

Sofern der Autor der Bibliothek die Bibliothek nicht bereits verwendet, sollten wir diese CMake-Funktion nicht verwenden, da sie schlecht mit C++-Vorlagen interagiert und bestimmte Compilerfeatures aufbricht. Bibliotheken, die keine DEF-Datei bereitstellen und keine __declspec()-Deklarationen verwenden, unterstützen einfach keine freigegebenen Builds für Windows und sollten als solche vcpkg_check_linkage(ONLY_STATIC_LIBRARY)gekennzeichnet werden.

Keine Binärdateien außerhalb der von upstream angegebenen Namen umbenennen

Dies bedeutet, dass die Debugbibliothek nicht umbenannt libxwerden sollte, wenn die upstream-Bibliothek unterschiedliche Namen in release and debug (libx vss libxd) hat. Umgekehrt, wenn die Upstreambibliothek denselben Namen in Release und Debug aufweist, sollten wir keinen neuen Namen einführen.

Wichtiger Vorbehalt:

  • Statische und freigegebene Varianten sollten häufig in ein gemeinsames Schema umbenannt werden. Dies ermöglicht es Den Verbrauchern, einen gemeinsamen Namen zu verwenden und unwissen über die nachgeschaltete Verknüpfung zu sein. Dies ist sicher, da wir jeweils nur jeweils eins zur Verfügung stellen.

Wenn eine Bibliothek CMake-Integrationsdateien generiert (foo-config.cmake), muss die Umbenennung über das Patchen des CMake-Builds selbst erfolgen, anstatt einfach die Ausgabearchive/LIBs aufzurufen file(RENAME) .

Schließlich sollten DLL-Dateien unter Windows niemals nach dem Build umbenannt werden, da die generierten LIBs unterbrochen werden.

Manifeste

Es ist erforderlich, dass die Manifestdatei formatiert ist. Verwenden Sie den folgenden Befehl, um alle Manifestdateien zu formatieren:

> vcpkg format-manifest --all

Drillinge

Wir akzeptieren derzeit keine Anfragen zum Hinzufügen von Nicht-Community-Triplets. Die Förderung von Community bis zum vollständigen Tripletstatus basiert in erster Linie auf dem Budget für die Hardware zum Testen solcher Triplets und wird von Metriken gesteuert, die von vcpkg übermittelt werden, um die Wahrscheinlichkeit zu maximieren, welche Personen tatsächlich verwenden, vollständig getestet wird.

Wir werden Community-Triplets hinzufügen, wenn:

  • Es wird gezeigt, dass die Menschen diese Community-Triplet tatsächlich nutzen werden; und
  • wir wissen nicht, dass ein solches Dreifache unterbrochen ist.

Beispielsweise haben wir kein Triplet https://github.com/microsoft/vcpkg/pull/29034 hinzugefügt, da der Autor einfach versucht hat, den Satz abzuschließen, anstatt anzugeben, dass er tatsächlich eine solche Sache verwendet, und wir haben erst linux-dynamic hinzugefügt, bis die Patchelf-Lösung die Ergebnisse relocatable macht.

Nützliche Implementierungshinweise

Portfiles werden im Skriptmodus ausgeführt

Während portfile.cmake's und CMakeLists.txt's eine gemeinsame Syntax und kernige CMake-Sprachkonstrukte (auch als "Skriptbefehle" bezeichnet) verwenden, werden Portdateien im "Skriptmodus" ausgeführt, während CMakeLists.txt Dateien im "Projektmodus" ausgeführt werden. Der wichtigste Unterschied zwischen diesen beiden Modi besteht darin, dass "Skriptmodus" nicht über die Konzepte "Toolchain", "Language" und "Target" verfügt. Alle Verhaltensweisen, einschließlich Skriptbefehle, die von diesen Konstrukten abhängen (z. B. CMAKE_CXX_COMPILER, CMAKE_EXECUTABLE_SUFFIX, CMAKE_SYSTEM_NAME), sind nicht korrekt.

Portfiles haben direkten Zugriff auf Variablen, die in der Tripletdatei festgelegt sind, aber CMakeLists.txts nicht (obwohl es häufig eine Übersetzung gibt, die geschieht -- VCPKG_LIBRARY_LINKAGE im Vergleich BUILD_SHARED_LIBS).

Portfiles und Project-Builds, die von Portfiles aufgerufen werden, werden in verschiedenen Prozessen ausgeführt. Begrifflich:

+----------------------------+       +------------------------------------+
| CMake.exe                  |       | CMake.exe                          |
+----------------------------+       +------------------------------------+
| Triplet file               | ====> | Toolchain file                     |
| (x64-windows.cmake)        |       | (scripts/buildsystems/vcpkg.cmake) |
+----------------------------+       +------------------------------------+
| Portfile                   | ====> | CMakeLists.txt                     |
| (ports/foo/portfile.cmake) |       | (buildtrees/../CMakeLists.txt)     |
+----------------------------+       +------------------------------------+

Um den Host in einer Portdatei zu ermitteln, sind die standardmäßigen CMake-Variablen in Ordnung (CMAKE_HOST_WIN32).

Um das Ziel in einer Portdatei zu ermitteln, sollten die vcpkg-Tripletvariablen verwendet werden (VCPKG_CMAKE_SYSTEM_NAME).

Eine vollständige Aufzählung möglicher Einstellungen finden Sie in unserer Triplet-Dokumentation .