Partager via


Guide de maintenance

Ce document répertorie un ensemble de stratégies que vous devez appliquer lors de l’ajout ou de la mise à jour d’une recette de port. Il est destiné à servir le rôle du manuel de stratégie de Debian, des instructions de maintenance de Homebrew et du livre de recettes de formule de Homebrew.

Objectifs globaux de conception du Registre

Les ports de la base de référence actuelle doivent être installés simultanément

Nous souhaitons pouvoir montrer aux utilisateurs en aval des bibliothèques dans le Registre organisé que la combinaison de bibliothèques dans une base de référence donnée que nous publions a été testée pour fonctionner ensemble dans au moins certaines configurations. Autoriser les ports à exclure les uns des autres interrompt la possibilité de tester ces configurations, car le nombre de builds nécessaires pour ces tests augmente en tant que 2^number_of_such_cases. En outre, l’installation de dépendances supplémentaires est toujours considérée comme « sécurisée » : il n’existe aucun moyen pour un port ou un utilisateur final d’affirmer qu’une dépendance n’est pas installée dans ses exigences.

Si vous souhaitez représenter une telle situation alternative pour les utilisateurs, envisagez de décrire comment une personne peut créer un port de superposition implémentant le formulaire de remplacement avec un commentaire portfile.cmake au lieu d’essayer d’ajouter des ports supplémentaires jamais intégrés dans l’intégration continue du registre organisé. Par exemple, consultez glad@0.1.36.

Avant l’introduction des registres, nous avons accepté plusieurs ports non testés en tant que solutions alternatives, comme boringsslla création de ports de superposition plus faciles. Cela n’est plus accepté, car les registres autorisent la publication de ces ports non testés sans modifier le registre organisé.

Structure de demande de tirage

Effectuer des demandes de tirage distinctes par port

Dans la mesure du possible, séparez les modifications en plusieurs demandes de tirage. Cela facilite considérablement la révision et empêche les problèmes liés à un ensemble de modifications de conserver toutes les autres modifications.

Éviter les modifications triviales dans les fichiers non touchés

Par exemple, évitez de reformatter ou de renommer des variables dans les fichiers de port qui n’ont pas de raison d’être modifiées pour le problème à la main. Toutefois, si vous devez modifier le fichier pour l’objectif principal de la demande de tirage (mise à jour de la bibliothèque), alors évidemment les modifications bénéfiques comme la correction des fautes de frappe sont appréciées !

Vérifier les noms sur d’autres référentiels

Les noms de port doivent tenter d’être sans ambiguïté quant au package installé par le port. Dans l’idéal, la recherche du nom du port dans un moteur de recherche doit rapidement vous conduire au projet correspondant. Un bon service pour vérifier de nombreux noms de package sur plusieurs référentiels à la fois est La topologie.

Les projets portant des noms courts ou nommés après des mots communs peuvent nécessiter une ambiguïté, spécialement lorsqu’il n’y a pas de projets avec une association forte au mot donné. Par exemple, un port portant le nom ip n’est pas acceptable, car il est probable que plusieurs projets soient nommés de la même façon.

Voici quelques exemples de bonnes ambiguïtés :

  • Nom d’utilisateur ou organisation du propriétaire du dépôt : google-cloud-cpp.
  • Le nom d’une suite de bibliothèques dont le projet fait partie : boost-dll.

Les préfixes et suffixes courants utilisés par C++ et les projets code source ouvert ne sont pas des ambiguïateurs valides, certains exemples incluent, mais ne sont pas limités à :

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

Par exemple, lors de la comparaison des noms de port suivants : ip-cpplibip et ip5 la suppression des ambiguïtés non valides, elles sont toutes réduites au même tronc (ip) et sont donc considérées comme ayant le même nom.

Une exception à cette directive est faite pour les noms fortement associés à un seul projet. Par exemple : libpng, openssl et zlib.

Utiliser des demandes de tirage de projet GitHub

GitHub Draft PR est un excellent moyen d’obtenir des commentaires ci ou humains sur le travail qui n’est pas encore prêt à fusionner. La plupart des nouvelles demandes de tirage doivent être ouvertes en tant que brouillons et converties en demandes normales une fois que le CI passe.

Pour plus d’informations sur les demandes de tirage provisoire GitHub, consultez Présentation des demandes de tirage provisoire.

Fichiers de port

