Зависимости с github
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 25.06.20 04:57
Оценка:
Приветствую!
Вопрос конкретно по правильной работе с открытыми библиотеке в открытом кроссплатформенном проекте, когда всё хостится на github и используется сборка на CMake. Но интересны и другие кейсы.
Допустим, что у меня проект использует несколько небольших библиотек с Гитхаба: spdlog, yaml-cpp, pybind11... Как мне их лучше использовать/подключать? Пользователи моего проекта — программисты. Я вижу вокруг несколько сценариев:
1. Проект поставляется как есть, а CMake просит указать пути к этим библиотекам, то есть зависимости пользователю надо ставить и собирать отдельно.
Плюс: не надо ничего таскать, пользователь может использовать то, что ему нравится.
Минус: многим пользователям сложно в этом разобраться и они завалят вопросами.

2. Проект носит все зависимости с собой в виде исходников в директории 3rdparty (например opencv так делает). Далее в CMake можно выбрать: использовать системные или те, что есть в 3rdparty.
Плюс: есть контроль версий зависимостей, наложены на них все необходимые для меня патчи.
Минус: в Линуксах такое часто нафиг не надо, там ставится почти всё необходимое из репозитория.

3. Проект не носит ничего с собой, а зависимости оформлены как git submodules и скачиваются/собираются с гитхаба.
Плюс: у нас всегда свежая версия зависимостей.
Минус: может выйти новая версия, которую я пока не поддерживаю -> надо указывать версию самому -> теряется плюс новой версии.

Как делаете или считаете правильным делать?
Re: Зависимости с github
От: kov_serg Россия  
Дата: 25.06.20 05:37
Оценка: +4
Здравствуйте, Nuzhny, Вы писали:

N>3. Проект не носит ничего с собой, а зависимости оформлены как git submodules и скачиваются/собираются с гитхаба.

N>Плюс: у нас всегда свежая версия зависимостей.
N>Минус: может выйти новая версия, которую я пока не поддерживаю -> надо указывать версию самому -> теряется плюс новой версии.
Всегда указываешь версию. Оно должно собираться и работать, а не быть самой свежей.
Но лучше форкаешь всё к себе и указываешь версии. Малоли что
Re: Зависимости с github
От: so5team https://stiffstream.com
Дата: 25.06.20 06:24
Оценка: 7 (1) +1
Здравствуйте, Nuzhny

Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.

Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.
Re[2]: Зависимости с github
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 25.06.20 08:09
Оценка:
Здравствуйте, so5team, Вы писали:

S>Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.


О, спасибо, не знал об этой штуке.

S>Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.


Не нравится мне он (и vcpkg тоже как-то не очень). Понимаю, что делают правильные штуки, но как-то всё душа не лежит.
Re[2]: Зависимости с github
От: SaZ  
Дата: 25.06.20 14:45
Оценка: 7 (1) +1
Здравствуйте, so5team, Вы писали:

S>Здравствуйте, Nuzhny


S>Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.


S>Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.


Я предпочитаю всё-таки FetchContent.

Из личного опыта скажу, что это большой гемморой — собирать зависимости при помощи CMake. Есть много проектов, которые не умеют CMake либо требуют овердофига настройки и не поддерживают все компиляторы. Например, gRPC не поддерживает mingw и не собирается им, если не предустановить в систему OpenSSL. Тот же OpenSSL не соберётся с помощью mingw . Для sqlite я написал свой сборщик на пару строк.

Но, в целом посмотрите, как в том же gRPC подключаются зависимости. Мне кажется они достаточно правильно сделали. Либо ищут через FindPackage либо добавляют через add_subdirectory.

Когда gRPC не поддерживал сборку с инсталляцией без предварительно скомпилированных зависимостей, приходилось извращаться. Но так делать я не советую. Всё это писалось когда я только начинал осваивать cmake.
Re: Зависимости с github
От: goloveshin Россия  
Дата: 25.06.20 15:20
Оценка: 7 (1)
Делаю так:

