Conan: менеджер зависимостей для C-C++

в 18:45, , рубрики: C, c++, пакетный менеджер, Промышленное программирование

image
Здравствуйте. Сегодня речь пойдёт про Conan — современный менеджер зависимостей для C/C++. Если Вы уже активно работаете с ним, то навряд ли найдёт что-нибудь новое для себя. Иначе — прошу под кат.

Зачем нужен менеджер зависимостей
Если Вы пользователь Linux-based дистрибутива или macOS, то для Вас скорее всего не является проблемой подтянуть какую-то нужную зависимость — в дистрибутивах скорее всего есть нужный Вам <library_name>-dev пакет. Но если Вы пользователь Windows, то думаю часто сталкивались с проблемой, как же подтянуть в проект какую-бы то ни было зависимость. Хорошо, если сторонняя библиотека header-only — нужно только скопировать заголовочные файлы в нужное и начинать использовать. Но обычно библиотеки нужно собирать (а так как в С++ зоопарк, то это зачастую не так просто сделать), потом разместить скомпилированную библиотеку в нужное Вам место. И только после этого Вы сможете её использовать.

К тому же не забудем про то, что мы должны компилировать библиотеки желательно одним компиляторам, не забывать о совместимости ABI и т.д. Да и сама компиляция занимает очень много времени (привет Boost). Многовато для обычных смертных, не находите? А тем временем некоторые люди просто используют pip, npm, cargo, maven и т.д. и экономят себе много нервов.

Предыдущие попытки
Хотелось бы иметь аналог npm, но для C++. Чтобы буквально одной командой подтягивать нужную Вам зависимость в проект и не знать головной боли.

Ранее уже были попытки создания такого средства для C++. Может, некоторые из Вас помнят такую вещь как biicode. Он, к сожалению, приказал долго жить. Здесь можете ознакомиться с причиной смерти пациента. Интересный факт: создатели Conan и biicode — примерно одни и те же люди. Возникает резонный вопрос: не повторит ли Conan судьбу biicode?
image

Есть и современные альтернативы Conan. Из наиболее известных: vcpkg, hunter, buckaroo.

Как установить?
Для начала нужно установить сам Conan. Есть множество путей для этого: Ваш любимый пакетный менеджер, pip, brew. Также имеются бинарные сборки под Ubuntu/Debian и Windows. Сами авторы рекомендуют использовать установку через pip. Если Вам эти способы не нравятся, то Вы всегда можете собрать сами из исходного кода.

Особенности
Conan отслеживает за Вас такие вещи как: компилятор, версия компилятора, операционная система, разрядность ОС, тип сборки (Release/Debug), версия стандартной библиотеки. Используя данные параметры Conan пытается найти собранную версию под Ваши конфигурацию. Если повезёт, то в репозитории найдётся уже собранная версия и Вам не придётся ничего компилировать.

Если же Вам не повезло и под сочетание Ваших ОС/компилятора/и т.д. собранного пакета не нашлось, то Conan автоматически скачает исходный код требуемой библиотеки и скомпилирует на Вашей рабочей машине. После этого Вы сможете спокойно использовать библиотеку, как будто она уже была кем-то собрана.

Как использовать
Имеем такой вот timer.cpp, который мы должны заставить компилировать и работать:

#include "Poco/Timer.h"
#include "Poco/Thread.h"
#include "Poco/Stopwatch.h"
#include <iostream>

using Poco::Timer;
using Poco::TimerCallback;
using Poco::Thread;
using Poco::Stopwatch;

class TimerExample{
public:
        TimerExample(){ _sw.start();}

        void onTimer(Timer& timer){
                std::cout << "Callback called after " << _sw.elapsed()/1000 << " milliseconds." << std::endl;
        }
private:
        Stopwatch _sw;
};

int main(int argc, char** argv){
        TimerExample example;
        Timer timer(250, 500);
        timer.start(TimerCallback<TimerExample>(example, &TimerExample::onTimer));

        Thread::sleep(5000);
        timer.stop();
        return 0;
}

Рассмотрим стандартный пример из документации. Хотим подключить в наш проект (предположим, что мы используем CMake) библиотеку POCO. Для этого в папке с проектом создаём файл conanfile.txt со следующим текстом:
[requires]
Poco/1.8.0.1@pocoproject/stable

[generators]
cmake

Разберём, что есть что в этом файле. В разделе Requires мы описываем нужные нам зависимости в виде НазваниеБиблиотеки/ВерсияБиблиотеки@ИмяМейнтейнера/СтабильностьПакета. Имя мейнтейнера — человек или организация, кто поддерживает пакет. Стабильность — просто показатель, насколько пакет стабилен. Обычно используют stable, testing, ci. Рекомендую использовать только stable пакеты.

В секции generators мы указываем, с чем мы хотим интегрироваться. В нашем случае указываем интеграцию с CMake. Conan для интеграции с CMake создаст автоматически файл conanbuildinfo.cmake, в котором будут определены переменные с путями к заголовочным файлам и уже скомпилированным библиотекам, которые мы будем использовать в нашем CMakeLists.txt:

project(FoundationTimer)
cmake_minimum_required(VERSION 2.8.12)
add_definitions("-std=c++11")

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

add_executable(timer timer.cpp)
target_link_libraries(timer ${CONAN_LIBS})

Обратите внимание на строки 5-6. В строке 5 мы подключаем ранее сгенерированный conanbuildinfo.cmake, а в 6-ой строке просто определяем макрос, который заставляет Conan магическим образом работать :-)

