Pull to refresh

Comments 37

По поводу распространения: что если использовать CQtDeployer?

Это просто скрипт, который позволяет собрать зависимости Qt. Кроме них в проекте ещё есть зависимости и он не решает проблемы доставки до пользователей приложения и библиотеки

Много раз я думал переписать уже все на go или rust и забыть про проблемы распространения C++ приложений как кошмарный сон. Но каждый раз я понимаю, что любой другой язык не даст мне такой свободы в реализации своих идей относительно проекта.

Какой именно свободы не дают другие языки? Для задач Daggy (IO-bound, асинхронность) и условий применения (простое распространение на разные ОС) использовать Go сам бог велел.

Gui к go не прикрутить потом. Кроме того как спроектировать расширяемый асинхронный интерфейс не очень понятно, чтобы можно было его в плагины вынести например

К Го крутить веб-интерфейс.

Отображать множество стримов в вебе такое себе.

Читаю-читаю про употребление колючек conan'а, думаю ну вот сейчас автор наконец напишет "а давайте теперь попробуем vcpkg" но вот что-то не написал и продолжил употреблять колючки и делать какие-то выводы :(

Когда проект начал, о нем было известно ещё меньше, чем о conan. Надо будет как нибудь попробовать

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

В этом и суть проблемы. Чтобы заинтересовал, нужно чтобы попробовал. По крайней мере мне только так удавалось его продвигать.

Я пока не уверен как сделать автоматический вход через sudo (у меня в компании запрещено входить через root на удаленные сервера), но кажется это реализуемо. А так очень хочется взять и попробовать. Кажется, это идеальный инструмент для локально-удаленной разработки, когда нужно с абсолютно разных сервисов нужно собирать параллельные логи, а сами сервисы не пишут ни в какой агрегатор и с них надо собирать из stdout, у каких-то из файла, к кому то в апишку лезть за метриками и так далее. По крайней мере такой юз-кейс у меня сложился пока смотрел воркшоп и читал доки

sudo требуется только для tcpdump. Можно или убрать команду из файла, или научить запускать tcpdump от пользователя. Тогда sudo не нужен

А так у вас основной сценарий использования утилиты )

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

Вы очень много страдаете со сборкой и пакетированием. Больше половины статьи об этом. Воспользуйтесь nix, он прекрасно работает как пакетный менеджер для с++ и установки системных зависимостей вроде gcc.

Там все это буквально пара строк в buildInputs и nativeBuildInputs. И rpath сам патчит. Жаль что на виндовс его нет.

Это ещё один пакетный менеджер куда нужно встраивать сборку, как в fedora dnf или debian apt-get, а значит не решает проблему.

Проблема С++, что он не имеет пакетного менеджера с изолированным окружением, в который вы можете добавить свой пакет и забыть о его распространении под другие платформы, где может применяться С++. Таким пакетным менеджером мог бы стать conan, но очень далек от этого.

Проблема С++, что он не имеет пакетного менеджера с изолированным окружением, в который вы можете добавить свой пакет и забыть о его распространении под другие платформы, где может применяться С++. Таким пакетным менеджером мог бы стать conan, но очень далек от этого.

nix как раз такой пакетный менеджер, буквально основная фича - это собирать пакеты с внешними зависимостями, в изолированном окружении.

Воспользуйтесь nix, он прекрасно работает как пакетный менеджер для с++ и установки системных зависимостей вроде gcc.

Ничего не могу сказать про nix как ПМ для C++, но nix как ПМ для хаскеля — это просто отвратительно. На одной моей прошлой работе мы делали всякие штуки для Plutus (который язык смарт-контрактов в Cardano), а Plutus живёт в nix-экосистеме. Так вот, это был ад. Это был ад даже несмотря на то, что минимум один коллега получал зарплату за поддержку и развитие nix'а, и у меня был доступ к его мозгам и возможность припрягать его для помощи с моими проблемами.

Во-первых, воспроизводимые сборки (основная якобы киллер-фича nix) — это миф. Было очень смешно, когда из одного и того же коммита у моего другого коллеги всё собиралось, а у меня — валилась сборка R на тестах. Вышеупомянутый мейнтейнер nix даже подключился к моему tmux (tmate FTW!) и часа два там что-то ковырял, ковырял, ковырял, но так и не понял, почему тесты валятся у меня, но не у коллеги. В итоге кончилось всё тем, что он куда-то что-то прописал, и сборка и проверка тестов для R в моём локальном билде скипнулась.