1. Сторонние зависимости собираются из исходников и так делается на всех платформах.
2. Если политика использования сторонних исходников позволяет хранить их под контролем версий, то хранить там и, желательно, в виде архива, в котором их предлагают скачивать с сайта, т.е. "как есть". Если хранить сторонние исходники нельзя, то они скачиваются в момент сборки по точному url. Например, как уже указали выше, в ExternalProject_Add можно указать и тот и другой способ.
3. Собирать как можно больше сторонних зависимостей — это минимизирует зависимость пакета от системы.
4. Можно _не_ собирать те зависимости, которые есть у всех и/или тот функционал/интерфейс, который вам оттуда нужен, не меняется долгое время — например, какой-нить libzip.
5. Все — и программисты и тестировщики и клиенты должны использовать только один набор внешних зависимостей — тот, что мы собрали. Запретить напрочь использования зависимостей с системы, иначе тестировать будем одно, а на клиенте будет работать другое.


плюсы:
— общий для всех рантайм — "всё своё ношу с собой"
— унификация: например, вы собираете свою OpenSSL и далее все зависимости собираются только с этой OpenSSL, при использовании же пакетов каждый их них волен указать свою версию OpenSSL или вообще включить ее статически
— работа по сборке новой внешней зависимости делается один раз и в дальнейшем она собирается централизованно, позволяя не замусоривать машины разработчиков зависимостями, нужными исключительно для сборки наших зависимостей
— возможность собирать версии с нужными параметрами, а не теми, которые предлагают пакетные менеджеры
— возможность сборки нужными компиляторами
— возможность накатывать свои патчи
— возможность работать на системах, поддержка которых закончилась (пакета с нужной версией там может уже не быть)

минусы:
— нужно всё это собирать
— геморрой
— местами очень сильный геморрой

Пример сборки сторонних зависимостей (CMake, ExternalProject_Add).
Здесь приоритет скачиваемым исходникам, кроме тех, где по какой-то причине это невозможно.
iOS и Android не показаны, но там всё по той же схеме.

https://github.com/goloveshin/label_ci/tree/test/libs_ext
Re: Зависимости с github
От: Vain Россия google.ru
Дата: 25.06.20 22:33
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>3. Проект не носит ничего с собой, а зависимости оформлены как git submodules и скачиваются/собираются с гитхаба.

boost в модулях пуллится 13 минут, одной репой — 3 минуты. Это всё что нужно знать о модулях.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: Зависимости с github
От: Vain Россия google.ru
Дата: 25.06.20 22:36
Оценка:
Здравствуйте, so5team, Вы писали:

S>Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.

Жуткое угрёбище, лучше уж подключить 3dparty ссылками в проект и добавлять через add_subdirectory.

S>Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.

Оно уже умеет тащить из разных систем контроля версий хостящихся на разных доменах или из разных локальных папок?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[3]: Зависимости с github
От: so5team https://stiffstream.com
Дата: 26.06.20 05:18
Оценка:
Здравствуйте, Vain, Вы писали:

S>>Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.

V>Жуткое угрёбище, лучше уж подключить 3dparty ссылками в проект и добавлять через add_subdirectory.

Тут уж каждый пусть сам себе выбирает то, что ему удобнее. Вариант с ExternalProject_Add (с моей точки зрения) хорош тем, что все зависимости в нужных версиях автоматически подтянутся у пользователя. При этом пользователь через опции, передаваемые в ваш CMakeLists.txt, может указывать какие зависимости следует тянуть, а какие -- нет. Типа того, что если указывается опция MY_SUPER_PUPER_PROJECT_USE_EXTERNAL_FMTLIB, то fmtlib через ExternalProject_Add не подтягивается вообще.

S>>Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.

V>Оно уже умеет тащить из разных систем контроля версий хостящихся на разных доменах или из разных локальных папок?