Éviter les fonctions d’assistance déconseillées

À ce stade, les assistances suivantes sont déconseillées :

Certaines des fonctions d’assistance de remplacement se trouvent dans des « ports d’outils » pour permettre aux consommateurs d’épingler leur comportement à des versions spécifiques, afin de verrouiller le comportement des helpers à une version particulière. Les ports d’outils doivent être ajoutés aux ports de "dependencies"votre port, comme suit :

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

Éviter des commentaires excessifs dans les fichiers de portfiles

Dans l’idéal, les fichiers de port doivent être courts, simples et aussi déclaratifs que possible. Supprimez les commentaires de plaque de chaudière introduits par la create commande avant de soumettre une demande de tirage.

Les ports ne doivent pas être dépendants du chemin d’accès

Les ports ne doivent pas modifier leur comportement en fonction des ports déjà installés dans un formulaire qui modifierait le contenu installé par le port. Prenons l’exemple suivant :

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

et

> vcpkg install b

les fichiers installés par b doivent être identiques, quelle que soit l’influence de l’installation précédente de a. Cela signifie que les ports ne doivent pas essayer de détecter si un élément est fourni dans l’arborescence installée par un autre port avant d’effectuer une action. Une cause spécifique et courante de ce comportement « dépendant du chemin » est décrite ci-dessous dans « Lors de la définition des fonctionnalités, contrôlez explicitement les dépendances ».

Règle d’attribution de port unique

Dans l’ensemble du système vcpkg, aucun deux ports qu’un utilisateur ne doit utiliser simultanément peuvent fournir le même fichier. Si un port tente d’installer un fichier déjà fourni par un autre fichier, l’installation échoue. Si un port souhaite utiliser un nom extrêmement courant pour un en-tête, par exemple, il doit placer ces en-têtes dans un sous-répertoire plutôt que dans include.

Cette propriété est vérifiée régulièrement par des exécutions d’intégration continue qui tentent d’installer tous les ports dans le Registre, ce qui échouera FILE_CONFLICTS si deux ports fournissent le même fichier.

Ajouter des exportations CMake dans un espace de noms non officiel

Une conception principale idéale pour vcpkg consiste à ne pas créer de « verrouillage » pour les utilisateurs. Dans le système de build, il ne doit pas y avoir de différence entre la fonction d’une bibliothèque du système et celle d’une bibliothèque de vcpkg. À cette fin, nous évitez d’ajouter des exportations CMake ou des cibles à des bibliothèques existantes avec « le nom évident », afin de permettre aux amonts d’ajouter leurs propres exportations CMake officielles sans conflit avec vcpkg.

À cette fin, toutes les configurations CMake que le port exporte, qui ne se trouvent pas dans la bibliothèque en amont, doivent avoir unofficial- comme préfixe. Toutes les cibles supplémentaires doivent se trouver dans l’espace unofficial::<port>:: de noms.

Cela signifie que l’utilisateur doit voir :

  • find_package(unofficial-<port> CONFIG) comme moyen d’obtenir au package unique-to-vcpkg
  • unofficial::<port>::<target> en tant que cible exportée à partir de ce port.

Exemples :

  • brotli crée le package, produisant la unofficial-brotli cible unofficial::brotli::brotli.

Chaque port doit fournir un fichier nommé copyright dans le dossier ${CURRENT_PACKAGES_DIR}/share/${PORT}. Si le contenu de licence d’un package est disponible dans ses fichiers sources, ce fichier doit être créé par un appel à vcpkg_install_copyright(). vcpkg_install_copyright regroupe également plusieurs fichiers de droits d’auteur si nécessaire.

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

Une méthode plus ancienne pour créer manuellement ce fichier est avec la commande intégrée file de CMake. Cela est déconseillé en faveur de vcpkg_install_copyright nouveaux ports, mais est toujours autorisé.

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

Si le contenu de la licence dans les fichiers sources en amont n’est pas sous forme texte (par exemple, un fichier PDF), copyright doit contenir une explication sur la façon dont un utilisateur peut trouver les exigences de licence. Si possible, il doit également inclure un lien vers les fichiers sources d’origine indiquant cela, afin que les utilisateurs puissent vérifier s’il est à jour.

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

Contraintes de version dans les ports