Теперь мы готовы к сборке. И перед стандартным запуском CMake мы должны попросить у Conan установить зависимости. Делается это следующей командой:
conan install /path/to/conanfile.txt
Обычно команда будет выглядеть просто как
conan install ..

image
Здесь происходит самое интересное — как Conan подтягивает зависимости

Порядок поиска зависимостей:

  • Проверяем локальный кеш.
  • Ищем в подключенных репозиториях нужный нам рецепт. Обращаю Ваше внимание, что поиск ведётся строго в том порядке, в каком у Вас подключены репозитории. Если пакет будет в двух репозиториях, то найдётся первый попавшийся.
  • Если рецепт был найден и есть уже собранная библиотека под Вашу конфигурацию, то просто качаем из репозитория пакет и сохраняем его в локальный кеш. Стоит отметить, что пакет выкачивается автоматически со всеми зависимостями к нему.
  • Если же под Вашу конфигурацию собранной библиотеки нет (или нет собранной какой-то зависимости библиотеки под Вашу конфигурацию), то Conan сообщит об этом и попросит запустить его ещё раз с флагом --build missing для запуска сборки пакета на Вашей машине.

Если Вы не хотите использовать кем-то собранную библиотеку и не доверяете чужим сборкам, то всегда можно указать флаг --build, чтобы библиотека и всё её зависимости были принудительно пересобраны на Вашей машине.

Поздравляю, все зависимости подтянуты с помощью Conan (если повезло)!

Conan и интеграция с билд-системой
Важно не просто скачать нужную версию библиотеки, но и подключить её правильно в проект. И желательно, чтобы это делалось как можно легче для разработчика. Поэтому Conan умеет интегрироваться с такими вещами как CMake, Visual Studio, Xcode и т.д. С полным списком Вы всегда можете ознакомиться здесь.

Conan как способ управления собственными зависимостями
Conan — это не только клиент для установки зависимостей из уже созданных кем-то репозиториев. Авторы данного менеджера зависимостей также любезно нам предоставили программу conan-server, которая позволяет буквально в пару-тройку действий поднять свой собственный сервер с готовыми библиотеками. Очень удобно для компаний, которые хотят наладить свою собственную инфраструктуру по управлению зависимостями.

Существующие проблемы
Ценность пакетного менеджера определяется удобством его использования и количеством пакетов. Если с первым особых проблем нет (Conan и правда очень удобен в использовании), то вот с количеством пакетов есть определённые проблемы. Если Вы посмотрите на основные репозитории, то увидите их целых два: conan-center и conan-transit. Согласитесь, это вводит в заблуждение — какой же использовать? Здесь нужно рассказать немного истории.

Изначально в Conan имелся один репозиторий, в который любой пользователь имел право грузить пакеты. Из-за этого репозиторий Conan очень быстро превратился в одну большую помойку. Авторы решили, что так дело продолжаться не может и решили создать репозиторий, в который пакеты будут попадать только после тщательной проверки. Так и появился conan-center. А старый, «мусорный» репозиторий решили не удалять, а просто его перевести в режим read-only и переименовали в conan-transit.

Где хранятся пакеты для Open-source библиотек
Хранением всех пакетов занимается организация JFrog Bintray. Не так давно Conan переехал на инфраструктуру Bintray, поэтому у нас появился доступ к более вместительному хранилищу пакетов, а также к CDN. Одним из самых интересных новшеств после переезда является то, что Вы можете создать абсолютно бесплатно свой собственный репозиторий для OSS пакетов. Если же Вы хотите приватности, то можете воспользоваться триал-версией на 30 дней, а потом придётся платить.

Bincrafters
Библиотек много, и ко всем хотелось бы иметь готовые пакеты. Команда Conan сейчас очень маленькая и занята в основном разработкой самого пакетного менеджера, поэтому им некогда пакетить всё подряд (хотя они постоянно ищут разработчиков в том числе и для пакетирования). Но пакетить библиотеки надо, иначе нет смысла в Conan. Так и появилась команда Bincrafters — команда энтузиастов, которая активно пакетит open-source библиотеки. У них сейчас открыта программа на Patreon по сбору средств для аренды дополнительных CI мощностей. Если Вы хотите присоединиться к команде — милости просим.

Что делать, если библиотеки X нет в Conan?
На данном этапе развития такое случается очень часто. Вы всегда можете оставить заявку на создание пакета здесь (перед этим убедитесь, что никто до Вас уже об этом не просил). Если заявка уже существует, то просто напишите в комментариях, что данная библиотека и Вам нужна. И, конечно, Вы сами можете опакетить библиотеку, все только спасибо скажут.

Наиболее полезные команды (на мой взгляд)

  • conan search <library_name_pattern> — поиск пакета в репозиториях по заданному шаблону
  • conan info — просмотр информации о пакете (лицензия, дата создания, адрес исходного кода пакета и т.д.)
  • conan remote — управление репозиториями Conan (добавление, удаление и т.д.)

Советы

  • Используйте только stable пакеты. Использование пакетов testing и ci не рекомендуется, так как могут ломаться регулярно.
  • Если надумаете писать свои рецепты, то пример хорошего рецепта можно посмотреть вот тут.
  • При создании пакетов крайне рекомендуется уже иметь настроенный CI под все целевые платформы. Проблема всплывают всегда там, где Вы их не ожидаете :-)
  • Не забывайте обновлять Conan. Может так случиться, что в Conan просто сломают обратную совместимость и рецепт, который работает с новым Conan, со старым уже работать не будет.
  • Рекомендуемый порядок поиска пакетов (на данный момент): conan-center, public-conan (репозиторий Bincrafters team), conan-transit, другие репозитории.

Полезные ссылки:

Автор: ZaMaZaN4iK

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js