Вероятно, вы Conan с чем-то другим путаете. Он вообще никогда (емнип) не предназначался для того, чтобы тянуть что-то из разных систем контроля версий или разных локальных папок. В Conan-е проекты выкладываются в специальные репозитории (типа conan.io/center), из которых затем и устанавливаются на машине пользователя. При этом репозитории могут быть и свои (развернутые на своих серверах), и чужие. Т.е. необязательно все толкать в conan-center, можно создавать свои репозитории (например, на bintray.com) и пользователю достаточно просто описать такой репозиторий у себя (делается одной командой) для того, чтобы иметь возможность забирать нужные ему библиотеки из этого репозитория.

И то, что Conan скачал на машину пользователя устанавливается в специальные папки, которые находятся под контролем самого conan-а.
Re[3]: Зависимости с github
От: SaZ  
Дата: 26.06.20 10:40
Оценка:
Здравствуйте, Vain, Вы писали:

V>Жуткое угрёбище, лучше уж подключить 3dparty ссылками в проект и добавлять через add_subdirectory.


Вы так будете делать ровно до тех пор, пока не отгребёте с конфигурацией проекта. Если CMakeLists.txt который вы подключаете будет активно менять глобальные свойства. Не говоря уже о том, что некоторые вещи могут делаться лишь на этапе install.

V>Оно уже умеет тащить из разных систем контроля версий хостящихся на разных доменах или из разных локальных папок?


Всегда умело. Насчёт систем контроля версий придётся повозиться и написать руками командну строку аля git clone. Из локальных папок, с серверов по URL и прочее — умеет.
Re[4]: Зависимости с github
От: Vain Россия google.ru
Дата: 28.06.20 14:13
Оценка:
Здравствуйте, so5team, Вы писали:

S>>>Если есть завязка строго на CMake то можно рассмотреть вариант с использованием ExternalProject_Add. В этом случае вам не нужно включать чужие исходники в состав своего проекта и класть их в 3rdparty, они могут подтягиваться по мере надобности.

V>>Жуткое угрёбище, лучше уж подключить 3dparty ссылками в проект и добавлять через add_subdirectory.
S>Тут уж каждый пусть сам себе выбирает то, что ему удобнее. Вариант с ExternalProject_Add (с моей точки зрения) хорош тем, что все зависимости в нужных версиях автоматически подтянутся у пользователя. При этом пользователь через опции, передаваемые в ваш CMakeLists.txt, может указывать какие зависимости следует тянуть, а какие -- нет. Типа того, что если указывается опция MY_SUPER_PUPER_PROJECT_USE_EXTERNAL_FMTLIB, то fmtlib через ExternalProject_Add не подтягивается вообще.
У ExternalProject_Add масса недостатков:
* Вложенность на каждый вызов, из-за чего при 3-4 вызовах путь до последнего файла вырастает длиннее 260 символов и падает сами знаете почему.
* Надо явно пробрасывать все -D переменные в каждый вызов и не забывать их пробрасывать во все вложенные вызовы.
* Поменялась одна переменная, — везде куда проброшено, всё пересобирается с 0, жди полной вложенной пересборки, это когда проект X пересобирается не один раз, а N — на каждую вложенность.
* Рассинхронизация кешей симейка (на каждый проект X — свой кеш), это когда проект X в одной части собрался с одними настройками, а в другой — с другими. Удачи потом искать рассинхрон, из-за чего потом бинарники могут падать в случайных местах.
* Приходится допиливать функциональность самой функции. Видел некоторые реализации, где конфигур вызывается "на месте", т.е. без колхоза оно не может.

S>>>Ну и, конечно же, имеет смысл рассмотреть вариант с использованием Conan-а. Там есть версионирование и пользователь может в локальных настройках указывать собственные версии зависимостей.

V>>Оно уже умеет тащить из разных систем контроля версий хостящихся на разных доменах или из разных локальных папок?
S>Вероятно, вы Conan с чем-то другим путаете. Он вообще никогда (емнип) не предназначался для того, чтобы тянуть что-то из разных систем контроля версий или разных локальных папок.
Ну здрасти, это чуть ли не первое, что требуется в реальности.

