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 de fmt
et de 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 :
Créez le répertoire de build du projet.
PS D:\versions-test> mkdir build PS D:\versions-test> cd build
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 ...
Générez le projet.
PS D:\versions-test\build> cmake --build . [2/2] Linking CXX executable main.exe
Exécutez-le !
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 de port dans ports/
, vcpkg recherche les fichiers pour chaque version dans buildtrees/versioning/versions/
. Les fichiers de ports/
sont toujours utilisés lors de l’exécution de vcpkg en mode classique.
Note
La sortie de vcpkg lors de la configuration de CMake est disponible uniquement lors de l’utilisation de la version CMake 3.18
ou une version ultérieure. Si vous utilisez un ancien CMake, vous pouvez vérifier le fichier vcpkg-manifest-install.log
dans votre répertoire de build à la place.
Lisez notre billet de blog annonces de manifestes pour apprendre à 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 des versions que pour vos projets à l’aide de la propriété version-string
. Maintenant que le contrôle de version est venu, vcpkg est conscient de certains nouveaux schémas de gestion de version.
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 cadre des déclarations de "dependencies"
. 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, si zlib
devaient déclarer une dépendance sur fmt
version 7.1.4
, vcpkg installerait 7.1.4
à la place.
vcpkg utilise une approche de version minimale, dans notre exemple, même si fmt
version 8.0.0
devaient être publiées, 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 ligne de base est nécessaire pour activer le contrôle de version ; sinon, vous obtiendrez les versions actuelles dans le répertoire ports/
. 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 documentation "builtin-baseline"
.
Dans notre exemple, nous ne déclarons pas de contrainte de version pour zlib
; Au lieu de cela, la version est extraite de la base de référence. En interne, vcpkg recherche dans la validation 3426db05b996481ca31e95fff3734cf23e0f51bc
pour savoir quelle version de zlib
a été la dernière à 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"
}
] }
Note
La valeur 1.2.11#7
représente la version 1.2.11
, la version du port 7
.
Étant donné que la base de référence introduit une contrainte de version minimale pour zlib
à 1.2.11#9
et qu’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 bibliothèques boost
, il est plus pratique de définir la baseline
une fois que la déclaration d’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
forcera vcpkg à utiliser la version exacte déclarée, point.
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 que le fmt
est maintenant à la 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 rendre votre propre registre personnalisé.
Lecture plus poussée
Si vous souhaitez approfondir les détails du fonctionnement du contrôle de version, nous vous recommandons de lire nos de référence de contrôle de version et de concepts de contrôle de version.