Partager via


Prise en main du contrôle de version

Utilisation de versions avec des manifestes

Commençons par créer un projet CMake simple qui dépend fmt et zlib.

Créez un dossier avec les fichiers suivants :

vcpkg.json

{
    "name": "versions-test",
    "version": "1.0.0",
    "dependencies": [
        {
            "name": "fmt",
            "version>=": "7.1.3#1"
        }, 
        "zlib"
    ],
    "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc"
}

main.cpp

#include <fmt/core.h>
#include <zlib.h>

int main()
{
    fmt::print("fmt version is {}\n"
               "zlib version is {}\n", 
               FMT_VERSION, ZLIB_VERSION);
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.18)

project(versionstest CXX)

add_executable(main main.cpp)

find_package(ZLIB REQUIRED)
find_package(fmt CONFIG REQUIRED)
target_link_libraries(main PRIVATE ZLIB::ZLIB fmt::fmt)

Et maintenant, nous créons et exécutons notre projet avec CMake :

  1. Créez le répertoire de build du projet.

    PS D:\versions-test> mkdir build
    PS D:\versions-test> cd build
    
  2. Configurez CMake.

    PS D:\versions-test\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake ..
    -- Running vcpkg install
    Detecting compiler hash for triplet x86-windows...
    The following packages will be built and installed:
        fmt[core]:x64-windows -> 7.1.3#1 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\fmt\4f8427eb0bd40da1856d4e67bde39a4fda689d72
        vcpkg-cmake[core]:x64-windows -> 2021-02-26 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\vcpkg-cmake\51896aa8073adb5c8450daa423d03eedf0dfc61f
        vcpkg-cmake-config[core]:x64-windows -> 2021-02-26 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\vcpkg-cmake-config\d255b3d566a8861dcc99a958240463e678528066
        zlib[core]:x64-windows -> 1.2.11#9 -- D:\Work\viromer\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4
    ...
    
  3. Créez le projet.

    PS D:\versions-test\build> cmake --build .
    [2/2] Linking CXX executable main.exe
    
  4. Exécutez-la !

    PS D:\versions-test\build> ./main.exe
    fmt version is 70103
    zlib version is 1.2.11
    

Examinez la sortie :

fmt[core]:x86-windows -> 7.1.3#1 -- D:\vcpkg\buildtrees\versioning\versions\fmt\4f8427eb0bd40da1856d4e67bde39a4fda689d72
...
zlib[core]:x86-windows -> 1.2.11#9 -- D:\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4

Au lieu d’utiliser les fichiers portfiles dans ports/, vcpkg est case activée sortie des fichiers pour chaque version dans buildtrees/versioning/versions/. Les fichiers en ports/ cours d’utilisation sont toujours utilisés lors de l’exécution de vcpkg en mode classique.

Remarque

La sortie de vcpkg lors de la configuration de CMake est disponible uniquement lors de l’utilisation de la version de CMake ou d’une version 3.18 ultérieure. Si vous utilisez un CMake plus ancien, vous pouvez case activée le fichier dans votre répertoire de build à la vcpkg-manifest-install.log place.

Lisez notre billet de blog d’annonce de manifestes pour découvrir comment utiliser des manifestes avec MSBuild.

Modifications du manifeste

Si vous avez utilisé des manifestes avant de remarquer qu’il existe de nouvelles propriétés JSON. Examinons ces modifications :

version

{
    "name": "versions-test",
    "version": "1.0.0"
}

Il s’agit de la déclaration de version de votre projet. Auparavant, vous ne pouviez déclarer que des versions pour vos projets à l’aide de la version-string propriété. Maintenant que le contrôle de version est venu, vcpkg est conscient de certains nouveaux schémas de gestion de version.

Schéma de version Description
version Numériques séparés par des points : 1.0.0.5.
version-semver Versions sémantiques conformes : 1.2.0 et 1.2.0-rc.
version-date Dates au YYYY-MM-DD format : 2021-01-01
version-string Chaînes arbitraires : vista, candy.

version>=

{
    "dependencies": [
        { "name": "fmt", "version>=": "7.1.3" },
        "zlib"
    ]
}

Cette propriété est utilisée pour exprimer des contraintes de version minimales, elle n’est autorisée que dans le "dependencies" cadre des déclarations. Dans notre exemple, nous définissons une contrainte explicite sur la version 7.1.3#1 de fmt.

vcpkg est autorisé à mettre à niveau cette contrainte si une dépendance transitive nécessite une version plus récente. Par exemple, s’il zlib s’agissait de déclarer une dépendance sur fmt la version 7.1.4 , vcpkg s’installerait 7.1.4 à la place.

vcpkg utilise une approche de version minimale, dans notre exemple, même si fmt la version 8.0.0 devait être publiée, vcpkg installerait toujours la version 7.1.3#1 , car il s’agit de la version minimale qui satisfait à la contrainte. Les avantages de cette approche sont que vous n’obtenez pas de mises à niveau de dépendance inattendues lorsque vous mettez à jour vcpkg et que vous obtenez des builds reproductibles (en termes de version utilisée) tant que vous utilisez le même manifeste.

Si vous souhaitez mettre à niveau vos dépendances, vous pouvez augmenter la contrainte de version minimale ou utiliser une base de référence plus récente.