S>В Conan-е проекты выкладываются в специальные репозитории (типа conan.io/center), из которых затем и устанавливаются на машине пользователя. При этом репозитории могут быть и свои (развернутые на своих серверах), и чужие. Т.е. необязательно все толкать в conan-center, можно создавать свои репозитории (например, на bintray.com) и пользователю достаточно просто описать такой репозиторий у себя (делается одной командой) для того, чтобы иметь возможность забирать нужные ему библиотеки из этого репозитория.

Т.е. в довесок к репам из github, gitlab, bitbucket, sourceforge (git, svn, mercurial, perforce) и ещё чёрти знает чего, имеем ещё отдельные репы/протоколы под conan? Так это лишнее, не?

S>И то, что Conan скачал на машину пользователя устанавливается в специальные папки, которые находятся под контролем самого conan-а.

Мене нужно просто взять 3dparty из 100500 разных реп, уже существующих до конана. Оно умеет в это?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[4]: Зависимости с github
От: Vain Россия google.ru
Дата: 28.06.20 14:18
Оценка:
Здравствуйте, SaZ, Вы писали:

V>>Жуткое угрёбище, лучше уж подключить 3dparty ссылками в проект и добавлять через add_subdirectory.

SaZ>Вы так будете делать ровно до тех пор, пока не отгребёте с конфигурацией проекта. Если CMakeLists.txt который вы подключаете будет активно менять глобальные свойства. Не говоря уже о том, что некоторые вещи могут делаться лишь на этапе install.
Я так делаю уже несколько лет — полёт нормальный. В качестве конфигурации — обычные шелл скрипты. Все переменные смейка у меня просто вынесены во внешние файлы. Хранить их внутри смейка уже фейл.

V>>Оно уже умеет тащить из разных систем контроля версий хостящихся на разных доменах или из разных локальных папок?

SaZ>Всегда умело. Насчёт систем контроля версий придётся повозиться и написать руками командну строку аля git clone. Из локальных папок, с серверов по URL и прочее — умеет.
Оно умеет по своим протоколам или всё же по чужим? Разница всё-таки значительная.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[5]: Зависимости с github
От: so5team https://stiffstream.com
Дата: 28.06.20 16:45
Оценка: -1
Здравствуйте, Vain, Вы писали:

V>У ExternalProject_Add масса недостатков:


Значит в ваших условиях ExternalProject_Add не подходит.

У других разработчиков эти недостатки могут a) не проявляться или b) могут не быть столь существенными, как у вас.

S>>Вероятно, вы Conan с чем-то другим путаете. Он вообще никогда (емнип) не предназначался для того, чтобы тянуть что-то из разных систем контроля версий или разных локальных папок.

V>Ну здрасти, это чуть ли не первое, что требуется в реальности.

V>Т.е. в довесок к репам из github, gitlab, bitbucket, sourceforge (git, svn, mercurial, perforce) и ещё чёрти знает чего, имеем ещё отдельные репы/протоколы под conan? Так это лишнее, не?


V>Мене нужно просто взять 3dparty из 100500 разных реп, уже существующих до конана. Оно умеет в это?


Если вы хотите, чтобы вам прочитали лекцию по Conan-у, то нет. RTFM: https://docs.conan.io/en/latest/

И лекцию о том, почему кто-то в мире C++ хочет иметь в XXI-ом веке аналоги Maven, Gradle, Cargo, RubyGems, PIP, NuGet и пр. менеджеров зависимостей, так же нет возможности прочитать.
Re: Зависимости с github
От: AlexGin Беларусь  
Дата: 10.07.20 09:19
Оценка:
Здравствуйте, уважаемый Nuzhny, Вы писали:

ИМХО этот вариант наиболее правильный:

N>3. Проект не носит ничего с собой, а зависимости оформлены как git submodules и скачиваются/собираются с гитхаба.

N>Плюс: у нас всегда свежая версия зависимостей.
N>Минус: может выйти новая версия, которую я пока не поддерживаю -> надо указывать версию самому -> теряется плюс новой версии.

