Введение
vcpkg — пакетный менеджер C/C++ от Microsoft, который заметно упрощает установку и связывание сторонних библиотек с CMake-проектом: вместо ручной компиляции зависимостей из исходников или установки через системные пакетные менеджеры (которые дают разные версии на разных ОС) vcpkg предоставляет единообразный интерфейс установки и автоматическую интеграцию с CMake через toolchain-файл. В статье рассмотрим, как настроить Qt-проект с зависимостями через vcpkg.
Концепция
vcpkg работает в двух основных режимах: classic mode (зависимости устанавливаются глобально в инсталляцию vcpkg и переиспользуются между проектами) и manifest mode (зависимости описываются в файле vcpkg.json в корне проекта и устанавливаются изолированно для конкретного проекта — рекомендуемый сегодня подход, аналогичный package.json в Node.js или requirements.txt в Python).
Интеграция с CMake происходит через указание toolchain-файла vcpkg при конфигурации: -DCMAKE_TOOLCHAIN_FILE=.../vcpkg.cmake. После этого все вызовы find_package() в проекте автоматически находят библиотеки, установленные через vcpkg, без ручной настройки путей.
Пример кода: vcpkg + Qt + CMake
// vcpkg.json — манифест зависимостей проекта
{
"name": "my-qt-app",
"version": "1.0.0",
"dependencies": [
"fmt",
"nlohmann-json",
{
"name": "boost-asio",
"version>=": "1.83.0"
}
]
}
# CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(MyApp LANGUAGES CXX)
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
find_package(fmt CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(Boost REQUIRED COMPONENTS asio)
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE
Qt6::Core
Qt6::Widgets
fmt::fmt
nlohmann_json::nlohmann_json
Boost::asio
)
# Настройка и сборка проекта с использованием vcpkg в режиме манифеста
cmake -B build -S . \
-DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_PREFIX_PATH=path/to/Qt/6.x.x/gcc_64
cmake --build build
Пояснения к коду
Файл vcpkg.json в режиме манифеста объявляет нужные зависимости прямо в проекте — при первой конфигурации CMake vcpkg автоматически устанавливает их именно в той версии (или диапазоне версий), которая указана, изолированно для текущего проекта в подпапку vcpkg_installed. Это устраняет проблему «у меня на машине работает, а у коллеги — нет» из-за разных версий глобально установленных библиотек.
В CMakeLists.txt зависимости подключаются стандартными вызовами find_package() — vcpkg прозрачно подставляет нужные пути через toolchain-файл, поэтому код CMake выглядит так же, как если бы библиотеки были установлены системно.
Подводные камни
- Указание
CMAKE_TOOLCHAIN_FILEиCMAKE_PREFIX_PATH(для Qt) одновременно иногда приводит к конфликтам поиска пакетов, если Qt также установлен через vcpkg — нужно явно разобраться, откуда берётся Qt (отдельная установка Qt vsvcpkg install qtbase), чтобы не получить дублирующиеся или несовместимые версии. - Долгая первая сборка зависимостей «с нуля». vcpkg по умолчанию собирает многие библиотеки из исходников, что может занимать значительное время при первой настройке — для CI рекомендуется настроить binary caching (например, через github-actions-%d0%bf%d0%b5%d1%80%d0%b2%d1%8b%d0%b9-workflow-%d0%b4%d0%bb%d1%8f-%d1%81%d0%b1%d0%be%d1%80%d0%ba%d0%b8-qt-%d0%bf%d1%80%d0%be%d0%b5%d0%ba%d1%82%d0%b0/" class="qth-seo-autolink">GitHub Actions Cache или vcpkg’s встроенный NuGet-based binary cache).
- Несовпадение архитектуры/триплета. На Windows нужно явно указывать triplet (например,
x64-windowsилиx64-windows-static), иначе можно случайно собрать или подключить библиотеку под неверную архитектуру или с несовместимым типом линковки CRT (динамическая vs статическая), что приводит к ошибкам линковки. - Версии зависимостей в vcpkg отстают от последних релизов — vcpkg использует собственный реестр портов, который обновляется не мгновенно после выхода новой версии библиотеки; для самых свежих версий иногда приходится использовать overlay-порты или fallback на
FetchContent.