builtin-baseline

{ "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc" }

Ce champ déclare la ligne de base de contrôle de version pour tous les ports. La définition d’une base de référence est nécessaire pour activer le contrôle de version ; sinon, vous obtiendrez les versions actuelles sur le ports/ répertoire. Vous pouvez exécuter « git rev-parse HEAD » pour obtenir la validation actuelle de vcpkg et la définir comme base de référence intégrée. Pour plus d’informations, consultez la "builtin-baseline" documentation .

Dans notre exemple, nous ne déclarons pas de contrainte de version pour zlib; à la place, la version est extraite de la base de référence. En interne, vcpkg recherche dans la validation 3426db05b996481ca31e95fff3734cf23e0f51bc pour savoir quelle version d’a zlib été la plus récente à ce moment-là (dans notre cas, c’était 1.2.11#9).

Pendant la résolution de version, les versions de référence sont traitées comme des contraintes de version minimales. Si vous déclarez une contrainte explicite inférieure à une version de référence, la contrainte explicite est mise à niveau vers la version de référence.

Par exemple, si nous avons modifié nos dépendances comme suit :

{ "dependencies": [
    {
        "name": "fmt",
        "version>=": "7.1.3#1"
    },
    {
        "name": "zlib",
        "version>=": "1.2.11#7"
    }
] }

Remarque

La valeur 1.2.11#7 représente la version 1.2.11, la version 7du port .

Étant donné que la base de référence introduit une contrainte de version minimale pour zlib at 1.2.11#9 et une version ultérieure répond à la contrainte de version minimale pour 1.2.11#7, vcpkg est autorisé à la mettre à niveau.

Les bases de référence sont également un mécanisme pratique pour mettre à niveau plusieurs versions à la fois, par exemple, si vous souhaitez dépendre de plusieurs boost bibliothèques, il est plus pratique de définir une baseline seule fois qu’une contrainte de version sur chaque package.

Mais que se passe-t-il si vous souhaitez épingler une version antérieure à la base de référence ?

overrides

Étant donné que les bases de référence établissent un étage de version pour tous les packages et les contraintes explicites sont mises à niveau lorsqu’elles sont inférieures à la base de référence, nous avons besoin d’un autre mécanisme pour rétrograder les versions au-delà de la base de référence.

Le mécanisme vcpkg fournit pour ce scénario overrides. Lorsqu’un remplacement est déclaré sur un package, vcpkg ignore toutes les autres contraintes de version soit directement déclarées dans le manifeste, soit à partir de dépendances transitives. En bref, overrides force vcpkg à utiliser la version exacte déclarée, période.

Nous allons modifier notre exemple une fois de plus, cette fois pour forcer vcpkg à utiliser la version 6.0.0 de fmt.

{
    "name": "versions-test",
    "version": "1.0.0",
    "dependencies": [
        {
            "name": "fmt",
            "version>=": "7.1.3#1"
        },
        {
            "name": "zlib",
            "version>=": "1.2.11#7"
        }
    ],
    "builtin-baseline": "3426db05b996481ca31e95fff3734cf23e0f51bc",
    "overrides": [
        {
            "name": "fmt",
            "version": "6.0.0"
        }
    ]
}

Régénérer notre projet :

PS D:\versions-test\build> rm ./CMakeCache.txt
PS D:\versions-test\build> rm -r ./vcpkg_installed
PS D:\versions-test\build> cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=D:/vcpkg/scripts/buildsystems/vcpkg.cmake ..
-- Running vcpkg install
Detecting compiler hash for triplet x86-windows...
The following packages will be built and installed:
    fmt[core]:x86-windows -> 6.0.0 -- D:\vcpkg\buildtrees\versioning\versions\fmt\d99b6a35e1406ba6b6e09d719bebd086f83ed5f3
    zlib[core]:x86-windows -> 1.2.11#9 -- D:\vcpkg\buildtrees\versioning\versions\zlib\827111046e37c98153d9d82bb6fa4183b6d728e4
...
PS D:\versions-test\build> cmake --build .
[2/2] Linking CXX executable main.exe

Et exécutez-le !

PS D:\versions-test\build> .\main.exe
fmt version is 60000
zlib version is 1.2.11

Notez comment l’est maintenant à la fmt version 6.0.0 comme nous le voulions.

Versions et ports personnalisés

La dernière chose à aborder est la façon dont les ports de superposition interagissent avec la résolution de contrôle de version. La réponse est : ils ne le font pas.

En accédant plus en détail, lorsque vous fournissez une superposition pour un port, vcpkg utilise toujours le port de superposition sans prendre en charge la version contenue dans celui-ci. Les raisons sont deux fois : (1) il est cohérent avec le comportement existant des ports de superposition de masquage complet du port existant, et (2) les ports de superposition ne fournissent pas (et ne sont pas censés) fournir suffisamment d’informations pour alimenter la fonctionnalité de contrôle de version de vcpkg.

Si vous souhaitez avoir une personnalisation de port flexible avec le contrôle de version, vous devez envisager de créer votre propre registre personnalisé.

Pour aller plus loin

Si vous souhaitez approfondir les détails du fonctionnement du contrôle de version, nous vous recommandons de lire nos concepts de référence et de contrôle de version.