Les contraintes de version au sein des ports doivent généralement être évitées, car elles peuvent entraver l’évolution indépendante des projets. L’ajout de telles contraintes n’est autorisée que lorsqu’il existe une justification bien documentée, telle que l’incompatibilité éprouvée avec des versions antérieures spécifiques. Ces contraintes ne doivent pas être utilisées uniquement pour maintenir la parité avec les projets indépendants.

Fonctionnalités

N’utilisez pas de fonctionnalités pour implémenter des alternatives

Les fonctionnalités doivent être traitées comme des fonctionnalités additives. Si port[featureA] vous installez et port[featureB] installez, vous port[featureA,featureB] devez l’installer. En outre, si un deuxième port dépend [featureA] et qu’un troisième port dépend [featureB], l’installation des deuxième et troisième ports doit avoir leurs dépendances satisfaites.

Les bibliothèques dans ce cas doivent choisir l’une des options disponibles telles qu’elles sont exprimées dans vcpkg, et les utilisateurs qui souhaitent qu’un paramètre différent doit utiliser des ports de superposition pour l’instant.

Exemples existants que nous n’accepterions pas aujourd’hui conservés pour la compatibilité descendante :

  • libgit2, libziptoutes open62541 ont des fonctionnalités pour sélectionner un serveur principal TLS ou crypto. curl possède différentes options de back-end de chiffrement, mais permet de les sélectionner au moment de l’exécution, ce qui signifie que le tenet ci-dessus est conservé.
  • darknet a opencv2, opencv3fonctionnalités pour contrôler la version d’opencv à utiliser pour ses dépendances.

Une fonctionnalité peut impliquer la préversion ou la fonctionnalité bêta

Malgré ce qui précède, s’il existe une branche d’aperçu ou similaire où la fonctionnalité d’aperçu a une probabilité élevée de ne pas perturber la fonctionnalité non-préversion (par exemple, aucune suppression d’API), une fonctionnalité est acceptable pour modéliser ce paramètre.

Exemples :

  • Les Kits de développement logiciel (SDK) Azure (du formulaire azure-Xxx) ont une public-preview fonctionnalité.
  • imgui a une experimental-docking fonctionnalité qui engage sa branche d’ancrage en préversion qui utilise une validation de fusion attachée à chacune de leurs versions numérotées publiques.

Les fonctionnalités par défaut ne doivent pas ajouter d’API

Les fonctionnalités par défaut sont destinées à garantir qu’une build raisonnablement fonctionnelle d’une bibliothèque est installée pour les clients qui ne savent pas qu’ils l’utilisent. S’ils ne savent pas qu’ils utilisent une bibliothèque, ils ne peuvent pas connaître les fonctionnalités de liste. Par exemple, libarchive expose les fonctionnalités qui permettent aux algorithmes de compression d’une interface générique existante ; si elles sont créées sans aucune de ces fonctionnalités, la bibliothèque peut ne pas avoir d’utilitaire.

Il faut déterminer soigneusement si une fonctionnalité doit être activée par défaut, car la désactivation des fonctionnalités par défaut est complexe.

La désactivation d’une fonctionnalité par défaut en tant que consommateur « transitif » nécessite :

  • Tous les clients désactivant explicitement les fonctionnalités par défaut via "default-features": false ou inclus [core] dans la liste des fonctionnalités sur la ligne de commande.
  • Nommage de la dépendance transitive sur la vcpkg install ligne de commande ou en tant que dépendance directe dans le manifeste de niveau supérieur

Dans le Registre organisé de vcpkg, si la fonctionnalité ajoute des API supplémentaires, des exécutables ou d’autres fichiers binaires, elle doit être désactivée par défaut. En cas de doute, ne marquez pas une fonctionnalité comme étant par défaut.

N’utilisez pas de fonctionnalités pour contrôler les alternatives dans les interfaces publiées

Si un consommateur d’un port dépend uniquement des fonctionnalités principales de ce port, avec une probabilité élevée qu’ils ne doivent pas être rompus en activant la fonctionnalité. Cela est encore plus important lorsque l’alternative n’est pas directement contrôlée par le consommateur, mais par les paramètres du compilateur comme /std:c++17 / -std=c++17.

Exemples existants que nous n’accepterions pas aujourd’hui conservés pour la compatibilité descendante :

  • redis-plus-plus[cxx17] contrôle un polyfill, mais ne fait pas cuire le paramètre dans l’arborescence installée.
  • ace[wchar] modifie toutes les API à accepter const wchar_t* plutôt que const char*.

