@semenyakinVS
Писатель кода и не только

Как правильно организовать проект, выкладываемый в open source?

Собираюсь выкладывать в open source библиотеку. Внимательнее изучив организации нескольких open source проектов, с которыми имел дело, пришёл к выводу, что, как правило, проекты имеют следующую структуру:

/src --- Исходники из которых можно собрать библиотеку
/include --- Интерфейс для доступа к API собранной библиотеки
/test --- Тесты для кода проекта
/lib --- Собранная библиотека, как-нибудь стабильная версия
/doc --- Документация к проекту
... --- Другие папки - какие?

README.txt --- Информация для первичного ознакомления с библиотекой
INSTALL.txt --- Общая информация о настройке проекта
LICENCE.txt --- Информация о лицензии

Вот ещё пример проекта: asio. Структура не совсем такая, но тоже сойдёт, как по мне.

Обычно работа с проектами, организованными подобным образом, выглядела для меня так:
1. Использование либы. Я клоню репу полностью, в клоне собираю библиотеку (папка source), потом копи-пастой тащу папку include и папку с собранными бинами к себе в проект, теряя таким образом какую-либо связь с репой.
2. Тестирование либы. Я прямо в скаченной версии репозитория открываю проект с тестами, вручную копи-пащу либу рядом с тестами, собираю - и смотрю как работают тесты.

Я правильно понимаю, что всё рассчитывается на подобный способ работы с репозиторием? И нет ли другого способа организации репозитория, который позволяет при работе с ним более плотно связать свой проект с контролем версий самой библиотеки (сейчас есть момент копи-пасты, который разрывает связь)?

П.С.: Да, возможно, это тоже важно. Библиотека написана на С++.
  • Вопрос задан
  • 2026 просмотров
Решения вопроса 1
Да, возможно, это тоже важно. Библиотека написана на С++.

Да, это важно. Мы тоже используем примерно ту же структуру проектов, и стараемся её придерживаться на всех используемых платформах, однако технические различия между ними диктуют и различия в структуре. Например, папка include в мире .net не нужна, т.к. вся необходимая информация о содержимом библиотеки находится в самой сборке. То же касается и Java-библиотек. В целом, я согласен с вами по структуре репозитория (единственная вкусовщина для меня - называть папки docs и tests во мн. числе :)).

Другие папки - какие?

Вот в последнее время считаю крайне полезной папку examples с кодом примеров по использованию библиотеки. Очень удобно, когда на основные сценарии использования либы есть по проекту/файлику с кодом примера. Очень быстро можно пробежаться по возможностям библиотеки, и оценить удобство использования (накануне сранивал таким образом json-либы для C++). И для вас это тоже своеобразные "тесты" на удобство. У этих "тестов" задача не покрыть логику на 100%, а показать, как взаимодействовать с библиотекой в основных, стандартных сценариях.

Отмечу, что вы очень хорошо написали про API библиотеки в include. Многие разработчики почему-то кладут в эту папку и приватные хедеры тоже. Я лично в этом смысла не вижу - все приватные хедеры это часть основных исходников, а они находятся в /src.

потом копи-пастой тащу папку include и папку с собранными бинами к себе в проект

Вот это я не знаю честно говоря, зачем вы делаете - папки include и lib как раз на то и рассчитаны, чтобы их было удобно подключать к компилятору и линковщику - как раз пути к этим папкам и передаются при подключении зависимых библиотек. Единственное, что может быть нужно скопировать из папки библиотеки - собранные бинарники (dll/so) в случае динамической линковки, если нет возможности/желания прописывать пути к динамическим библиотекам. Ну и какие-нибудь файлы данных, если таковые есть.

Тесты вообще должны собираться вместе с библиотекой (например, в папку /bin), также по идее ничего никуда копировать не надо.

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

Также, вы почему-то не указали используемую систему сборки. В том же CMake есть очень полезная фишка, называется find_package, которую грех не использовать.

В целом, отмечу что копи-пасты должно быть минимум, include и lib копироваться не должны вообще, для этого у любого компилятора есть ключи (например, -I и -L). Даже если копирование неизбежно, его следует максимально автоматизировать в сборочных инструкциях. Многие системы сборки умеют определять, что некоторые файлы устарели (например, вы перекомпилили dll), и в этом случае их можно попросить скопировать эти файлы.

Чем вы все-таки либу свою собираете? Это важно, т.к. даже для опытных разработчиков сборка незнакомой C++ библиотеки может стать целым делом.

Да, кстати еще момент с include-ами: именно по причине того, что библиотеки обычно подключаются путем указания путей компилятору и линковщику (которые потом соберут содержимое всех include и lib-папок в единое пространство имён), есть популярная договоренность создавать в папке include подпапку с именем библиотеки, например: раз, два, три. Это даёт возможность инклудить так: #include <soci/blob.h>, а не так: #include <blob.h>. Это позволяет разработчику называть файлы коротко и так, как ему удобно (blob.h вместо soci_blob.h), и при этом сводить риск конфликта имен инклудов к минимуму.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@balamut108
Py
Самую большую ценность для меня в OS - это возможность абстрагирования от реализации и возможность просто использовать библиотеку в своём коде без дополнительных сложностей. Вот на что надо обратить внимание в первую очередь. То что Вы описали, конечно, по большей части так, но главное это документация и возможность начать использовать библиотеку после 3-5 минут ознакомления с доками.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы