Guide de maintenance

Ce document décrit les stratégies, les instructions et les bonnes pratiques à suivre lors de la contribution à vcpkg.

Il est destiné à servir le même rôle que :

Objectifs de conception de registre soigneusement sélectionné

Les ports doivent être installés simultanément

Un port inclus dans le Registre organisé doit être généré correctement en présence de tous les autres ports du Registre. La combinaison complète de ports est testée régulièrement par l'intégration continue automatisée de vcpkg.

Un port ne doit pas effectuer l’une des opérations suivantes :

Les exceptions sont effectuées pour :

  • Ports qui remplacent un autre port à titre officiel. Cela inclut les cas où :
    • Le même projet publie un composant successeur.
    • Un autre projet prend le relais de la maintenance d’un composant abandonné, y compris par le biais d’un fork.
    • Un autre projet publie un composant de remplacement.
  • Ports où il n’y a pas de chevauchement de plateforme. Par exemple, un remplacement Windows uniquement pour un composant Linux qui ne prend pas en charge Windows.
  • Ports qui précèdent cette politique et qui ont un nombre d'utilisateurs et de contributeurs significatif et démontrable.

Les mainteneurs de vcpkg évaluent les exceptions de droits acquis au cas par cas. Par exemple, boringssl a été ajouté avant que les registres personnalisés ne soient disponibles et reste dans le registre organisé, car il a toujours un nombre d’utilisateurs important, même si openssl est le fournisseur canonique pour la famille de duplications OpenSSL. L’acceptation préalable seule ne garantit pas une exception.

Les ports qui ne sont pas conformes à cette stratégie ne peuvent pas être acceptés dans le registre organisé.

Conseil / Astuce

Si votre port ne peut pas être inclus dans le registre organisé, envisagez de publier un registre personnalisé ou d’utiliser un port de superposition.

Les ports doivent être testés dans au moins un triplet officiel

Tous les ports du registre organisé doivent être testés dans CI pour au moins un triplet officiel.

Les exceptions sont effectuées pour :

  • Circonstances temporaires, telles que :
    • Le port ne se construit pas sans mise à jour de l’infrastructure CI.
    • Le port ne se génère pas en raison d’une modification majeure récente dans une dépendance en amont, et des travaux sont en cours pour résoudre le problème.
  • Ports qui précèdent cette politique et qui ont un nombre d'utilisateurs et de contributeurs significatif et démontrable.

Les nouveaux ports qui ne peuvent pas être testés dans au moins un triplet officiel ne sont pas acceptés dans le répertoire organisé. Les ports existants qui ne sont plus conformes à cette politique et qui ne sont pas éligibles à une exception répertoriée ci-dessus sont retirés du registre. Par exemple, si les tests CI ont été désactivés sur chaque triplet officiel pris en charge par un port et qu’aucune exception ne s’applique, le port est retiré de la liste.

Conseil / Astuce

Si votre port ne peut pas être inclus dans le registre organisé, envisagez de publier un registre personnalisé ou d’utiliser un port de superposition.

Les composants empaquetés doivent être stables et gérés activement

Les composants empaquetés dans le registre organisé doivent être en maintenance active. Les ports des composants inactifs peuvent être délistés.

Un composant est considéré comme inactif si :

  • Ses mainteneurs ont déclaré le composant abandonné.
  • Son référentiel source est archivé ou n’accepte plus de contributions.
  • Les responsables de maintenance ne répondent pas ou ne sont pas accessibles.
  • Aucune modification significative n’a été apportée depuis longtemps.

Des exceptions sont prévues pour les composants fondamentaux considérés comme matures et stables et font rarement l’objet de modifications. Par exemple : zlib.

Les composants packagés doivent avoir atteint un niveau de maturité suffisant

Les composants empaquetés dans le registre organisé doivent être matures et destinés aux utilisateurs de vcpkg. Les composants destinés à une utilisation personnelle doivent être publiés dans des registres personnalisés.

Un composant est considéré comme suffisamment mature pour le registre organisé, si l’un de ces énoncés est vrai :

  • Le composant a une publication dont la date remonte à au moins six mois.
  • Le composant fait preuve d’au moins six mois de développement public actif.
  • Le composant est une partie officielle d’un projet avec au moins six mois de versions ou un développement public actif. Par exemple, une nouvelle bibliothèque Boost ou un nouveau composant Qt.
  • Le composant illustre une maturité équivalente aux exigences précédentes à un autre titre.

Voici quelques indicateurs de l’immaturité des composants :

  • Le composant ne s’affiche pas dans les moteurs de recherche.
  • Le composant a des renommages fréquents.
  • Conflits avec d’autres bibliothèques.

Conseil / Astuce

Si votre port ne peut pas être inclus dans le registre organisé, envisagez de publier un registre personnalisé ou d’utiliser un port de superposition.

Structure de demande de tirage

Effectuer des pull requests distinctes par port

Les requêtes de tirage plus petites (les PR) sont plus faciles à examiner. Les demandes de tirage doivent apporter des modifications à un seul port. Cela réduit également les temps d’attente pour les résultats de l’intégration continue (CI).

La limitation des demandes de tirage à un seul port peut ne pas être possible dans certains cas. Par exemple, lors de la modification d’un port, les consommateurs en aval nécessitent une mise à jour ou un correctif.

Éviter les changements cosmétiques non liés

N’apportez pas de modifications cosmétiques sans rapport à un portage par ailleurs non modifié, comme le reformatage, le renommage de variables ou la correction des fautes de frappe. Ces modifications mobilisent du temps de calcul qui serait mieux utilisé ailleurs. Les modifications qui améliorent la validité, la compatibilité, la fiabilité ou la reproductibilité de la compilation ne sont pas considérées comme triviales uniquement parce que les fichiers installés restent inchangés.

Utiliser des noms de port distinctifs

Le nom d’un port doit indiquer son contenu.

La recherche du nom du port dans un moteur de recherche ou des navigateurs de package spécialisés, comme Repology, doit conduire à son composant correspondant.

Les ports portant des noms courts ou nommés après des mots communs nécessitent une ambiguïté. Cela s’applique uniquement au nom du port dans le Registre organisé, le nom du composant empaqueté et son contenu n’ont pas à être conformes à cette politique.

Des exceptions sont prévues pour les ports qui empaquettent un composant avec une association forte au nom de son port. Par exemple : libpng, openssl, ou zlib.

Pour respecter cette stratégie, les nouveaux ports avec des noms ambigus peuvent utiliser un préfixe, par exemple :

  • Propriétaire, nom d’utilisateur ou organisation du référentiel. Exemple : google-cloud-cpp. Pour les ports des composants hébergés sur GitHub, le propriétaire GitHub est un préfixe <github owner>-<repository name>non ambigu acceptable.
  • Nom d’une suite à laquelle appartient le package : boost-dll. Uniquement si le package est un composant officiel d’une telle suite.

Exemple : nom de port ambigu

Un port portant le nom ip est considéré comme ambigu, car :

  • le nom est trop court,
  • le nom est un mot commun, et
  • le nom n’est pas fortement associé à un composant singulier.

Pour déterminer si un nom est ambigu, supprimez les préfixes et suffixes courants suivants utilisés par C++ et les composants open source du nom du port :

  • cpp
  • free
  • lib
  • open
  • chiffres

Par exemple : ip-cpp, libip et ip5, sont ambigus, car ils sont réduits à la même ip tige.

Limiter les opérations de renommage de port

Pour éviter toute confusion pour les utilisateurs, un port ne doit pas être renommé plus d’une fois au cours d’une période de 12 mois.

Utiliser les brouillons de demandes de tirages GitHub

Les brouillons de demandes de tirages GitHub sont un excellent moyen d'obtenir des commentaires sur l'intégration continue ou des retours humains concernant le travail qui n'est pas encore prêt à être fusionné. La plupart des nouvelles demandes de tirages devraient être ouvertes en tant que brouillons et converties en demandes de tirages normales une fois que l'intégration continue est réussie.

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

Un mainteneur de vcpkg peut convertir votre pull request en brouillon pendant le processus d’examen, généralement lors de la demande de modifications ou en laissant des commentaires qui indiquent quand marquer la pull request comme prête à être examinée.

Fermer les demandes de tirage inactives

Un responsable de maintenance vcpkg peut fermer une demande de tirage après avoir attendu l’action du contributeur pendant plus de 60 jours. Le compte à rebours d’inactivité s’exécute uniquement lorsque l’action du contributeur est requise. Elle ne s’exécute pas pendant que la PR attend la vérification du build lab, ou est en attente d’une révision par un mainteneur vcpkg.

Une demande de tirage est prête à être révisée lorsqu’elle :

  • N’a pas de vérifications de demandes de tirages échouées, ou le contributeur demande de l’aide ou justifie les raisons des échecs.
  • N’a pas de modifications ou de clarifications demandées en attente d’un responsable vcpkg.
  • N’a pas de conflits de fusion.

Le compte à rebours commence lorsque la PR entre dans un état qui nécessite une action du contributeur. Cela peut se produire lorsqu’une PR est ouverte avec des problèmes que le contributeur doit résoudre, ou lorsqu’un mainteneur de vcpkg demande des modifications ou des clarifications. Un mainteneur vcpkg peut marquer la pull request comme brouillon lorsqu’une action du contributeur est requise.

Une réponse de fond du contributeur réinitialise le compte à rebours. Si la réponse résout toutes les demandes en attente et que la PR est prête à être examinée, le compte à rebours s’arrête jusqu’à ce qu’une action du contributeur soit de nouveau requise. Si le contributeur ne répond pas dans les 60 jours si une action est requise, la PR est considérée comme obsolète et peut être fermée à la discrétion d’un mainteneur vcpkg.

Fichiers de port

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

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

Certaines des fonctions auxiliaires de remplacement se trouvent dans des « ports d’outils » pour que les utilisateurs puissent fixer leur comportement à des versions précises, afin de figer le comportement des fonctions auxiliaires à une version particulière. Les ports d'outils doivent être ajoutés à votre port "dependencies", 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 réutilisables introduits par la commande create avant de soumettre une demande de tirage.

Utiliser des minuscules pour les chaînes de chiffres hexadécimaux

De nombreuses fonctionnalités de vcpkg reposent sur la comparaison de chaînes de chiffres hexadécimaux. Parmi les exemples, citons les hachages SHA512, les ID de commit Git et les hachages d’objets d’arborescence.

En interne, vcpkg utilise la normalisation en minuscules pour comparer de telles valeurs lorsque la casse n’est pas pertinente. Cependant, les outils construits sur l’infrastructure de vcpkg peuvent ne pas prendre en compte les mêmes considérations. Pour cette raison, nous avons besoin de chaînes hexadécimales

à mettre en minuscules pour plus de cohérence dans les scénarios suivants :

  • Le SHA512 paramètre dans les fonctions d’assistance de vcpkg.
  • Paramètre REF dans les fonctions d’assistance vcpkg, lorsque la valeur est une chaîne hexadécimale.
  • L’objet git-tree dans les fichiers de base de données de version.
  • L’objet sha512 dans le scripts/vcpkg-tools.json fichier.
  • D’autres endroits où la casse de la chaîne hexadécimale n’a pas d’importance.

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, pas deux ports qu’un utilisateur est susceptible d’utiliser simultanément ne peuvent fournir le même fichier. Si un port tente d’installer un fichier déjà fourni par un autre port, 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 namespace 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 dépendre d’une bibliothèque du système et dépendre d’une bibliothèque de vcpkg. À cette fin, nous évitons d’ajouter des exportations CMake ou des cibles à des bibliothèques existantes portant « le nom évident », afin de permettre aux projets 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 le package spécifique à vcpkg
  • unofficial::<port>::<target> en tant que cible exportée à partir de ce port.

Exemples :

  • brotli crée le package, unofficial-brotli produisant la 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 lors de l'utilisation avec les nouveaux ports, mais reste 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 composants. 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 composants indépendants.

Les variables dans MAYBE_UNUSED_VARIABLES doivent s’appliquer à au moins une configuration.

Lors de l’ajout d’une nouvelle variable pour MAYBE_UNUSED_VARIABLES désactiver un avertissement lors de l’étape de configuration de CMake, vous devez ajouter un commentaire expliquant le cas où la nouvelle variable s’applique. Si une variable ne s’applique dans aucune configuration, il est très probable qu’un bogue sous-jacent existe (par exemple, un nom de variable mal orthographié) et que son ajout n’ait aucun effet réel sur la build.

vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
  FEATURES
    windowsfeature WINDOWS_OPTION
)

vcpkg_cmake_configure(
  SOURCE_PATH "${SOURCE_PATH}"
  OPTIONS
    ${FEATURE_OPTIONS}
  MAYBE_UNUSED_VARIABLES
    WINDOWS_OPTION # Applies only on Windows
)

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] et port[featureB] sont installés, alors port[featureA,featureB] doit être installé. 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 cette situation doivent choisir l'une des options disponibles telles qu'exprimées dans vcpkg, et les utilisateurs qui souhaitent un paramètre différent doivent, pour l'instant, utiliser des ports de superposition.

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 des fonctionnalités opencv2, opencv3 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 fonctionnalité experimental-docking qui engage leur branche d'ancrage en préversion, laquelle utilise une validation de fusion liée à chacune de leurs versions numérotées publiques.

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

Note

Une fonctionnalité activée par défaut par le système de génération en amont n’implique pas que la fonctionnalité doit être ajoutée aux default-features entrées. Comme l’objectif prévu n’est default-features pas de modéliser les décisions prises en amont, mais de fournir des commodités pour les utilisateurs en mode classique .

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 savoir qu'il faut énumérer des fonctionnalités. Par exemple, libarchive expose des fonctionnalités qui permettent aux algorithmes de compression de s'intégrer à une interface générique existante ; si la bibliothèque est créée sans aucune de ces fonctionnalités, elle peut ne pas être utile.

Ici, les clients incluent les deux projets utilisateur qui consomment le graphe de packages et les ports en aval dans ce graphe. Les deux expriment leurs exigences de dépendance via la même interface de fonction.

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

Pour désactiver les fonctionnalités par défaut d’une dépendance transitive :

  • Chaque client qui dépend du port doit désactiver ses fonctionnalités par défaut dans sa déclaration de dépendance à l’aide de "default-features": false.
  • Le projet de niveau supérieur doit également nommer directement la dépendance transitive, soit dans son manifeste avec "default-features": false, soit sur la vcpkg install ligne de commande avec [core].

La désactivation des fonctionnalités par défaut n’empêche pas un autre client de demander explicitement n’importe laquelle de ces fonctionnalités.

Pour cette politique, une API est n’importe quelle interface exposée aux consommateurs, y compris les interfaces de bibliothèque, les interfaces de ligne de commande exécutables et d’autres interfaces binaires. Une fonctionnalité peut être activée par défaut lorsqu’elle ajoute un comportement via une API existante, comme la prise en charge d’algorithmes de compression supplémentaires via une interface générique existante.

Dans le Registre organisé de vcpkg, si une fonctionnalité ajoute une API, 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, il est très probable qu'il n'en soit pas affecté par l'activation de 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 n'intègre pas le paramètre dans l’arborescence installée.
  • ace[wchar] modifie toutes les API pour accepter const wchar_t* plutôt que const char*.

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

Nonobstant ce qui précède, les ports peuvent supprimer des polyfills avec une fonctionnalité, tant que :

  1. L’activation de la fonctionnalité transforme les polyfills en alias de l’entité polyremplie
  2. L’état du polyfill est inséré dans les en-têtes installés, rendant les erreurs d’exécution ABI « impossibles » peu 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] apporte des modifications absl::string_view à un remplacement ou std::string_view ; le correctif met en œuvre l’exigence de baking.

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 construction