Во-вторых, nix жрёт феерически много места на диске. Мне не хватило моего 240-гигабайтного системного SSD, поэтому пришлось выделить отдельный lvm-раздел на хардах в терабайт специально под /nix (и он всё равно регулярно забивался). Ну ещё бы, если ты хочешь просто собрать криптолибу на хаскеле, а тебе подтягивается R (который при этом не собирается), просто потому, что у криптолибы есть документация, один из пакетов сборки которой умеет выплёвывать что-то там под R… поэтому в итоге подтягивается половина линуксовой экосистемы. Кто du -sh /nix делал, тот над шутками про размер node_modules не смеётся.

В-третьих, о сложностях интеграции nix как ПМ и основного дистра я и не говорю. Пришлось приложить нетривиальные усилия, чтобы neovim (работающий вне nix) нормально взаимодействовал с haskell-language-server (поставленным внутри nix, потому что nix управляет всем, включая инструменты сборки, но делает это очень эгоистично).

В-четвёртых, так себе дружественность к разработчику. Начать можно с наркоманского предметного языка (даже cmake проще, а это таки о чём-то говорит), и закончить напрочь не помогающими сообщениями об ошибках. Я как-то после очередного git pull при попытке сборки получил сообщение в духе «invalid key-value pair parameter syntax in config» — оказалось, nix мне так сообщал о том, что он устарел, и неплохо бы обновиться, ведь я целый месяц его не обновлял.

В-пятых, всё просто очень сложно. Флейки ещё какие-то завезли, потом этот упомянутый выше мейнтейнер нашу кодовую базу на них пару дней мигрировал. Зачем это надо было и что от этого изменилось, я так и не понял. Возможно, это всё (и соответствующая сложность) имеет смысл, если пользоваться nix'ом как дистрибутивом, но nix как ПМ — не, оверкилл.

В-шестых, у меня сложилось впечатление очень ЧСВшного сообщества разработчиков nix. В какой-то момент, например, они отказались выкладывать исходные тексты релизов, поэтому мне в моей генте обновлять nix стало сложнее. Когда я зашёл к ним то ли в ирку, то ли куда-то ещё, и попросил выкладывать архивы исходников для сборки под другие дистрибутивы, мне ответили, что, по смыслу, проблемы других дистрибутивов шерифа не волнуют. Мне кажется, что у разрабов nix нет кредита на соответствующие выпендривания.

Поэтому, например, когда я сейчас вижу проект, использующий nix, я первым делом пишу свой stack.yaml и игнорирую напрочь всю эту пониксень. Это оказывается проще и продуктивнее, чем париться с nix.

Но, конечно, у nix есть и положительные аспекты: скажем, когда нашу команду по формальной верификации смарт-контрактов разогнали из-за потери спроса на эту верификацию, я очень грустил, потому что и задачи были интересные, и коллеги классные. И только осознание, что мне наконец-то больше не придётся трогать nix, и можно про него забыть как страшный сон, помогло мне преодолеть эту чёрную полосу в моей жизни. Спасибо nix!

Честно говоря, я не очень понял претензии к языку. Установка неподписанных/ненотаризованных бинарей - это в любом случае проблемное дело в той же винде или в macOS вне зависимости от того, на каком языке написано то, из чего эти бинари собраны. А если вы хотите просто показать потенциальному пользователю свое приложение в режиме "скачать и запустить", то требовать, чтобы этот потенциальный пользователь имел тулчейн для его сборки (а скорее всего еще и тулчейны для сборки всех его зависимостей, ведь они могут быть написаны на разных языках), каким бы распрекрасным и удобным этот тулчейн ни был - ну, такое.

