2013-08-04 4 views
0

Я строю очень базовую библиотеку, и это первый проект, который я планирую выпустить для других, если захотят. Таким образом, я хотел бы знать, что такое «лучшие практики» в отношении организации. Единственное, что может быть уникальным о моем проекте является то, что для того, чтобы использовать его в проекте, пользователи должны будут распространяться определенные абстрактные классы, что приводит меня к моему первому вопросу:Организация библиотеки C++

  • много из библиотек, которые я видел, состоит из файла .a и одного файла .h. Это лучшая практика? Не было бы лучше разоблачить все общедоступные файлы .h, чтобы пользователи могли выбирать, какие из них включать? Если это предпочтительный способ сделать что-то, как это делается? Что входит в этот файл .h?

Мой второй вопрос включает зависимости. Например, мой текущий проект основан на OpenGL, GLFW и GLEW. Должен ли я скомпоновать их каким-либо образом с моим проектом или просто поручить пользователю гарантировать, что они установлены?

Редактировать: Кто-то спросил о моей целевой ОС. Все мои зависимости - это кросс-платформа, поэтому я (возможно, наивно) надеялся сделать свою библиотеку и кросс-платформой.

Спасибо за любую помощь!

+0

Прежде всего: какой тип лицензии имеет ваша библиотека? и что такое целевая ОС? – zaufi

+0

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

ответ

2

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

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

В вышеуказанном случае также возможно иметь один «общий» заголовочный файл, который содержит несколько более мелких. В частности, если у вас довольно большие классы, их все в одном файле становится довольно грязным.

С другой стороны, если у вас есть один набор функций, которые касаются газов, растворенных в жидкостях, другой набор функций для расчета прочности/грузоподъемности стального баллона и другой набор функций для расчета трения резиновую шину на поверхности дороги, то они, вероятно, должны иметь разные заголовки, даже если все возможности выполняются в «Библиотеке физики/механики».

Редко рекомендуется поставлять библиотеки сторонних библиотек - да, если вы хотите предложить две загрузки, одну с «все, что вы, просто добавьте воду» и одну «голую библиотеку», это хорошо. Но я не хочу тратить три раза дольше, чем нужно, чтобы загрузить вашу библиотеку, просто потому, что она также содержит три другие библиотеки, которые использует ваш код, который уже находится на моей машине. Однако сделайте документацию о том, какие библиотеки нужны, и что вам нужно сделать, чтобы установить их на поддерживаемых платформах (и на каких поддерживаемых платформах). И какие версии библиотек вы протестировали - нет ничего хуже, чем «получение последних», только чтобы найти, что версия нуждается в двух шагах назад ...

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

+0

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

1

У вас есть варианты, и это действительно зависит от того, насколько удобно вы выбираете его для разработчиков, использующих ваши библиотеки.

Что касается заголовков, общий метод для библиотек средней сложности - иметь один заголовок, который разработчик может включить, чтобы получить все необходимое. Хороший метод - если у вас несколько заголовков, создайте один заголовок с тем же именем, что и ваша библиотека (не обязательно, просто обычная), и пусть он # включает все отдельные заголовки. Затем распределите один заголовок и отдельные заголовки. Таким образом, у ваших пользователей есть опция #, включающая только один, чтобы получить все, или # включая отдельные, если это необходимо.

E.g. в mylibrary.h:

#ifndef MYLIBRARY_H 
#define MYLIBRARY_H 

#include <mylibrary/something.h> 
#include <mylibrary/another.h> 
#include <mylibrary/lastone.h> 

#endif 

Убедитесь, что ваши отдельные заголовки могут быть включены автономные (т.е. они #include все, что нужно), если вы хотите, чтобы предоставить такую ​​возможность разработчикам.

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

  1. Нарушение систем пользователя, у которых уже установлены зависимости.
  2. Как упоминалось в ответе Маца Петерсона, заставляя пользователей загружать зависимости, которые у них уже есть.
  3. Нарушение прав на лицензирование сторонних библиотек.

Лучшее, что вам нужно сделать, - это четко документировать необходимые зависимости.

Для этого нет действительно стандартных «лучших практик». Любая нормальная практика будет хорошей практикой.

+0

Добавил пункт 2 в список выше, как указал Матс. –

+1

Я принял ответ Матса, потому что он был немного более подробным, но ваш ответ также был очень полезным. Я даже не думал о проблемах с лицензированием. – williamg

+0

Мне нравится ответ Матса лучше. –

Смежные вопросы