N’utilisez pas de dépendances fournies par un tiers

Préférez empaqueter les dépendances séparément afin que les utilisateurs puissent les sélectionner et les mettre à jour via vcpkg. Les dépendances embarquées présentent plusieurs défis :

  • Difficulté à mettre à jour : Les dépendances intégrées sont plus difficiles à suivre et à mettre à jour, notamment lors de l’application de correctifs de sécurité.
  • Conflits de symboles : Une dépendance embarquée peut définir les mêmes symboles qu’une autre version de la dépendance, provoquant des erreurs d’exécution ou un comportement non défini.
  • Conformité des licences : Les dépendances intégrées peuvent masquer les exigences de licence ou créer des problèmes de compatibilité de licence.
  • Maintenance accrue : La synchronisation des dépendances intégrées avec leurs versions en amont augmente le travail de maintenance et peut dupliquer le travail d’un port à l’autre.

Pour ces raisons, supprimez les dépendances fournisseurs chaque fois que cela est possible. Les dépendances intégrées ne doivent pas être exposées au domaine de liaison d’un utilisateur.

Un domaine de liaison est l’ensemble de symboles qui peuvent être résolus les uns avec les autres au moment de l’exécution. Sur Windows, chaque DLL a généralement son propre domaine de liaison. Sur les plateformes avec une table de symboles à l’échelle du processus, le domaine de liaison inclut généralement l’ensemble du processus.

Si un composant expose une dépendance embarquée au même domaine de liaison qu’une dépendance sélectionnée via vcpkg, les deux copies peuvent définir les mêmes symboles. Cela enfreint la règle de définition unique et peut entraîner des erreurs d’exécution ou un comportement non défini. Le problème peut apparaître uniquement lorsque les deux versions diffèrent suffisamment pour être incompatibles.

Une dépendance fournisseur est autorisée uniquement lorsqu’elle est entièrement isolée des domaines de liaison utilisés par les ports dépendants et les applications utilisateur. Par exemple, un outil de compilation réservé à l’hôte peut contenir une dépendance liée statiquement si les fichiers binaires en aval ne sont pas édités de liens avec l’outil et que les symboles de la dépendance ne peuvent pas être introduits dans leurs domaines d’édition de liens.

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 simple et plus facile à gérer de réécrire d’autres systèmes de build dans CMake à l’aide de directives file(GLOB).

Exemples : abseil

Choisir des fichiers binaires statiques ou partagés

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

Vous pouvez calculer d'autres paramètres de configuration à l'aide de 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}
)

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 en question.

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 EXCLUDE_FROM_ALL aux cibles indésirables et d’encapsuler 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)

Remplacez la install(TARGETS) ligne par un bloc conditionnel qui exclut également la cible indésirable de la build par défaut :

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 utilisant vcpkg_check_features() est é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 CMAKE_DISABLE_FIND_PACKAGE_<PackageName> et la documentation CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>.

Un fichier d’entrée de l’éditeur de liens installé dans lib ou debug/lib, tel qu’un fichier .lib, .dylib, .a ou .so, est considéré comme conflictuel s’il effectue l’une des opérations suivantes :

  • Définit main.
  • Définit malloc.
  • Définit des symboles également définis dans d’autres bibliothèques.

Certains fichiers d’entrée de l’éditeur de liens fournissent intentionnellement des remplacements limités pour les symboles que les consommateurs définiraient autrement ou obtiendraient ailleurs. Par exemple, main de Google Test fournit gtest-main.lib pour des exécutables de test dont les auteurs choisissent de l’utiliser au lieu de définir leur propre point d’entrée.

