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 boringssl
la 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-cpp
libip
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 :
vcpkg_extract_source_archive_ex()
doit être remplacé par la surcharge prise en charge devcpkg_extract_source_archive()
(parARCHIVE
)- La surcharge déconseillée de
vcpkg_extract_source_archive()
sansARCHIVE
doit être remplacée par la surcharge prise en charge parARCHIVE
. vcpkg_apply_patches()
doit être remplacé par lesPATCHES
arguments des helpers « extract » (par exemplevcpkg_from_github()
)vcpkg_build_msbuild()
doit être remplacé parvcpkg_install_msbuild()
vcpkg_copy_tool_dependencies()
doit être remplacé parvcpkg_copy_tools()
vcpkg_configure_cmake
doit être remplacé parvcpkg_cmake_configure()
après la suppressionPREFER_NINJA
vcpkg_build_cmake
doit être remplacé parvcpkg_cmake_build()
vcpkg_install_cmake
doit être remplacé parvcpkg_cmake_install()
vcpkg_fixup_cmake_targets
doit être remplacé parvcpkg_cmake_config_fixup
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-vcpkgunofficial::<port>::<target>
en tant que cible exportée à partir de ce port.
Exemples :
brotli
crée le package, produisant launofficial-brotli
cibleunofficial::brotli::brotli
.
Installer le fichier de copyright
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
,libzip
toutesopen62541
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
aopencv2
,opencv3
fonctionnalité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 unepublic-preview
fonctionnalité. imgui
a uneexperimental-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 à accepterconst wchar_t*
plutôt queconst 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 :
- L’activation de la fonctionnalité modifie les polyfills en alias de l’entité polyfilled
- 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.
- 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]
modificationsabsl::string_view
apportées à un remplacement oustd::string_view
; le correctif implémente l’exigence de cuisson.
Solutions recommandées
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.
Placer des bibliothèques en conflit dans un manual-link
répertoire
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"
de0
). - 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 sur1
.
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")
ouoption(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 leFORCE
paramètre est passé àset()
. Pour plus d’informations, consultez la documentation CMakeset
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 vcpkg
des 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 vcpkg
variables 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 libx
en . 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.txt
partagent 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.txt
ne 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.