If a C programmer asks "do you want to see something cool?", run away.
--John Van Enk

Thursday, February 9, 2017

c++ ecosystem pain points

Последние несколько месяцев я снова связан с разработкой на C++ (и C). Пришлось вспоминать подзабытые навыки и приобретать новые знания. Будучи причастным к ruby community последние несколько лет и немного к Go позволяет взглянуть на разработку на C++ несколько под иным углом. Основное наблюдение - большое колличество времени тратится не продуктивно.




Dependencies management

Для работы с зависимостями при сборке проекта мы используем комбинацию git submodules и ExternalProject_Add из cmake. Submodules - чтобы обеспечить правило "build should succeed if it is successfully cloned". Но уже при наличии 3х уровней Application->Module->Library - работа с зависимостями, в частности их апдейт до последних стабильных версий, становится затруднительной. Если ownership всех трех уровней за вами - то можно считать повезло, но если вдруг окажется, что где-то в зависимостях оказалась 3rd party library (xerces-c, xml-security-c, openssl, etc), а вам нужно обеспечить автоматическую сборку на Win32/Win64  - то на настройку сборки легко уходит до одного человеко-дня per dependency. Иногда это приводит к тому что в репозиторий просто добавляют binary blobs для всех поддерживаемых архитектур и платформ через git-lfs, например, + includes, которые потом не трогают годами потому. что "работает - не трогай".

Я как-то сделал попытку описать как должен ИМХО выглядеть идеальный dependency management tool но прогресс дальше этого пока не пошел.

Build system

Система сборки должна собирать проект. Быстро. Везде, на всех платформах.
Это основное требование. Еще крайне желательно чтобы был single source of truth - один для всех платформ файл с описанием как из текстовых файлов с кодом получить бинарник. Bazel, Pants - отпадают, т.к. UNIX-only, Buck - worth considering. Сейчас используем CMake как приемлемый вариант, рассматриваем Meson. Если надо быстро - make -j, главное правильно использовать add_dependencies. CMake gotchas достойны отдельного поста.

Legacy hurts Quality

Иногда нужно просто брать и выбрасывать наследие прошлых лет и делать новые библиотеки с идиоматичными интерфейсами, учитывая ошибки прошлых лет. Есть, например, zlib и все его используют, даже boost::iostreams но иногда хочется чтобы был std::zip который умеет работать с итераторами и последовательностями, например. Про 3rd party libraries которые изменяют глобальный state и просто потоко-небезопасны можно страшилки сочинять вроде "найди дедлок за 7 дней". О чем вообще можно говорить, когда даже качество библиотек boost - на самом деле оставляет желать лучшего:

и компиляторов от компании, ИмяКоторойНельзяНазывать, но мы все знаем что это Microsoft :)

Возьмите немножечко трансдьюсеров на C++14

Добавьте компилятор MSVC...
Что в итоге получится можно прочесть здесь.

Community

Сообщество C++ напоминает векторное поле в котором вместо векторов - Лебедь, Рак и Щука в каждой точке пространства.

CppCoreGuidelines попытка исправить такое положение вещей, по видимому. До этого у каждого был свой путь, который он должен был пройти, чтобы постигнуть Zen. И не факт что твой Zen это тот же Zen, который у коллеги, сидящего с тобой рядом. Путь этот обычно усеян сломанными велосипедами, которые падаван строит из соображений "лучше плохо ехать чем хорошо идти". Фанатичного отношения к тестированию, которое есть в ruby community, мне лично не хватает очень сильно. Отсутствие стандартизированных build system и deps management инструментов приводит к фрагментации сообщества.