Я считаю это особенностью языка. GO например такой проблемы не имеет. Если вы установили go, то этого достаточно и это гарантия того, что зависимости соберутся. В принципе и со всеми остальными языками так же (java, python, ruby, c#, rust и т.д.). Мне даже трудно назвать язык имеющий такую же проблему. Везде наличие компилятора/интерпретатора языка даёт гарантию подключения зависимостей.

Везде наличие компилятора/интерпретатора языка даёт гарантию подключения зависимостей.

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

Есть две проблемы:

  1. Проблема сборки зависимостей

  2. Проблема запуска

Для go обе проблемы решены

  1. Чтобы собрались зависимости достаточно компилятора go

  2. Чтобы приложение запустились, достаточно его один раз собрать на платформе (все зависимости линкуются статически).

Таким образом go на уровне языка решает обе эти проблемы. И так во всех языках обе эти проблемы каким то образом решены. Да, для некоторых потребуется заранее настроить ещё окружение для запуска (python, java, c#), но оно одно и ставится единожды на всю платформу.

В С/С++ задача сборки и запуска вообще никак на уровне языка не решается.

Еще раз - я не хочу себе на машине компилятор go (это как минимум, еще раз повторюсь, что если само приложение написано на go, это не значит, что все его зависимости написаны на go) для того чтобы один раз запустить приложение на попробовать. Везде это решается бинарными пакетами, которые я просто скачиваю из некоего стора или хранилища пакетов. Я все еще не понимаю, чем условный go в этом плане лучше чем условный C++. Бинарный пакет есть бинарный пакет, и проблемы его установки никак не зависят от языка на котором он написан.

Go лучше, потому что он вам на выходе даёт готовый к запуску на платформе бинарник. Для С++ вам ещё нужно организовать portable версию архива. Например самостоятельно пройтись по всем зависимостями положить их в одну папку. А вы могли ещё сделать это не правильно, например, случайно поместив в ваш архив библиотеки из системы, а не из зависимостей,с которыми вы собирались.

Это только в теории так все просто, со сферическим конем в вакууме. На практике же например у используемых вами (возможно, даже не напрямую) библиотек бывают плагины, которые статически просто не линкуются, а подгружаются исключительно динамически (через dlopen() или подобные механизмы). Более того, на разных системах нужны разные плагины в зависимости от... много чего - например, где-то нужен плагин для Xorg протокола, а где-то для Wayland, версия библиотеки, установленная в системе, об этом в курсе, а то, что вы там статически себе прилинковали - нет. Го вам поможет только в наипростейшем случае хелловорлда, что-то чуть более сложное - и вы будете совершенно так же огребать.

С этим я не спорю совершенно. Это вообще основная причина, почему я не поменял в итоге язык, он даёт полную свободу и возможность реализовать что угодно и интегрироваться куда угодно.

Но факт в том, что язык с++ не решает проблемы сборки и распространения вообще никак, в то время как в других языках эта проблема решена.

в то время как в других языках эта проблема решена

Это в какой-то степени решено только в языках, которые имеют свой рантайм (типа упоминавшихся вами питона, явы или шарпика), там просто все эти проблемы переложены на рантайм - и опять же, только если у вас нет вызовов каких-то сторонних библиотек через native interface. Говорить же, что эта проблема решена в языке потому что он может статически слинковать бинарь - ну, ИМХО, такое. И опять же, этот статически слинкованный вами бинарь, даже если нет никаких условных плагинов (или вы их не забыли все трудолюбиво найти и добавить в пакет), все равно будет точно так же огребать в винде или макоси от паранойи с подписями, как у вас в статье написано.

Нет, в go есть фича go run. То есть можешь поставить в системе go и запускать нужные тебе утилиты указывая ссылку на гитхаб нужной тебе утилиты. Тогда и проблема с паранойей решается тоже, а для разработчиков утилит можно дале не собирать бинарник для распространения.

И go это частный случай, во всех современных языках, что я знаю, эта проблема решена.

То есть можешь поставить в системе go

Ну собственно на этом можно и закончить :) Шутка (наполовину). А если серьезно - мы же берем случай не хелловорлда, а серьезного приложения с зависимостями, написанными на разных языках. То есть возвращаемся к началу - для "решения проблемы" (человек хочет попробовать новое приложение) ему нужно поставить go, поставить C/C++ компилятор, возможно, растокомпилятор (для зависимостей)... Боюсь, что с таким подходом у вас не получится значительно расширить пользовательскую аудиторию :)

Нет, зачем компилятор с/с++? Go достаточно. На понятно что gui приложение ты не соберёшь так, но это другое ограничение другого языка уже.

Нет, зачем компилятор с/с++? Go достаточно.

Ну как же, вот я например хочу использовать в своем приложении sdl2 (или любую другую библиотеку, написанную на C) через например вот такой враппер. Враппер при наличии только go вы может и соберете, а саму sdl2 кто будет собирать?

На понятно что gui приложение ты не соберёшь так, но это другое ограничение другого языка уже.

Таким образом можно собрать только относительно несложное приложение без зависимостей написанных на других языках. А другие языки были, есть и будут есть, потому что серебряных пуль не существует.

Это мы говорим о линковке с системными библиотеками из языка, которых нет из коробки. Ну в таком случае такой подход не будет работать, да. Но это все же ограничения языка я считаю. Когда он не может покрыть функциональность своими средствами, приходится их тянуть из с/с++ и тогда конечно будет не так просто выглядеть сборка. Но это частный случай. А в с/с++ любая сборка и распространение могут стать проблемой