Placez les fichiers d’entrée de l’éditeur de liens en conflit dans debug/lib/manual-link ou lib/manual-link afin que les systèmes de génération qui lient automatiquement des fichiers depuis le répertoire de bibliothèque ne les sélectionnent pas. Les DLL Windows restent dans bin ou debug/bin ; placez leurs bibliothèques d’importation dans manual-link lorsque la liaison explicite est requise. Les utilisateurs doivent explicitement choisir de lier ces fichiers et doivent éviter les définitions contradictoires. Cette exception n’est pas un mécanisme général permettant d’empaqueter des fournisseurs alternatifs d’un autre composant, et le déplacement d’un fichier d’entrée de l’éditeur de liens dans manual-link n’isole pas ses symboles du domaine de liaison du consommateur.

Installation de fichiers binaires prédéfinis

Les ports qui installent des artefacts prédéfinis (binaires uniquement) sont autorisés, mais fortement déconseillés, à condition que les artefacts n’empêchent pas les utilisateurs de sélectionner ou de mettre à jour des dépendances via vcpkg. La compilation à partir des sources est préférée, car elle respecte les paramètres vcpkg qui contrôlent le compilateur et les options.

Nous rejetterons les ports qui répondent à toutes les conditions suivantes :

  1. Installez des fichiers binaires prédéfinis plutôt que de générer à partir de la source et
  2. Ces fichiers binaires incorporent ou nécessitent des dépendances au moment de l’exécution fournies par d’autres ports dans le registre organisé et
  3. Les artefacts installés exposent ces dépendances à un domaine d’édition de liens qui peut également contenir des versions sélectionnées via vcpkg.

Cette combinaison verrouille efficacement le graphe de dépendances aux versions utilisées lorsque la version précompilée amont a été produite. Si vcpkg met à jour une dépendance telle que zlib ou openssl, les versions précompilées et sélectionnées par l’utilisateur peuvent définir des symboles incompatibles dans le même domaine de liaison. Cela peut entraîner des violations de la règle de la définition unique (ODR), des incompatibilités ABI ou des mises à jour de sécurité manquées.

Un artefact expose une dépendance chaque fois que cette dépendance participe au domaine de liaison d’un utilisateur, que l’amont ait ou non l’intention de l’exposer. Cela inclut les éléments suivants :

  • Les bibliothèques .lib, .a, .so, .dylib pouvant être liées par le consommateur ou les bibliothèques d’importation qui placent la dépendance dans le domaine de liaison de l’utilisateur.
  • En-têtes installés qui référencent (directement ou via du code inline/modèle) des symboles, des types ou des macros à partir d’autres ports vcpkg.
  • Fichiers de configuration CMake ou pkg-config installés qui appellent find_dependency() ou Requires: sur d’autres ports vcpkg.

Scénarios autorisés (mais toujours déconseillés) :

  • Outils d’assistance réservés à l’hôte utilisés au moment de la génération dont les sorties sont consommées, mais auxquels les ports dépendants ne sont pas liés, à condition qu’ils isolent les dépendances groupées ou s’appuient uniquement sur des bibliothèques de runtime système omniprésentes.
  • Les bibliothèques prédéfinies dont les dépendances groupées restent entièrement dans des domaines de liaison distincts et n’apparaissent pas dans les en-têtes installés ou les interfaces exportées. La liaison statique seule n’isole pas une dépendance de l’espace de liens d’un utilisateur.
  • Les packages de données uniquement, de microprogramme ou de ressources ne sont pas liés au code utilisateur.

Exemples interdits :

  • Bibliothèque prédéfinie qui lie statiquement une copie privée de zlib et expose ses symboles à un domaine de liaison qui peut également contenir la version zlib sélectionnée via vcpkg.
  • Un libfoo prédéfini qui installe lib/libfoo.lib ainsi que les en-têtes, y compris <zlib.h>, et qui a été compilé contre une version spécifique zlib ; les consommateurs créent ensuite des liens avec libfoo en espérant la compatibilité.
  • Kit de développement logiciel (SDK) prédéfini qui installe un fichier de package CMake appelant find_dependency(OpenSSL) alors que le fichier binaire a été compilé sur une version antérieure d’OpenSSL.

