Comments 16
Полезно. Долго искал подобную статью.
А чем cmake не угодил?
(Просто интересно, не зашло или не пробовали?)
Ответ ближе всего к не пробовали.
Когда начинался наш проект, Qt Creator безобразно с cmake работал, поэтому даже не смотрели на него. Пару лет назад у коллеги был энтузиазм переехать на cmake, пару библиотек перетащили на него, столкнулись с проблемами, поняли, что cmake надо хорошо изучить, а в qmake уже сделано все, что нам нужно, при этом получалось что перевозить на cmake, просто ради того, чтобы перевезти. В итоге не меняли, но решили, что если когда-нибудь начнем новый проект с Qt, то основательно взглянем на cmake.
для введения в conan статья только запутывает
зы посмотрел я на вашем сайте скриншоты софта .... был бы я у вас тестером - повесился )
Несколько вопросов (сейчас как раз вплотную занимаюсь аналогичной темой):
1) А как Вы развели команды conan create и conan upload на GitLab CI/CD?
2) Каким образом решён вопрос выбора номера версии для пакета (вручную или в автомате?)
3) Где храните конан-пакеты? В ГитЛабе (к сожалению у них там имеется проблема в модуле Конана, который они пока не хотят решать), в Артифактори (как решен вопрос авторизации? У меня вообще оно не захотело запускаться из под докера) или в референсном конан-сервере (который они сами не рекомендуют в продакшн, но я пока именно его использую, написав модуль авторизации через ГитЛабу)
4) Как сделаны зависимости между модулями? Жесткая привязка к версиям или "ближайшая подходящая" (тильда, знак больше....)?
Заранее спасибо.
1) Отказались от использования `conan create`. По отдельности запускаем `conan install`, `conan build`, `conan export`, `conan export-pkg` и `conan upload`, разделяем их по разным джобам, install
и build
в джобе build, а export
, export-pkg
и upload
в джобе conan package, таким образом не надо между джобами таскать кеш Conan. В артефактах переезжает только папка с скомпилированными бинарями
2) Номер версии хранится в conanfile.py, и является неотъемлемой частью коммита, а какую часть поднимать по semver полностью человеком решается
3) Собрали conan сервер в Docker, просто `pip install conan`, и `entrypoint conan_server`. Монтируем внутрь папку для пакетов. Подняли его еще когда начинали, так с ним и остались. Сейчас планируем перевезти пакеты в Nexus, но пока руки не дошли. В прод у нас уезжает инсталлер десктопного приложения, либо Docker образы - для серверных приложений. Поэтому ConanServer висит только во внутренней сети, пушить могут только GitLab раннеры после авторизации, а пуллить все кто хочет
4) Все зависимости через ~
. В случае когда меняется сигнатура каких-либо функций в хедерах (даже если изменения обратносовместимые) мы поднимаем минорную версию. После этого необходимо пересобрать все зависимости, чтобы зависимости скомпилились с новыми хедерами. У верхнеуровневых проектов стоят ^
, чтобы конечное приложение тащило самые свежие версии всех библиотек и если какую-то забыли пересобрать, то conan install у верхнеуровневого не пройдет при разруливании графа conan
@ujiman Добрый день! Разбираюсь по докам конана и по вашей статье. Возник вопрос. Как реализовать кейс когда у меня есть 2 пакета и один зависит от другого.
Например есть lib1 и lib2. И lib1 зависит от lib2.
Я в conanfile.py к lib1 прописал
build_requires = ("Lib2/0.1@monsoft/stable")
requires = ( "Lib2/0.1@monsoft/stable")
В итоге при выполнении conan create . monosoft/stable для Lib1 , автоматически подтягивается Lib2 в локальный кеш. Но Lib1 все равно не собирается , так как в моем тестовом примере в исходниках Lib1 сделан например #include "lib2.h"
И соответсвенно когда запускается conan create . для Lib1 при сборке компилятор не видит зависимость Lib2.
В простом случае когда мы собираем клиентское (не учавсвующее в сисеме сборки conan) приложение мы делаем conanfile.txt делаем conan install и нам генериться conanbuidinfo.pri ну и его мы включаем уже в приложение.
А вот в моем вышеописанном случае, откуда взять этот .pri файл для библиотеки Lib1?
PS:
Я попробовал в LIb1 включить pri файл след содержания:
system(conan install -u ../)
CONFIG+=conan_basic_setup
include(conanbuildinfo.pri)
Теперь у меня при запуске conan create . monosoft/stable для Lib1
на этапе
def build(self):
self.run(qmake)
срабатывает этот pri файл и в сборка проходит успешно, не считая предупреждения, но как то мне кажется что я какой то велосипед изобрел......
PPS: Да и спасибо за статью, без нее было бы намного тяжелее разбираться
@ujiman Вобшем разобрался.
Я запутался в начале. Оказывается если указана
build_requires = ("Lib2/0.1@monsoft/stable")
requires = ( "Lib2/0.1@monsoft/stable")
то конан при запуске conan create . сам сделает conan install . в папке сборки в кеше. Вобщем нужно только
include(conanbuildinfo.pri) подключить в профайл lib1 . И таким образом conan install . сгенерит conanbuildinfo.pri) а так как он у нас уже подключен то хедеры и бинары lib2 найдутся!)
Да вы все правильно поняли, единственное не стоит одну и ту же зависимость класть и в build_requires
и в requires
надо выбрать что-то одно.
Основной критерий - будет ли Lib2 светиться из Lib1 при использовании Lib1. Если, например, Lib2 статическая или header only и при этом ее хедеры не светятся из Lib1, то положить в build_requires, а если Lib2 является динамической и понадобится в рантайме, то в requires
@ujiman Понял спасибо. А не подскажете еще такой момеент, больше связанный с интеграцией конана и qmake. Вобщем если Lib1 зависит от lib2, то при сборке в кеше как я и писал выше конан сам генерит conanbuildinfo.pri. А вот при локальной сборке lib1 этот файл нужно генерить руками командой conan install.
Я этот процесс решил оптимизировать и добавил в pro файл lib1 вызов команды conan install
system(conan install -u .)
include(conanbuildinfo.pri)
CONFIG+=conan_basic_setup
сделал это чтобы разработчик просто в IDE нажал qmake make и на этапе qmake инсталились бы зависимости.
Но возникает проблема в том что при сборке в кеше conan сам создает conanbuildinfo.pri а conanfile.py в папке сборки в кеше и вовсе нет. Ну это понятно что как бы так разработчики conan реализовали команду create, она сама какаим то образом делает install зависимостей.
Ну и вобщем при сборке в кеше мой вызов system(conan install -u .) генерит ошибку , что не могу найти conanfile.py . Ну вобщем ничсего страшного не происходит в итоге все собирается все равно дальше, но как то некрасиво получается.
Хотелось бы чтобы при локальной сборке проекта автоматически создавался бы conanbuildinfo.pri , так же как он создается при сборке в кеше. Надеюсь что смог внятно изложить суть своей проблемы:)
PS: Желание конечно вообще чтобы было как например в android studio , открыл проект и начали сами зависимости обновляться (conan install -u).
Единственно что нагуглил по этому вопросу это вот этот тред https://qna.habr.com/q/1072188 тут такой же как у меня вариант только с cmake. И я так понимаю человек тоже столкнется с той же проблемой при сборке в кеше
Мы при первой интеграции с IDE также делали, встраивали `conan install` в qmake, но впоследствии это приводило к сложностям, потому что нам понадобилось пробрасывать разные опции типа версии Qt, поэтому сделали скрипт интеграции, чтобы запуск `conan install` был осмысленным действием.
Касательно вашей проблемы есть следующее решение, которым мы пользовались:
в методе build conanfile, вам так или иначе необходимо вызывать qmake (поэтому можно ему подсунуть флаг, который говорит, о том что qmake запускается из Conan, а не из IDE (т.е. сборка идет со стороны Conan)
в
.pro
файле ориентируетесь на эту переменную, и если она задана не выполняете команду
Пример добавления флага к команде qmake в нашем общем conanfile
qmake ... CONFIG+=conan_exported
Пример использования в .pro
файле
TEMPLATE = app
CONFIG += conan_basic_setup
!CONFIG(conan_exported) {
include($$OUT_PWD/../../conanbuildinfo.pri)
include($$OUT_PWD/../../../conanbuildinfo.pri)
# do whatever you want
}
Как мы навели порядок в C++/Qt проекте с помощью Conan