Не очень понял суть проекта. Собиратель логов различных служб в одном gui окне?

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

Нет) что то вроде ansible, но который запускает все команды одновременно, стримит их вывод и сохраняет его локально. Я все ещё не придумал, как объяснить коротко, что делает проект

Обидно за Конан.

Conan все еще нельзя использовать как пакетный менеджер С++

мы в проекте чудесно его используем, причем и для мобильных платформ тоже. Щас как раз заканчиваем портирование на v2.

Qt официально не поддерживает conan

как и более 95% других библиотек. Но что значит «поддерживать» Конан? «Рецепты» Конана — всего лишь набор команд по сборке и установке библиотек, которые можно и ручками вызвать.

С тех пор в марте 2025 у Qt вышел релиз 6.9.0, но его до сих пор не смогли вмержить в conan-center-index

При этом есть два закрытых, но не вмерженных пулл реквеста с обновлением версии qt (первыйвторой).

если все-таки почитать ПРы, то там не «не смогли вмержить», а:

  1. на CI не собирается из-за старого тулчейна

  2. автор тупо закрыл ПРы, потому что их не вмержили достаточно быстро / не адаптировали CI — как будто обиделся

ничего не мешает вновь их открыть и вступить в контакт с мейнтейнерами CCI, чтоб мерж все-таки произошел.

При этом digia делала некоторые попытки самостоятельно оседлать conan движение и выпустила свой conan репозиторий, но похоже там все заглохло

да, где-то они писали (в блоге вроде), что забили из-за очень малого спроса. А жаль.

Отсутствуют релизы. Основной поддерживаемый conan репозиторий - это conan-center-index. В нем отсутствуют релизы как таковые. Это значит, что если вы жестко не укажете версию зависимостей (включая хеш суммы бинарных пакетов), то вы рискуете в один из моментов просто потерять собираемость ваших зависимостей.

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

Вообще, рекомендуется хранить свои бинарные пакеты на своем сервере (артифактори ну либо в виде архива). Также можно иметь клон CCI нужных рецептов. Можно даже исходники библиотек кэшировать.

Conan нельзя использовать в качестве системного пакетного менеджера

его никто и не позиционирует так.

Если ваш пакет явно не инклудит <cstdint>, но при этом использует типы оттуда, то он просто не соберется у конечного пользователя.

так он и без Конана не соберется. Это проблема кода программы/библиотеки, а не пакета Конана. Конечно, в отдельных случаях можно накатить свой патч на подобную проблемную библиотеку либо при возможности решить это через разные точки кастомизации Конана, но это уже как обходные пути.

Conan подходит для фиксации текущей версии сборки, но не для непрерывного выпуска обновлений. Исходя из описанных выше проблем, каждое обновление версий зависимостей может превратиться в “приключение на 20 минут” для каждой из платформ

чаще всего с Конаном это никак не связано: ручное обновление зависимости точно так же может вызвать ошибку сборки.

Сложно добиться аппрува. Первый мой пулл реквест в conan-center-index прошел достаточно быстро, но второй висит уже неделю без движения на стадии “получить аппрув для сборки”.

Да, и это частая претензия к CCI (можно в issues найти). Причина ясна: мейнтейнеров крайне мало, а ПРов — много, ресурсы CI также ограничены. У меня ПРы и месяцами висят, но это никак не мешает использовать свои форки с правками при сборке зависимостей.

Вы можете представить подобного рода дискуссии вокруг go/python/java и других современных языков программирования со своими пакетными менеджерами? Я не могу. Я в статье специально написал, что conan - это лучшее, что произошло в мире С++, но он до сих пор далек от того, чтобы его можно было назвать менеджером пакетов языка С++. На текущий момент он может существенно упростить работу с зависимостями и собрать ваш проект для конкретных версий. Но постоянно поддерживать зависимости в актуальном состоянии для вашего проекта очень тяжело и опубликовать ваш пакет тоже не просто

По поводу Qt. Там тот же самый автор снова выложил два пуллреквеста, надеюсь они вмержатся.

Могу представить. Карго не собрал мне опенссл для какого-то проекта.

Пип начиная с некоторого объёма своей мусорки(кэша) начинает путаться и загибается.

А Го вкорячивает все зависимости в один 100Мб бинарник, чтобы избежать проблем с подгрузкой.

Вообще я сторонник не молиться на системы сборки, а понимать как работает чтобы править ручками.

Вообще странно ссылаться на то, что в новых языках все сделано удобнее.

Sign up to leave a comment.

Articles