Une fonctionnalité peut remplacer des polyfills par des alias, à condition que le remplacement soit cuit dans l’arborescence installée

Malgré les ports ci-dessus, les ports peuvent supprimer des polyfills avec une fonctionnalité, tant que :

  1. L’activation de la fonctionnalité modifie les polyfills en alias de l’entité polyfilled
  2. L’état du polyfill est inséré dans les en-têtes installés, de sorte que les erreurs d’exécution « impossible » ABI ne sont pas probables.
  3. Il est possible pour un consommateur du port d’écrire du code qui fonctionne dans les deux modes, par exemple en utilisant un typedef qui est polyfillé ou non

Exemple :

  • abseil[cxx17] modifications absl::string_view apportées à un remplacement ou std::string_view; le correctif implémente l’exigence de cuisson.

S’il est essentiel d’exposer les alternatives sous-jacentes, nous vous recommandons de fournir des messages au moment de la génération pour indiquer à l’utilisateur comment copier le port dans une superposition privée :

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

Techniques de génération

N’utilisez pas de dépendances fournisseur

N’utilisez pas de copies incorporées de bibliothèques. Toutes les dépendances doivent être fractionnées et empaquetées séparément afin qu’elles puissent être mises à jour et gérées.

Préférer utiliser CMake

Lorsque plusieurs systèmes de build sont disponibles, préférez utiliser CMake. En outre, le cas échéant, il peut être plus facile et plus facile à gérer pour réécrire d’autres systèmes de build dans CMake à l’aide file(GLOB) de directives.

Exemples : abseil

Choisir des fichiers binaires statiques ou partagés

Lorsque vous générez des bibliothèques CMake, vcpkg_cmake_configure() transmettez la valeur correcte en BUILD_SHARED_LIBS fonction de la variante demandée par l’utilisateur.

Vous pouvez calculer d’autres paramètres de configuration à l’aide string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" ...)de .

# 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}
)

Si une bibliothèque n’offre pas d’options de configuration pour sélectionner la variante de build, la build doit être corrigée. Lors de la mise à jour corrective d’une build, vous devez toujours essayer d’optimiser la maintenance future du port. En règle générale, cela signifie réduire le nombre de lignes qui doivent être touchées pour résoudre le problème à la main.

Exemple : Mise à jour corrective d’une bibliothèque CMake pour éviter de générer des variantes indésirables

Par exemple, lors de la mise à jour corrective d’une bibliothèque basée sur CMake, il peut être suffisant d’ajouter à des cibles indésirables et d’encapsuler EXCLUDE_FROM_ALL l’appel install(TARGETS ...) dans un if(BUILD_SHARED_LIBS). Cela sera plus court que l’encapsulage ou la suppression de chaque ligne qui mentionne la variante indésirable.

Pour un projet CMakeLists.txt avec le contenu suivant :

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)

Seule la install(TARGETS) ligne doit être corrigée.

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)

Lors de la définition de fonctionnalités, contrôlez explicitement les dépendances

Lors de la définition d’une fonctionnalité qui capture une dépendance facultative, assurez-vous que la dépendance ne sera pas utilisée accidentellement lorsque la fonctionnalité n’est pas explicitement activée.

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

L’extrait de code ci-dessous est vcpkg_check_features() équivalent.

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 dans l’extrait de code respecte la casse. Pour plus d’informations, consultez la documentation et CMAKE_REQUIRE_FIND_PACKAGE_<PackageName> la CMAKE_DISABLE_FIND_PACKAGE_<PackageName> documentation.

Une bibliothèque est considérée comme conflictuelle si elle effectue l’une des opérations suivantes :

  • Définir main
  • Définir malloc
  • Définir des symboles qui sont également déclarés dans d’autres bibliothèques

Les libs en conflit sont généralement par conception et ne sont pas considérés comme un défaut. Étant donné que certains systèmes de génération sont liés à tout dans le répertoire lib, ceux-ci doivent être déplacés dans un sous-répertoire nommé manual-link.

Contrôle de version

Suivez les conventions courantes pour le "version" champ

Lors de la création d’un port, suivez la convention de contrôle de version utilisée par l’auteur du package. Lors de la mise à jour du port, continuez à utiliser la même convention, sauf indication contraire en amont. Pour obtenir une explication complète de nos conventions, consultez notre documentation de contrôle de version.

