Cmake

Conan vs vcpkg: выбор пакетного менеджера для Qt-проекта

Введение

Conan и vcpkg — два самых распространённых пакетных менеджера для C++ сегодня, оба интегрируются с CMake, оба решают задачу управления сторонними зависимостями, но имеют разную философию и удобство в разных сценариях. В статье сравним их подходы и дадим рекомендации, какой выбрать для типичного Qt-проекта.

Концепция

vcpkg (от Microsoft) тяготеет к простоте: манифест vcpkg.json, единая команда установки, тесная интеграция с Visual Studio и относительно прямолинейная интеграция с CMake через toolchain-файл. Его модель — преимущественно сборка из исходников при установке (с опциональным binary caching), и реестр пакетов организован как Git-репозиторий с CMake/портфайлами.

Conan — более зрелая и гибкая система с собственным форматом профилей (описывающих компилятор, архитектуру, стандарт библиотеки), поддержкой нескольких бинарных репозиториев (включая собственные приватные), более сложной, но мощной системой версионирования зависимостей и возможностью переиспользовать готовые бинарные пакеты между проектами и машинами без повторной компиляции «из коробки» через ConanCenter. Conan лучше подходит для крупных организаций с собственной CI-инфраструктурой и потребностью в строгом контроле версий и бинарной совместимости между множеством проектов.

Пример кода: Conan vs vcpkg

# vcpkg.json — манифест для vcpkg
{
    "name": "my-qt-app",
    "version": "1.0.0",
    "dependencies": ["fmt", "nlohmann-json"]
}
# conanfile.txt — простой формат для Conan
[requires]
fmt/10.2.1
nlohmann_json/3.11.3

[generators]
CMakeDeps
CMakeToolchain
# Установка зависимостей и сборка через Conan
conan install . --output-folder=build --build=missing
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake
cmake --build build
# CMakeLists.txt — одинаков по сути для обоих менеджеров,
# так как оба интегрируются через find_package()
find_package(fmt CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)

add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE fmt::fmt nlohmann_json::nlohmann_json)

Пояснения к коду

Оба менеджера в конечном итоге сводятся к одному и тому же интерфейсу со стороны CMakeLists.txt — стандартному find_package() с последующим target_link_libraries(), что делает миграцию между ними относительно безболезненной на уровне самого проекта. Различия проявляются на уровне процесса установки: vcpkg интегрируется через единственный toolchain-файл, переданный при конфигурации CMake, а Conan генерирует собственный conan_toolchain.cmake через явный шаг conan install, который нужно выполнить перед конфигурацией CMake-проекта.

Параметр --build=missing у Conan указывает собирать из исходников только те пакеты, для которых нет готового бинарного пакета в используемых репозиториях — это балансирует скорость установки и совместимость с локальной конфигурацией компилятора.

Подводные камни

  • Несовпадение профиля компилятора Conan с фактическим компилятором проекта (например, профиль настроен на libstdc++11, а проект использует другую ABI) приводит к ошибкам линковки или need to пересобрать всё с --build=missing — особенно болезненно при первом знакомстве с системой профилей Conan.
  • vcpkg по умолчанию пересобирает зависимости из исходников при отсутствии бинарного кеша, что для крупных библиотек (Boost, Qt) может занимать очень много времени без настроенного binary caching в CI.
  • Смешивание двух пакетных менеджеров в одном проекте (например, Qt через vcpkg, а остальные зависимости через Conan) усложняет конфигурацию CMake и повышает риск конфликтов версий одной и той же транзитивной зависимости, разрешённой по-разному двумя системами.
  • ConanCenter и реестр портов vcpkg не идентичны по составу и версиям пакетов — нужная версия конкретной библиотеки может быть доступна в одном реестре, но отсутствовать или быть устаревшей в другом, что иногда становится решающим фактором выбора менеджера для конкретного проекта.