Atténuations / alternatives :

  • Fournissez une construction à partir du code source en utilisant des scripts en amont ou ajoutez un wrapper CMake mince.
  • Demandez au projet source de publier une version basée sur la source ou des instructions de construction reproductibles ; faites référence au problème/à la demande de tirage en amont dans un commentaire dans portfile.cmake ou vcpkg.json.
  • Utilisez un port de superposition ou un registre privé pour les prédéfinis spécifiques à l’organisation qui ne peuvent pas satisfaire ces règles.

Gestion des versions

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 depuis un certain temps, ne modifiez pas le système de gestion des versions du port à version-date pour obtenir les dernières modifications. Ces commits 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 champ "port-version" pour chaque port modifié

Chaque pull request qui modifie un port doit produire une nouvelle version de ce port. Les PR sont fusionnées par squash, donc mettez à jour la version de chaque port modifié une seule fois par PR, et non une fois par commit ou par révision de revue.

Si la version en amont n’a pas changé, incrémentez le champ "port-version". Si la version en amont a changé, réinitialisez "port-version" à zéro en supprimant le champ ou en le définissant sur 0.

Par exemple :

  • La version du paquet Zlib est actuellement 1.2.1, sans "port-version" explicite (é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/ pour chaque port modifié

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 pertinents sont :

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

Pour chaque port modifié dans une PR, mettez à jour ses fichiers de version pour enregistrer l’arborescence Git finale. Si vous apportez d’autres modifications lors de la révision, exécutez vcpkg x-add-version <port-name> --overwrite-version pour actualiser l’entrée de version non fusionnée

sans incrémenter "port-version" à nouveau.

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.

Pour plus d’informations, consultez les articles Référence sur le contrôle de version et 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 de recourir aux correctifs qui :
    • 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'enchevêtrement de licence avec le référentiel vcpkg lui-même

Notification préalable et périodes d’attente

Les responsables amont sont les derniers arbitres du comportement de leur composant. Les responsables de maintenance de vcpkg exigent que le projet amont soit informé des correctifs pertinents pour l’amont et des bugs identifiés par des outils d’examen de code par IA dans les nouvelles soumissions de port.

Correctifs pertinents pour l’amont

Si un correctif peut être utile en amont, les mainteneurs de vcpkg exigent que l’amont soit informé du contenu du correctif. Les correctifs qui appliquent un comportement spécifique à vcpkg non lié à upstream, tels que la dévendoration d’une dépendance, ne nécessitent pas de notification.

Pour éviter les situations où le projet amont n’est pas d’accord avec le correctif, les mainteneurs de vcpkg attendent au moins 30 jours après avoir notifié le projet amont avant d’appliquer ces correctifs.

Les mainteneurs de vcpkg ignorent cette période d’attente s’ils ont la ferme conviction que la modification est correcte. Voici quelques exemples de correctifs à haut niveau de confiance, mais qui ne sont pas limités à :

  • L'acceptation en amont comme correctif (par exemple, le rétroportage d'une modification spécifique à partir d'une demande de tirage que le dépôt en amont a fusionné).
  • Ajout des éléments 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.

Bugs identifiés par l’IA dans de nouveaux ports

Le registre organisé vise à éviter l’expédition de code exploitable connu, mais les mainteneurs de vcpkg ne peuvent pas auditer de manière exhaustive le code source de chaque composant. Les résultats de la révision du code IA ne sont pas, par eux-mêmes, une détermination finale selon laquelle le code en amont est vulnérable.

Lorsque les outils de révision de code IA identifient un bogue lors de l’examen d’une nouvelle soumission de port, les responsables de vcpkg exigent que le bogue soit signalé en amont, en suivant le processus de signalement de sécurité du projet pour les bogues potentiellement exploitables. Cette exigence s’applique même lorsque le constat concerne le code en amont que le port ne corrige pas.

  • Si l’amont détermine que le comportement signalé n’est pas un bug, les mainteneurs de vcpkg acceptent cette détermination comme finale et ne rejettent pas la nouvelle soumission de port sur la base de cette conclusion.
  • Si l’amont corrige le bogue, les mainteneurs de vcpkg acceptent la version corrigée ou un correctif approuvé en amont, soumis à la politique de correctifs et aux autres exigences pour les nouveaux ports.
  • Si le projet amont ne répond pas dans les 30 jours suivant le signalement du bogue, les mainteneurs de vcpkg traitent par défaut le signalement de l’IA comme un problème exploitable et ferment la nouvelle soumission de port.

Les exceptions très fiables à la période d’attente des correctifs ne dispensent pas de cette exigence de création de rapports de bugs ni de la nécessité d’une réponse en amont.

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

Il est préférable de définir des options dans un appel à vcpkg_configure_xyz() plutôt que de modifier 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 les paramètres /p:
  • [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 correctif approuvé ou fusionné peut être obtenu à partir d’un commit en amont, téléchargez-le et appliquez-le au lieu de l’intégrer au port. Ce processus est préférable, car il :

  • Confirme que upstream a accepté les modifications du patch.
  • Simplifie le processus d’examen en déplaçant le fardeau 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.

Téléchargez les correctifs uniquement à partir d’URL épinglées à un ID de validation complet, et non à partir d’URL de demande de tirage ou de fusion dont le contenu peut changer. Lors du téléchargement d’un patch de commit à partir de GitHub ou GitLab, ajoutez ?full_index=1 à l’URL. Ce paramètre demande des ID d’objet complets dans le diff ; il ne rend pas immuable une URL mutable.

Par exemple:

https://github.com/linux-audit/audit-userspace/commit/f8e9bc5914d715cdacb2edc938ab339d5094d017.patch?full_index=1

Préférez le correctif plutôt que la substitution des valeurs VCPKG_<VARIABLE>

Certaines variables préfixées par VCPKG_<VARIABLE> ont 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}")

En utilisant les chaînes d'outils intégrées de vcpkg, cela fonctionne car la valeur de VCPKG_<LANG>_FLAGS 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 ne s'agit pas d'implémenter de nouvelles fonctionnalités au lieu de suivre la procédure Open Source appropriée (soumission d’un problème/d’une demande de tirage, 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 tout simplement pas en charge les builds partagées pour Windows et doivent être marquées comme telles :

if(VCPKG_TARGET_IS_WINDOWS)
    vcpkg_check_linkage(ONLY_STATIC_LIBRARY)
endif()

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 en libx. Inversement, si la bibliothèque en amont porte le même nom dans les versions de publication et de débogage, nous ne devrions pas introduire un 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é en modifiant directement la configuration CMake elle-même, plutôt que simplement appeler file(RENAME) sur les archives/LIBs de sortie.

Enfin, les fichiers DLL sur Windows ne doivent jamais être renommés après la compilation, car cela casse les fichiers de bibliothèque générés.

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 du statut communautaire au statut de triplet complet est principalement basée sur le budget du matériel nécessaire pour tester ces triplets et sera guidée par les métriques soumises par vcpkg pour maximiser la probabilité que ce que les gens utilisent réellement soit entièrement testé.

Nous ajouterons des triplets communautaires si :

  • Il est démontré que les gens utiliseront réellement ce triplet communautaire ; et
  • nous ignorons qu'un tel triplet est cassé.

Par exemple, nous n'avons pas ajouté de triplet dans https://github.com/microsoft/vcpkg/pull/29034 car l'auteur essayait simplement de "compléter l'ensemble" plutôt que d'indiquer qu'ils utiliseraient réellement une telle chose, et nous n'avons pas ajouté linux-dynamic tant que la solution patchelf pour rendre les résultats déplaçables n'a pas été créée.

Notes d’implémentation utiles

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

Tandis que les constructeurs de portfile.cmake et CMakeLists.txt partagent une syntaxe commune et des constructions principales du langage CMake (appelées « commandes de script »), les portfiles s'exécutent en « mode script », alors que les fichiers CMakeLists.txt 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 du triplet pour obtenir une énumération complète des paramètres possibles.