Si l’amont n’a pas publié de version dans un certain temps, ne modifiez pas le schéma version-date de contrôle de version du port pour obtenir les dernières modifications. Ces validations peuvent inclure des modifications qui ne sont pas prêtes pour la production. Au lieu de cela, demandez au référentiel en amont de publier une nouvelle version.

Mettre à jour le "port-version" champ dans le fichier manifeste des ports modifiés

vcpkg utilise ce champ pour déterminer si un port donné est obsolète et doit être modifié chaque fois que le comportement du port change.

Notre convention consiste à utiliser le "port-version" champ pour les modifications apportées au port qui ne modifient pas la version en amont et à rétablir la "port-version" valeur zéro lorsqu’une mise à jour vers la version en amont est effectuée.

Par exemple :

  • La version du package de Zlib est actuellement 1.2.1, sans explicite "port-version" (équivalent à un "port-version" de 0).
  • Vous avez découvert que le fichier de copyright incorrect a été déployé et corrigé dans le fichier portfile.
  • Vous devez mettre à jour le "port-version" champ dans le fichier manifeste sur 1.

Pour plus d’informations, consultez la documentation de contrôle de version.

Mettre à jour les fichiers de version dans versions/ tous les ports modifiés

vcpkg utilise un ensemble de fichiers de métadonnées pour alimenter sa fonctionnalité de contrôle de version. Ces fichiers se trouvent à l’emplacement suivant :

  • ${VCPKG_ROOT}/versions/baseline.json, (ce fichier est commun à tous les ports) et
  • ${VCPKG_ROOT}/versions/${first-letter-of-portname}-/${portname}.json (un par port).

Par exemple, pour zlib les fichiers appropriés, vous trouverez les éléments suivants :

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

Nous nous attendons à ce que chaque fois que vous mettez à jour un port, vous mettez également à jour ses fichiers de version.

La méthode recommandée pour mettre à jour ces fichiers consiste à exécuter la x-add-version commande, par exemple :

vcpkg x-add-version zlib

Si vous mettez à jour plusieurs ports en même temps, vous pouvez exécuter :

vcpkg x-add-version --all

pour mettre à jour les fichiers pour tous les ports modifiés à la fois.

Remarque

Ces commandes vous obligent à avoir validé vos modifications sur les ports avant de les exécuter. La raison est que la SHA Git du répertoire de port est requise dans ces fichiers de version. Mais ne vous inquiétez pas, la x-add-version commande vous avertit si vous avez des modifications locales qui n’ont pas été validées.

Pour plus d’informations, consultez la référence de contrôle de version et la création de registres.

Application de correctifs

vcpkg est une solution d’empaquetage, et non les propriétaires ultimes des composants que nous déployons. Nous devons appliquer des correctifs dans certains cas pour améliorer la compatibilité des composants avec des plateformes ou la compatibilité des composants entre eux.

  • Nous voulons éviter les correctifs suivants :
    • en amont ne serait pas d’accord avec
    • provoquer des vulnérabilités ou des blocages
    • nous ne pouvons pas gérer les mises à jour de version en amont
    • sont suffisamment volumineux pour provoquer l’inanglement de licence avec le référentiel vcpkg lui-même

Notifier les propriétaires en amont pour les correctifs pertinents en amont

Si un correctif peut être utile en amont, l’amont doit être averti du contenu du correctif. (Correctifs qui appliquent un comportement spécifique à vcpkg non lié à l’amont, comme la dévendoration d’une dépendance, ne nécessitent pas de notification.)

Pour éviter les situations où l’amont n’est pas d’accord avec le correctif, nous attendons au moins 30 jours pour appliquer ces correctifs.

Nous allons ignorer cette période d’attente si nous avons une grande confiance que le changement est correct. Voici quelques exemples de correctifs à haut niveau de confiance, mais qui ne sont pas limités à :

  • L’acceptation en amont en tant que correctif (par exemple, la rétroportation d’une modification spécifique d’une demande de tirage en amont a fusionné).
  • Ajout de s manquants #include.
  • Correctifs de code de produit petits et évidents (par exemple, initialisation d’une variable non initialisée).
  • Désactivation des composants non pertinents dans vcpkg de la build, tels que des tests ou des exemples.

Préférer les options par rapport à la mise à jour corrective

Il est préférable de définir des options dans un appel pour vcpkg_configure_xyz() corriger directement les paramètres.

