Header only либы. Pros and cons
#новичкам
Мы живем в мире С++, где почти нет ничего общепринятого. Часто даже не для очень специфичной задачи, типа сериализации, приходится искать какие-то сторонние решения и сравнивать их. Давайте отложим в сторону вопросы о качестве кода и дизайне и сконцентрируемся вот на чем. Какую библиотеку выбрать: уже скомпилированную или полностью header-only? Будем рассматривать вопрос с точки зрения header-only либ. Какие у них преимущества и недостатки?
Преимущества:
✅ Упрощенный процесс сборки. Вам не нужно ничего компилировать библиотеку и в кишках симейка указывать кучу зависимостей. Подключил хэдэр, указал к нему путь и вперед!
✅ Упрощенная поддержка. Если у вас есть скомпилированная библиотека, вы, вероятно, захотите создать несколько ее версий: одну скомпилированную с включенной отладкой, другую с включенной оптимизацией и, возможно, еще одну без символов. И, возможно, даже больше для мультиплатформенного приложения. Все это довольно сильно усложняет интеграцию библиотеки и будущее обновление.
✅ Можно нормально дебажить. Большинство бинарных либ распространяются именно в релизной версии и их функции невозможно нормально дебажить. Я знаю, что большинство из вас дебажатся принтами и ваша хата с краю, но иногда очень полезно было бы иметь дебажную версию.
✅ Бо'льшая переносимость. Не все компиляторы одинаково компилируют одни и те же сущности даже на одной и той же платформе. Ваша ддлка или сошник может просто по ABI вам не подходить. Хэдэр-онли либы приходится компилировать вместе с проектом, что убирает проблему несовместимости ABI.
✅ Возможность использования нестандартной стандартной либы. Оксюморон? Может быть. Но иногда вам может понадобиться использовать либо свою, либо пропатченную стандартную библиотеку. Возможно, в вашем проекте запрещены вызовы каких-то стдшных функций или вы сами подкручиваете и оптимизируете код в узких местах. Тогда ваше единственное спасение - хэдэр онли либы. Только они позволят вашим изменениям отразиться на скомпилированном коде библиотечных сущностей.
Недостатки:
⛔️ Крупные объектные файлы. Раз нам доступно определение сущностей, то мы можем попробовать их встроить. Это само по себе увеличивает размер бинарного файла. Так еще и на каждую единицу трансляции будет свое определение слабого символа этой сущности. Да, в конце они объединятся, но в объектные файлы все еще будут повторения.
⛔️ Более длинная компиляция. Раз код еще не скомпилирован, то надо его скомпилировать. Причем даже те сущности, которые используются в нескольких единицах трансляции, придется компилировать в каждой из них отдельно. Большое обилие компилируемых сущностей и слабых символов сильно тормозят работу компилятора и линкера.
⛔️ Перекомпиляция. При изменении исходников вам скорее всего будет нужно перекомпилировать весь проект. С бинарными либами такой проблемы нет. Перекомпилировать нужно только те единицы трансляции, которые непосредственно используют код библиотеки.
⛔️ Кожаным труднее читать. Даже с лучшей документацией пользователям библиотеки часто приходится прибегать к чтению заголовков библиотеки. Заголовки в хэдэр-онли либах заполнены деталями реализации, которые мешают пониманию интерфейса. С скомпилированной библиотекой все, что вы видите, это интерфейс и краткий комментарий о том, что делает реализация, и это обычно все, что вам нужно. Даже так, ничего кроме этого вам не должно быть нужно! Нафиг детали реализации, концентрируемся на интерфейсе.
В каждом конкретном случае разные ключевые факторы играют роль, поэтому нельзя дать универсальный ответ на вопрос "какой тип либы исопльзовать?". Контекст вам сам подскажет ограничения. Надо просто уметь метчить ограничения с типом библиотеки.
Make the right choice. Stay cool.
Post #585
4.81K