При этом, не факт, что всё из новой версии бибдиотеки всегда актуально в нашем проекте.
Re: Зависимости с github
От: alex_public  
Дата: 15.07.20 01:52
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Как делаете или считаете правильным делать?


Я никогда не делал опенсорсные проекты, поэтому тут ничего сказать не могу. Но зато я очень часто использовал множество сложных зависимостей от тяжёлых библиотек (в том числе и опенсорсных с гитхаба) в больших проектах. Поэтому могу изложить так сказать экспертное мнение потенциального пользователя твоей библиотеки:

И так, если ограничиться твоими условиями (система сборки CMake и это довольно логично для опенсорса на гитхабе, т.к. её все знают), то однозначно первый вариант. Который впрочем можно упростить для пользователя с помощью автоматического поиска (в процессе настройки проекта) установленных у пользователя библиотек (с помощью pkg-config под Линухом или переменных среды для некоторых библиотек под виндой). Можно даже предлагать пользователю скачать их (в CMake и такое можно засунуть) в процессе настройки проекта.

Остальные два варианта не удобны по разным причинам. Особенно второй плох — как вспомню ситуацию, когда две жирные библиотеки зависят от одной мелкой, которую они таскают с собой и конечно же разных (несовместимых между собой) версий...

Ну а вообще, если твои пользователи готовы ради твоей библиотечки научиться чему-то не самому попсовому, то можно просто использовать настоящую современную систему сборки с отслеживанием всех зависимостей. Благо такая уже лет пять как появилась в мире C++ (причём она ещё и наголову мощнее всех этих maven'ов и т.п.). И единственный её недостаток в том, что широкие массы хомячков от программирования пока не научились с ней работать.
Re[3]: Зависимости с github
От: alex_public  
Дата: 15.07.20 01:54
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Тот же OpenSSL не соберётся с помощью mingw .


Без проблем собирается. Причём и сейчас и много лет назад. )
Re[6]: Зависимости с github
От: alex_public  
Дата: 15.07.20 02:02
Оценка:
Здравствуйте, so5team, Вы писали:

S>И лекцию о том, почему кто-то в мире C++ хочет иметь в XXI-ом веке аналоги Maven, Gradle, Cargo, RubyGems, PIP, NuGet и пр. менеджеров зависимостей, так же нет возможности прочитать.


Вообще то уже давно есть и на голову превосходящий. Только вот это именно речь о менеджере зависимостей, а не о репозитории готовых пакетов — это большая разница...
Re: Зависимости с github
От: kaa.python Ниоткуда РСДН профессионально мёртв и завален ватой.
Дата: 15.07.20 02:11
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Как делаете или считаете правильным делать?


Логичнее всего использовать менеджер зависимостей типа Conan или vcpkg. Остальные варианты, конечно, имеют право на существование, но должны использоваться только в крайних случаях. Без менеджера пакетов ты, фактически, делаешь его работу вручную. Если (когда) проект разрастается, появляются зависимости между пакетами, которые так же надо будет разрешать вручную. Обновление сторонних пакетов? Снова ручная работа. Зачем всё это?
Re: Зависимости с github
От: Reset  
Дата: 15.07.20 03:09
Оценка:
N>Как делаете или считаете правильным делать?

Использовать

Пакетные менеджеры в C++ есть и ими нужно пользоваться.
Отредактировано 15.07.2020 3:25 Reset . Предыдущая версия .
Re[2]: Зависимости с github
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 15.07.20 05:04
Оценка:
Здравствуйте, alex_public, Вы писали:

_>Ну а вообще, если твои пользователи готовы ради твоей библиотечки научиться чему-то не самому попсовому, то можно просто использовать настоящую современную систему сборки с отслеживанием всех зависимостей. Благо такая уже лет пять как появилась в мире C++ (причём она ещё и наголову мощнее всех этих maven'ов и т.п.). И единственный её недостаток в том, что широкие массы хомячков от программирования пока не научились с ней работать.


Что же это за среда? Ни vcpkg, ни Conan далеко не идеальны и требуют костылей.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.