Options courantes qui vous permettent d’éviter la mise à jour corrective :

  • [MSBUILD] <PropertyGroup> les paramètres à l’intérieur du fichier projet peuvent être remplacés par le biais /p: de paramètres
  • [CMAKE] Les appels vers find_package(XYz) des scripts CMake peuvent être désactivés via -DCMAKE_DISABLE_FIND_PACKAGE_XYz=ON
  • [CMAKE] Les variables de cache (déclarées en tant que set(VAR "value" CACHE STRING "Documentation") ou option(VAR "Documentation" "Default Value")) peuvent être remplacées en les transmettant simplement sur la ligne de commande en tant que -DVAR:STRING=Foo. Une exception notable est si le FORCE paramètre est passé à set(). Pour plus d’informations, consultez la documentation CMake set

Préférer télécharger les correctifs approuvés par rapport à leur vérification dans le port

Si un fichier patch approuvé ou fusionné peut être obtenu en amont, les ports doivent essayer de les télécharger et de les appliquer au lieu de les avoir dans le cadre des fichiers de port. Ce processus est préférable, car il :

  • Confirme que l’amont a accepté les modifications des correctifs
  • Simplifie le processus d’examen en déplaçant les charges en amont
  • Réduit la taille du référentiel vcpkg pour les utilisateurs qui n’utilisent pas le correctif
  • Évite les conflits de licences avec le référentiel vcpkg

Les correctifs doivent être téléchargés à partir d’un point de terminaison stable pour éviter les conflits SHA. Lors du téléchargement de fichiers correctifs à partir d’une demande de tirage ou d’une validation à partir de GitHub et gitLab, le ?full_index=1 paramètre doit être ajouté à l’URL de téléchargement.

Exemples :

  • 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

Préférer la mise à jour corrective sur la substitution de VCPKG_<VARIABLE> valeurs

Certaines variables précédées VCPKG_<VARIABLE> d’un équivalent CMAKE_<VARIABLE>. Toutefois, toutes ne sont pas transmises à la build de package interne (voir implémentation : chaîne d’outils Windows).

Prenons l’exemple suivant :

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

L’utilisation vcpkgdes chaînes d’outils intégrées fonctionne, car la valeur de VCPKG_<LANG>_FLAGS celle-ci est transférée à la variable appropriée CMAKE_LANG_FLAGS . Toutefois, une chaîne d’outils personnalisée qui n’est pas consciente des vcpkgvariables ne les transférera pas.

En raison de cela, il est préférable de corriger le système de build directement lors de la définition CMAKE_<LANG>_FLAGS.

Réduire les correctifs

Lorsque vous apportez des modifications à une bibliothèque, essayez de réduire le différentiel final. Cela signifie que vous ne devez pas reformater le code source en amont lorsque vous apportez des modifications qui affectent une région. Lors de la désactivation d’un conditionnel, il est préférable d’ajouter une AND FALSE ou && 0 à la condition que de supprimer chaque ligne du conditionnel. Si une grande région doit être désactivée, il est plus court d’ajouter un if(0) ou #if 0 autour de la région au lieu de supprimer chaque ligne du correctif.

N’ajoutez pas de correctifs si le port est obsolète et que la mise à jour du port vers une version publiée plus récente résout le même problème. vcpkg préfère mettre à jour les ports par rapport à la mise à jour corrective des versions obsolètes.

Cela permet de réduire la taille du référentiel vcpkg et d’améliorer la probabilité que le correctif s’applique aux futures versions de code.

N’implémentez pas de fonctionnalités dans les correctifs

L’objectif de la mise à jour corrective dans vcpkg est d’activer la compatibilité avec les compilateurs, les bibliothèques et les plateformes. Il n’est pas nécessaire d’implémenter de nouvelles fonctionnalités au lieu de suivre une procédure Open Source appropriée (envoi d’un problème/pr/etc.).

Ne pas générer de tests/docs/exemples par défaut

Lors de l’envoi d’un nouveau port, recherchez les options telles BUILD_TESTS ou WITH_TESTS ou POCO_ENABLE_SAMPLES vérifiez que les fichiers binaires supplémentaires sont désactivés. Cela réduit les temps de génération et les dépendances pour l’utilisateur moyen.

Si vous le souhaitez, vous pouvez ajouter une test fonctionnalité qui permet de générer les tests, mais cela ne doit pas figurer dans la Default-Features liste.

