Я создаю очень простую библиотеку, и это первый проект, который я планирую выпустить для использования другими людьми, если они захотят. Таким образом, я хотел бы знать, что некоторые «лучшие практики», насколько организация идет. Единственное, что может быть уникальным в моем проекте, это то, что для его использования в проекте пользователям потребуется расширить некоторые абстрактные классы, что приводит меня к моему первому вопросу:
Мой второй вопрос связан с зависимостями. Например, мой текущий проект опирается на OpenGL, GLFW и GLEW. Должен ли я каким-то образом упаковать их в свой проект или просто возложить на пользователя ответственность за их установку?
Изменить: Кто-то спросил о моей целевой ОС. Все мои зависимости кроссплатформенные, поэтому я (возможно, наивно) надеюсь сделать мою библиотеку кроссплатформенной.
Спасибо за любую помощь!
Это действительно зависит от обстоятельств. Если у вас есть довольно сложные функции, входящие в число тесно связанных функций, то один заголовок — правильное решение.
Например. вы пишете набор функций, которые рисуют что-то на экране, и вам нужно несколько функций для настройки / настройки среды, несколько функций для определения и размещения объектов на сцене, несколько функций для фактического рисования / обработки, и, наконец, демонтаж, а затем использование одного заголовочного файла — хороший план.
В приведенном выше случае также возможно иметь один «общий» заголовочный файл, который включает в себя несколько меньших. В частности, если у вас достаточно большие классы, вставлять их в один файл становится довольно грязно.
С другой стороны, если у вас есть один набор функций, которые работают с газами, растворенными в жидкостях, другой набор функций для расчета прочности / несущей способности стальной балки и другой набор функций для расчета трения резиновой шины относительно если у них есть дорожная поверхность, то они, вероятно, должны иметь разные заголовки — даже если это все возможные функции — перейти в «Библиотеку физики / механики».
Редко хорошей идеей является предоставление сторонних библиотек своей библиотекой — да, если вы хотите предложить две загрузки, одну с «все, что вам нужно, просто добавьте воды», и одну «голую библиотеку», это нормально. Но я не хочу тратить в три раза больше времени, чем необходимо, чтобы загрузить вашу библиотеку, просто потому, что она также содержит три другие библиотеки, которые использует ваш код, который уже находится на моем компьютере. Однако, документируйте, какие библиотеки нужны, и что вам нужно сделать, чтобы установить их на поддерживаемых платформах (и какие есть поддерживаемые платформы). И какие версии библиотек вы тестировали — нет ничего хуже, чем «получить последнюю версию», только чтобы обнаружить, что нужная версия находится в двух шагах назад …
(И, как отмечает Джейсон С., лицензирование становится очень запутанным, когда у вас есть несколько разных пакетов, от которых зависит ваш код, потому что ваша лицензия должна быть совместима со ВСЕМИ другими лицензиями — иногда это даже невозможно …)
У вас есть варианты, и это действительно зависит от того, насколько удобно сделать это для разработчиков, использующих ваши библиотеки.
Что касается заголовков, общий метод для библиотек средней сложности состоит в том, чтобы иметь один заголовок, который разработчик может включить, чтобы получить все, что ему нужно. Хороший метод, если у вас несколько заголовков, создайте один заголовок с тем же именем, что и у вашей библиотеки (не обязательно, просто общий), и включите в него #include все отдельные заголовки. Затем распределите один заголовок и отдельные заголовки. Таким образом, ваши пользователи имеют возможность #include только один, чтобы получить все, или #include отдельных, если необходимо.
Например. в mylibrary.h:
#ifndef MYLIBRARY_H
#define MYLIBRARY_H
#include <mylibrary/something.h>
#include <mylibrary/another.h>
#include <mylibrary/lastone.h>
#endif
Убедитесь, что ваши отдельные заголовки могут быть включены автономно (т.е. они включают в себя все, что им нужно), если вы хотите предоставить эту опцию разработчикам.
Что касается зависимостей, вы захотите сделать так, чтобы пользователь отвечал за их установку. Пользователь компилирует свой код и ссылается на вашу библиотеку, поэтому он также обязан ссылаться на зависимые библиотеки. Если вы упаковываете сторонние зависимости в свою библиотеку, вы рискуете:
Лучшее, что вы можете сделать, это четко документировать необходимые зависимости.
Для этого не существует действительно стандартных «лучших практик». Любая вменяемая практика была бы хорошей практикой.