[[https://github.com/microsoft/vcpkg/|Site web]] =====Utilisation===== ====Exécution==== C'est un installateur de dépendances en compilant depuis les sources. Il suffit d'ajouter en tant que submodule le projet et de suivre les indications : ===Télécharger le dépôt=== git clone https://github.com/microsoft/vcpkg ===Générer le bootstrap=== Sous Windows : .\vcpkg\bootstrap-vcpkg.bat Sous Linux : .\vcpkg\bootstrap-vcpkg.sh ===Installer les librairies=== ''vcpkg'' peut fonctionner en deux modes : classique ou ''manifest''. En mode classique, il faut passer en ligne de commande la liste des librairies à installer. En mode ''manifest'', un fichier ''vcpkg.json'' va être lu pour extraire la liste des librairies à installer. * Mode classique Il n'est pas possible de sélectionner le mode de fonctionnement. ''vcpkg'' va automatiquement chercher le fichier ''vcpkg.json'' dans les dossiers parents et active le mode ''manifest'' si le fichier est trouvé. vcpkg\vcpkg install --triplet x64-windows --host-triplet x64-windows gtest Si l'architecture de destination n'est pas compatible avec l'architecture de compilation, enlever ''%%--%%triplet-host''. Par exemple: Succès: ''%%./vcpkg install --triplet=x64-linux --host-triplet=x64-linux qt --dry-run%%'' Succès: ''%%./vcpkg install --triplet=x64-linux-dynamic --host-triplet=x64-linux-dynamic qt --dry-run%%'' Succès: ''%%./vcpkg install --triplet=x64-linux qt --dry-run%%'' Échec: ''%%./vcpkg install --triplet=x64-linux-dynamic qt --dry-run%%'' : ''%%qtwebengine is only supported on '!static & !((x86 | arm) & windows)', which does not match x64-linux.%%'' * Mode ''manifest'' Toutes les commandes précédents sont valables si on enlève le nom des paquets à installer (puisque les paquets sont définis dans le fichier ''vcpkg.json''). Si on souhaite installer une librairie qui dépend d'une feature, il faut ajouter l'option ''%%--x-feature=%%''. Pour plusieurs features, il faut plusieurs ''%%--x-feature=XXX --x-feature=YYY%%''. ===Spécificité à Windows=== Si un paquet échoue car la longueur du chemin Windows est trop long avec plus de 255 caractères (par exemple qtwebengine), plutôt que tout effacer et de tout recommencer avec le chemin ''c:\v'', utiliser : subst j: C:\Users\longlonglongpath\vcpkg et travailler directement avec le lecteur ''J''. La liste complète des triplets peut se consulter dans le dossier ''vcpkg/triplets''. Le sous dossier ''community'' indique une disponibilité mais pas une obligation de support officiel. ===Expliciter les dossiers=== Par défault, ''vcpkg'' va chercher le fichier ''vcpkg.json'' dans les dossiers parents. Il est possible d'expliciter l'emplacement des dossiers. Cela peut-être nécessaire pour exécuter ''vcpkg'' depuis Visual Studio. * ''%%--vcpkg-root=%%'' pour spécifier l'emplacement du dépôt ''vcpkg''. * ''%%--x-manifest-root=%%'' pour spécifier l'emplacement des fichiers ''vcpkg.json'' et ''vcpkg-configuration.json'' (facultatif). * ''%%--x-install-root=%%'' pour l'emplacement du dossier d'installation. Il y a d'autres options pour des dossiers spécifiques mais ils sont plus rarement nécessaires (''%%--x-asset-sources=%%'', ''%%--x-buildtrees-root=%%'', ''%%--downloads-root=%%'', ''%%--x-packages-root=%%'', ''%%--x-builtin-ports-root=%%'', ''%%--x-builtin-registry-versions-dir=%%'', ''%%--overlay-triplets=%%''). ====Configuration globale==== Spécifier l'emplacement du dossier de cache : variable ''VCPKG_DEFAULT_BINARY_CACHE''. Ce dossier ne stocke que les fichiers compilés. Le téléchargement se fait en local dans ''vcpkg/download'' et la compilation dans ''vcpkg/buildtrees''. ====Intégration dans une CI==== Ne pas lancer le script bootstrap pour éviter de télécharger ''vcpkg.exe'' à chaque fois. Utiliser les scripts ci-dessous qui va mettre en cache ''vcpkg.exe''. Sous Linux : vcpkg_tag=$(sed -n 's/^VCPKG_TOOL_RELEASE_TAG=\(.*\)/\1/p' < vcpkg/scripts/vcpkg-tool-metadata.txt) if [ ! -f "$VCPKG_CACHE_PATH/vcpkg-$vcpkg_tag" ]; then wget -O "$VCPKG_CACHE_PATH/vcpkg-$vcpkg_tag" "https://github.com/microsoft/vcpkg-tool/releases/download/$vcpkg_tag/vcpkg-glibc" || exit 1; chmod +x "$VCPKG_CACHE_PATH/vcpkg-$vcpkg_tag"; fi cp "$VCPKG_CACHE_PATH/vcpkg-$vcpkg_tag" vcpkg/vcpkg || exit 1 Sous Windows : $vcpkg_tag = (Get-Content vcpkg\scripts\vcpkg-tool-metadata.txt) | Select-String -Pattern '^VCPKG_TOOL_RELEASE_TAG=(.*)' | %{$_.Matches.Groups[1].value} $url="https://github.com/microsoft/vcpkg-tool/releases/download/$vcpkg_tag/vcpkg.exe" $destination="$Env:VCPKG_CACHE_PATH/vcpkg-$vcpkg_tag.exe" if(-not(Test-Path $destination)){Invoke-WebRequest -Uri $url -OutFile $destination} Copy-Item $destination vcpkg/vcpkg.exe ====CMake==== cmake -B [build_directory] -S . -G "Visual Studio 17 2022" -A x64 -DBUILD_SHARED_LIBS=OFF -DVCPKG_TARGET_TRIPLET=x64-windows-static-md -DVCPKG_HOST_TRIPLET=x64-windows-static-md -DCMAKE_TOOLCHAIN_FILE=vcpkg/scripts/buildsystems/vcpkg.cmake cmake --build [build_directory] --config Release Ici, on ne veut pas de librairie partagée pour le projet. Si on veut que cette contrainte s'applique également aux dépendances ''vcpkg'', il est nécessaire d'utiliser le triplet ''x64-windows-static''. Mais comme ''CMake'' par défaut va également mettre les redistribuables de VC en statique, il faut également mettre ''-md''. Si le host est compatible avec la target, il est préférable de mettre le même. Cela évitera à ''vcpkg'' de récupérer tous les binaires pour la target mais également d'autres binaires pour que la compilation se passe bien sur le host. [[https://github.com/microsoft/vcpkg/issues/33040#issuecomment-1669805396|vcpkg creates multiple triplets for packages with no reason]] {{ :prog:vcpkg:vcpkg_creates_multiple_triplets_for_packages_with_no_reason._issue_33040_microsoft_vcpkg_github_24_11_2023_10_20_02_.html |Archive du 08/08/2023 le 24/11/2023}} ====Visual Studio==== Préférer la méthode ''CMake'' La présente méthode va avoir plusieurs conséquences : * Il n'est possible d'avoir qu'un seul dépôt "intégré" (déclaré dans ''C:\Users\xxx\AppData\Local\vcpkg''). * Si un projet dépend d'une librairie qui est compilé en local alors qu'elle est également dans ''vcpkg'' mais avec une version différente, il va y avoir conflit et risque d'erreur de compilation. Cette fonctionnalité permet d'avoir accès au dépôt ''vcpkg'' en natif sans passer par ''CMake''. .\vcpkg\vcpkg integrate install ====Contraintes sur les paquets à installer (version / option de compilation)==== Il peut être nécessaire d'installer une version précise. Ce n'est pas possible de le faire en ligne de commande. Cela se faire par l'ajout d'un fichier ''vcpkg.json'' à la racine du projet. Pour rappel, vcpkg est cloné dans un sous dossier, à la racine du projet. Sans ''vcpkg.json'', il est possible d'installer un paquet via ''vcpkg install paquetXXX''. Le dossier d'installation sera dans ''vcpkg/installed''. Avec ''vcpkg.json'', il n'est plus possible d'utiliser ''vcpkg install paquetXXX''. Il n'est plus possible que de faire ''vcpkg install'' et le dossier d'installation sera dans ''vcpkg_installed'' et ne sera plus dans un sous dossier de ''vcpkg''. Il est même possible de rendre optionnel certaines dépendances en fonction des ''WITH_*'' passés à CMake. { "features": { "hdf5": { "description": "Enable read / write of hdf files", "dependencies": [ { "name": "hdf5", "default-features": false, "features": [ "cpp" ] }, "boost-pfr", "magic-enum" ] }, "python": { "description": "Enable python binding", "dependencies": [ "pybind11" ] }, "tests": { "description": "Enable testing", "dependencies": [ "catch2" ] }, "matlab": { "description": "Enable matlab" } }, "overrides": [ { "name": "hdf5", "version": "1.8.23" } ], "builtin-baseline": "f31398b18d1c7cdf2360bebbe73010afdf8e6cb4" } ''f31398b18d1c7cdf2360bebbe73010afdf8e6cb4'' est le commit minimum du vcpkg qui permette de respecter les dépendances (généralement le commit du clone de vcpkg). Et dans ''CMakeLists.txt'' : cmake_minimum_required(VERSION 3.9) option(WITH_HDF5 "Build with HDF5" OFF) if(WITH_HDF5) list(APPEND VCPKG_MANIFEST_FEATURES "hdf5") endif() option(WITH_MATLAB "Build Matlab wrappers" OFF) if(WITH_MATLAB) list(APPEND VCPKG_MANIFEST_FEATURES "matlab") endif() option(WITH_PYTHON "Build Python module" OFF) if(WITH_PYTHON) list(APPEND VCPKG_MANIFEST_FEATURES "python") endif() option(BUILD_TESTING "Build the testing tree." ON) if(BUILD_TESTING) list(APPEND VCPKG_MANIFEST_FEATURES "tests") endif() project(...) include(CTest) enable_testing() ... Les ''option'' / ''VCPKG_MANIFEST_FEATURES'' doivent être définis avant ''project''. Par contre, il n'est pas possible de faire un ''include(CTest)'' avant ''project(...)''. D'où la nécessité de définir l'option ''BUILD_TESTING'' manuellement. [[https://learn.microsoft.com/en-us/vcpkg/reference/vcpkg-json|vcpkg.json Reference]] {{ :prog:vcpkg:vcpkg.json_reference_microsoft_learn_18_09_2023_11_01_45_.html |Archive du 18/07/2023 le 18/09/2023}} ====Contraintes sur les options de compilation==== Pour spécifier le compilateur, il faut passer par un triplet personnalisé avec 2 fichiers : Dans ''vcpkg/triplets'', créer un triplet personnalisé sur la base d'un existant et ajouter la ligne ''set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../scripts/toolchains/XXXXXXX.cmake)'' include(${CMAKE_CURRENT_LIST_DIR}/x64-linux.cmake) set(VCPKG_CHAINLOAD_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/../scripts/toolchains/linux-clang.cmake) et dans ''vcpkg/scripts/toolchains'', ajouter les variables CMake pour définir l'utilisation de clang : include(${CMAKE_CURRENT_LIST_DIR}/linux.cmake) set(CMAKE_C_COMPILER /usr/bin/clang) set(CMAKE_CXX_COMPILER /usr/bin/clang++) set(CMAKE_AR /usr/bin/llvm-ar) set(CMAKE_AS /usr/bin/llvm-as) set(CMAKE_RANLIB /usr/bin/llvm-ranlib) =====Arborescence des dossiers===== Pour faciliter la recherche d'informations sur les paquets de vcpkg. Liste des paquets avec leurs versions de publication et versions d'instructions de compilation : vcpkg\versions Liste des instructions pour la compilation des paquets : vcpkg\ports * Compilation Dossier source : vcpkg\buildtrees\[package]\src\[sha256]-[random_hash].clean Dossier de compilation : vcpkg\buildtrees\[package]\[triplet]-[dbg|rel] Logs de compilation : vcpkg\buildtrees\[package]\*.log Le dossier ''vcpkg\buildtrees\[package]'' ne contient qu'un fichier ''[triplet].vcpkg_abi_info.txt'' avec les checksums des dépendances si la version compilée du paquet a été récupéré depuis le cache. [[https://learn.microsoft.com/en-us/vcpkg/users/binarycaching#abi-hash|Binary Caching]] {{ :prog:vcpkg:binary_caching_microsoft_learn_3_5_2024_12_19_05_pm_.html |Archive du 10/01/2024 le 05/03/2024}} Paquet installé : vcpkg\packages\[package]_[triplet] =====Ajout / modification d'un paquet===== Voir les fichiers ''vcpkg.json'' et ''portfile.cmake'' dans les dossiers ''vcpkg/scripts/templates'' et les mettre dans le dossier ''vcpkg/ports/[package]/''. ====vcpkg.json==== * ''license'' : doit correspondre à un élément de la liste https://spdx.org/licenses/. Si une autre licence, mettre null sans guillemet. * ''dependencies'' : doit toujours avoir ''vcpkg-cmake'' même si le paquet n'utilise pas ''CMake''. Ajouter également ''vcpkg-cmake-config'' si le projet nécessite ''CMake'' pour configurer et compiler le projet. * ''features'' : Ici, on active une feature par défaut : ''hfd5''. "default-features": [ "hdf5" ], "features": { "hdf5": { "description": "Enable read / write of hdf files", "dependencies": [ { "name": "hdf5", "features": [ "cpp" ] } ] } } ====portfile.cmake==== ===Récupérer le code source=== SHA512 se calcule depuis l'URL https://github.com/[REPO]/archive/[REF].tar.gz ou ''%%curl -H "PRIVATE-TOKEN: ${TOKEN}" -L git@[GITLAB_REPOSITORY]/[PROJECT]/-/archive/[VERSION]/[PROJECT]-[VERSION].tar.gz --output ${version}.tar.gz%%''. Mais pour faire simple, mettre 0 (pas vide) et laisser le téléchargement échouer. ''vcpkg'' affichera le bon ''SHA512''. Il est aussi possible de mettre ''SKIP_SHA512'' (très mauvaise idée en production). Si la valeur change à chaque fois, il y a probablement un problème de droit. Ouvrir le fichier téléchargé dans le dossier ''download'' avec un éditeur de texte pour vérifier le contenu (probablement une page HTML). ''vcpkg_from_github'' : par défaut, c'est systématiquement ''REF'' et son ''SHA512'' associé qui est utilisé. vcpkg_from_github( OUT_SOURCE_PATH SOURCE_PATH REPO PLSysSec/rlbox_sandboxing_api REF 638807ad6842d82690fb2e712a32ccab4c7eec8f SHA512 d8f0788b2c46bb07041d28d9ce9426a9a3ec6df8217b81b311fc02366c49850ee138f9d3f9784cf34c778d5173779db20acc3bee436d6f1494fa8fccff5950af HEAD_REF master PATCHES catch2.patch ) Il est possible de pointer vers une branche (port à usage de développement uniquement). On remplace ''REF'' par ''HEAD_REF'', on supprime ''SHA512'' et on définit ''VCPKG_USE_HEAD_VERSION'' pour forcer l'utilisation de ''HEAD_REF''. set(VCPKG_USE_HEAD_VERSION ON) vcpkg_from_gitlab( OUT_SOURCE_PATH SOURCE_PATH GITLAB_URL ${GITLAB_REPOSITORY} REPO ${PROJECT} HEAD_REF "master") ===Compiler=== ''vcpkg_check_features'' active le define ''WITH_HDF5'' si la feature ''hdf5'' est activée. ''vcpkg_cmake_configure''. ''BUILD_SHARED_LIBS'' est automatiquement transmis. Pour avoir la liste complète des variables automatiquement transmises, voir ''vcpkg\scripts\cmake\vcpkg_configure_cmake.cmake''. vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES hdf5 WITH_HDF5) vcpkg_cmake_configure( SOURCE_PATH ${SOURCE_PATH} OPTIONS ${FEATURE_OPTIONS} ) ===Installer=== vcpkg_cmake_install() vcpkg_copy_pdbs() ===Patcher=== Il faut ensuite tester l'installation et patcher pour rendre l'installation compatible avec vcpkg. Pour tester : ./vcpkg.exe build [package] --triplet x64-windows Fonctions et modifications possibles, à mettre après ''vcpkg_cmake_install'' : vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt") vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/package-1.2.3") file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include") ===Subtilités=== * Accès aux variables d'environnement de Windows Sous Windows, les variables d'environnement ne sont pas passées à vcpkg et donc pas non plus à CMake. Pour activer cette possibilité, il faut ajouter la liste des variables d'environnement dans le triplet souhaité : set(VCPKG_ENV_PASSTHROUGH PATH) set(VCPKG_ENV_PASSTHROUGH_UNTRACKED VCPKG_TOKEN) La modification d'une variable dans ''VCPKG_ENV_PASSTHROUGH'' entrainera la recompilation des paquets. Contrairement à ''VCPKG_ENV_PASSTHROUGH_UNTRACKED''. [[https://learn.microsoft.com/en-us/vcpkg/users/triplets|Triplets reference]] * Connaître l'architecture source / destination L'architecture source (hôte qui compile) : `CMAKE_HOST_`. L'architecture de destination (target qui exécutera) : `VCPKG_TARGET_IS_`. `WIN32` et `LINUX` sont dépréciés car il y a confusion facile entre l'hôte et la target. ====Publication des modifications==== ===Mise à jour=== Si on change de numéro de release de version du paquet, supprimer la ligne ''port-version''. Si on garde le même numéro de release, il faut incrémenter (ou ajouter) la ligne ''port-version'' (e.g. ''%%"port-version": 1%%'', sans guillemet autour du nombre. Un nombre à 0 équivalent à une absence de ligne). ===git=== Il faut commencer par faire un commit avec les modifications du dossier ''port/[package]''. Lancer ensuite ''vcpkg.exe x-add-version package''. Puis commiter à nouveau (en amendant) la modification des fichiers ''versions/baseline.json'' et ''versions/[a-z]-/[package].json''. git add ports/package/* git commit -m "[package] new port" ./vcpkg format-manifest ports/package/vcpkg.json ./vcpkg x-add-version package --overwrite-version git add versions git commit -a -m "[package] new port" git push ====Dépôt vcpkg local==== * Création d'un dépôt ''git'' Plutôt que de devoir cloner tout le dépôt vcpkg de Microsoft, il est possible de faire son propre dépôt (registry) et d'y ajouter les packages. [[https://learn.microsoft.com/en-us/vcpkg/produce/publish-to-a-git-registry|Tutorial: Publish packages to a private vcpkg registry using Git]] {{ :prog:vcpkg:tutorial_publish_packages_to_a_private_vcpkg_registry_using_git_microsoft_learn_3_8_2024_12_59_10_pm_.html |Archive du 10/01/2024 le 08/03/2024}} mkdir vcpkg-registry cd vcpkg-registry git init mkdir ports mkdir versions { "default": {} } git add versions/baseline.json git commit -m "Initial commit" * Création d'un dépôt ''filesystem'' Voir exemple [[https://github.com/vcpkg/example-filesystem-registry/|example-filesystem-registry]] {{ :prog:vcpkg:example-filesystem-registry-2021-05-06.zip |Archive du 06/05/2021 le 08/03/2024}} Les différentes sont dans les fichiers ''versions/*-/XXXX.json'', à la place des champs ''git-tree'', il faut remplir le champ ''path'' : { "versions": [ { "version": "1.0.0", "path": "$/ports/XXXX/1.0.0" } ] } L'arborescence du dossier ''ports'' est donc légèrement différente et il n'y a pas besoin d'appeler ''%%vcpkg x-add-version ...%%''. * Ajout des paquets au dépôt Ajouter ensuite les paquets selon la méthode du paragraphe précédent. Si le registry n'a pas de binaire ''vcpkg.exe'', il est possible d'utiliser celui du dépôt de Microsoft et de spécifier l'emplacement du dossier du registry : ../vcpkg-microsoft/vcpkg --x-builtin-ports-root=./ports --x-builtin-registry-versions-dir=./versions x-add-version --all --verbose * Utilisation de plusieurs dépôts en même temps Il n'est pas possible de spécifier en ligne de commande un registry secondaire sans passer par un fichier ''vcpkg-configuration.json''. Cela n'impose pas la présence d'un fichier ''vcpkg.json'' et il reste donc possible d'utiliser ''vcpkg'' en mode classique ou manifest. Si le fichier ''vcpkg.json'' existe, il faut créer le fichier ''vcpkg-configuration.json'' à côté de ce fichier. Si ''vcpkg.json'' n'existe pas, il faut créer le fichier ''vcpkg-configuration.json'' dans le même dossier que ''VCPKG_ROOT'' (le registry principal). { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-configuration.schema.json", "default-registry": { "kind": "git", "baseline": "ab887c562326c686478284d9076d722c1ec4b48c", "reference": "master", "repository": "https://github.com/microsoft/vcpkg.git" }, "registries": [ { "kind": "git", "baseline": "cb7613262642f41dc3ee3a1ddc11ed82e391c21d", "reference": "main", "repository": "https://example.com/vcpkg-registry.git", "packages": [ "hdf5" ] } ] } Attention, ''baseline'' doit être dans le passé de la branche ''reference'' et non dans son futur via une autre branche. Le dossier temporaire de clone des dépôts git sont dans ''C:\Users\[USER]\AppData\Local\vcpkg\registries''. =====Ajout / modification d'un triplet===== Voir la documentation [[https://learn.microsoft.com/fr-fr/vcpkg/users/triplets|triplet]] de vcpkg. ====Variables les plus courantes==== ===Toutes plateformes=== * ''VCPKG_TARGET_ARCHITECTURE'' : architecture des librairies à générer (''x64'', ...), * ''VCPKG_LIBRARY_LINKAGE'' : compilation en ''dynamic'' ou ''static'' des librairies générer, * ''VCPKG_CRT_LINKAGE'' : compilation en ''dynamic'' ou ''static'' avec la librairie standard de Visual Studio. Par expérience, j'ai souvent moins de problème à mettre ''dynamic'' quand configurer un projet avec les binaires de vcpkg. * ''VCPKG_BUILD_TYPE'' : laisser vide pour compiler en ''Debug'' et ''Release''. Mettre ''release'' (sans la majuscule) pour compiler uniquement en Release. Uniquement ''debug'' n'est pas supporté. * Flags de compilation : ''VCPKG_CXX_FLAGS'', ''VCPKG_CXX_FLAGS_DEBUG'', ''VCPKG_CXX_FLAGS_RELEASE'', ''VCPKG_C_FLAGS'', ''VCPKG_C_FLAGS_DEBUG'', ''VCPKG_C_FLAGS_RELEASE'', ''VCPKG_LINKER_FLAGS'', ''VCPKG_LINKER_FLAGS_DEBUG'', ''VCPKG_LINKER_FLAGS_RELEASE''. ===Windows uniquement=== * ''VCPKG_ENV_PASSTHROUGH'' et ''VCPKG_ENV_PASSTHROUGH_UNTRACKED'' : toutes les variables d'environnement de Windows sont ignorés. Il faut ajouter le nom des variables dans ces variables CMake pour que vcpkg les prennent en compte. Les variables dans ''VCPKG_ENV_PASSTHROUGH'' sont pris en compte dans le calcul du hash pour savoir s'il faut recompiler. Les variables dans ''VCPKG_ENV_PASSTHROUGH_UNTRACKED'' ne sont pas prises en compte (mot de passe par exemple). * ''VCPKG_PLATFORM_TOOLSET'' : version de Visual Studio à reprendre (''v140'', ''v141'', ''v142'', ''v143'', ''ClangCL''). Equivalent à l'option ''-T'' de CMake. ====Personnalisation avancée==== Il est possible d'appliquer des options de compilation spécifiques pour certains paquets : set(VCPKG_LIBRARY_LINKAGE static) if(${PORT} MATCHES "qt5-") set(VCPKG_LIBRARY_LINKAGE dynamic) endif()