Permettre aux utilisateurs existants de la bibliothèque de basculer vers vcpkg

Ne pas ajouter CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS

Sauf si l’auteur de la bibliothèque l’utilise déjà, nous ne devons pas utiliser cette fonctionnalité CMake, car elle interagit mal avec les modèles C++ et interrompt certaines fonctionnalités du compilateur. Les bibliothèques qui ne fournissent pas de fichier .def et n’utilisent pas les déclarations __declspec() ne prennent simplement pas en charge les builds partagées pour Windows et doivent être marquées comme telles avec vcpkg_check_linkage(ONLY_STATIC_LIBRARY).

Ne renommez pas les fichiers binaires en dehors des noms donnés par l’amont

Cela signifie que si la bibliothèque en amont a des noms différents dans la version et le débogage (libx et libxd), la bibliothèque de débogage ne doit pas être renommée libxen . Inversement, si la bibliothèque en amont porte le même nom dans la version et le débogage, nous ne devrions pas introduire de nouveau nom.

Mise en garde importante :

  • Les variantes statiques et partagées doivent souvent être renommées en schéma commun. Cela permet aux consommateurs d’utiliser un nom commun et d’ignorer la liaison en aval. Cela est sûr, car nous ne rendons qu’un seul à la fois disponible.

Si une bibliothèque génère des fichiers d’intégration CMake (foo-config.cmake), le renommage doit être effectué par le biais de la mise à jour corrective de la build CMake elle-même au lieu d’appeler file(RENAME) simplement les archives/liBs de sortie.

Enfin, les fichiers DLL sur Windows ne doivent jamais être renommés après la génération, car ils interrompent les bases de données générées.

Manifestes

Nous exigeons que le fichier manifeste soit mis en forme. Utilisez la commande suivante pour mettre en forme tous les fichiers manifestes :

> vcpkg format-manifest --all

Triplés

Nous n’acceptons pas les demandes d’ajout de triplets non communautaires pour l’instant. La promotion de la communauté au triplet complet est principalement basée sur le budget du matériel pour tester ces triplets et sera pilotée par les métriques soumises par vcpkg pour maximiser la probabilité que les personnes utilisent réellement sont entièrement testées.

Nous ajouterons des triplets communautaires si :

  • Il est démontré que les gens utiliseront réellement ce triplet communautaire ; et
  • nous ne savons pas qu’un tel triplet est cassé.

Par exemple, nous n’avons pas ajouté de triplet car https://github.com/microsoft/vcpkg/pull/29034 l’auteur essayait simplement de « terminer l’ensemble » plutôt que de indiquer qu’ils utiliseraient réellement une telle chose, et nous n’avons pas ajouté linux-dynamic tant que la solution patchelf n’a pas été créée pour que les résultats soient déplacés.

Notes d’implémentation utiles

Les fichiers de port sont exécutés en mode script

Tandis que portfile.cmake's et’s CMakeLists.txtpartagent une syntaxe commune et des constructions de langage CMake principales (appelées « commandes de script »), les fichiers portfiles s’exécutent en « mode script », tandis que CMakeLists.txt les fichiers s’exécutent en « mode projet ». La différence la plus importante entre ces deux modes est que « Mode script » n’a pas les concepts de « Chaîne d’outils », « Language » et « Target ». Tous les comportements, y compris les commandes de script, qui dépendent de ces constructions (par exemple CMAKE_CXX_COMPILER, , CMAKE_EXECUTABLE_SUFFIX, CMAKE_SYSTEM_NAME) ne sont pas corrects.

Les fichiers de port ont un accès direct aux variables définies dans le fichier triplet, mais CMakeLists.txtne le font pas (bien qu’il y ait souvent une traduction qui se produit -- VCPKG_LIBRARY_LINKAGE par rapport BUILD_SHARED_LIBSà ).

Les fichiers de port et les builds Project appelés par les fichiers de port sont exécutés dans différents processus. Conceptuellement:

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

Pour déterminer l’hôte dans un portfile, les variables CMake standard sont correctes (CMAKE_HOST_WIN32).

Pour déterminer la cible dans un fichier de port, les variables triplet vcpkg doivent être utilisées (VCPKG_CMAKE_SYSTEM_NAME).

Consultez également notre documentation triplet pour obtenir une énumération complète des paramètres possibles.