LINUX.ORG.RU

Помогите со структурой проекта

 ,


0

2

Здравствуйте, хотел бы посоветоваться по поводу структуры проекта на cmake, как сделать правильно и красиво.

На данные момент есть 4 репозитория:

1) libProject - библиотека под GPL в открытом доступе. Есть example app и тесты. Коммиты сюда крайне редки, если не считать синхронизации из mainProject.

2) mainProject - программа, которая зависит от libProject в привате. Никаких сабмодулей, чтобы не усложнять жизнь другим программистам. Периодически вручную синхронизируется с libProject тупым копированием содержимого.

3) subprojectA - часть mainProject в привате, зависит от libProject, libproject подтягивается сабмодулем. В сабмодуль было решено вынести после того, как девелоперы лезли в libProject и ломали mainProject. Если девелоперу нужно внести изменения в libProject, то он должен создать отдельный пулл реквест в libProject, но такая необходимость возникает крайне редко.

4) subprojectB - то же, что и subprojectA, просто другая часть mainProject

Корень subprojectA/B выглядит так:

  • CMakeLists.txt
  • libProject (submodule dir)
  • subprojectA (dir)

В mainProject и назад синхронизация из подпроектов идет опять же в ручном режиме. Как правило над subprojectA и subprojectB в основной программе никто не работает.

Корень mainProject условно выглядит так:

  • CMakeLists.txt
  • libProject (dir)
  • libs (3rdparty libraries dir)
  • subprojectA (dir)
  • subprojectB (dir)
  • src
  • resources

Вопрос такой - как внести subprojectA и subprojectB в основной проект избежав дублирования libProject?

По поводу ручной синхронизации - я раньше пробовал делать это через subtree, но видимо не до конца разобрался и при очередном мердже он мне вывалил миллион конфликтов. Можно ли как-то вернуться к subtree структуре без коммита удаления подпроекта и добавления назад?


Как-то слишком сумбурно написано, текущую структуру слабо понял. А совет простой - избегать дублирования кода в любом проявлении, и всё сразу станет на свои места.

Если есть какие-то две обособленные части проекта, на самом деле есть 3 варианта их существования:

  1. В одном репозитории (больше нигде)
  2. В разных репозиториях, один включается в другой (submodule/subtree/копия исходников/tarball)
  3. В разных репозиториях, подразумевается что та часть что является зависимостью будет опакечена и установлена в систему отдельно (примеры таких проектов libansilove/ansilove, liblcf/easyrpg-player).

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

Если таковые есть, выбор между 2 и 3 может быть довольно сложен, сразу скажу что на него не влияет:

  • «Сложность» submodule. Нет тут сложности, на самом деле это самый правильный способ включать другой репозиторий, т.к. при этом не нарушается требование о единственности копии кода, не засоряется история включающего проекта, и остаётся гибкость в том как обновлять версию зависимости в основном проекте (т.е. в working copy submodule можно переключить на любой коммит и ветку как зафиксировав это, так и во время разработки и тестирования).

  • Возможность сломать один репозиторий коммитя в другой. Для этого придумали CI - если проекты разные, но экосистема одна, при тестировании зависимости может подтягиваться то что от неё зависит и всё собираться/тестироваться вместе. Соответственно если PR в libXXX сломал XXXapp это сразу будет видно. Хотя намного правильнее зафиксировать API и покрыть всё тестами, хотя это и тяжелее.

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

В общем случае я бы начал с одного репозитория со структурой как у вас в последнем примере (subprojectA и subprojectB используют ту же самую libProject что и основной проект, понятно). Библиотеки вынес бы в отдельные репозитории если у них есть чёткое самостоятельное применение, никак не привязанное к проекту (например, библиотека для чтения какого-то формата, или для абстрактной прокладки маршрутов, или плюсовая обёртка над другой либой), но не раньше чем к тому появилась бы объективная предпосылка (например, понадобилась в другом проекте, или кто-то внешний заиспользовал код). По началу включил бы сабмодулем, а если бы основной проект был бы где-то опакечен, и библиотека использовалась бы хотя бы одним чужим проектом, тоже где-то опакеченным, и я бы был уверен что могу гарантировать стабильное API, то можно и затребовать в основном проекте эту библиотеку из системы.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Спасибо.

Да, прошу прощения за сумбурность.

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

Сабпроекты нужны, чтобы фрилансерам, которые приходят, не давать доступ к основной части проекта, а только к ограниченной части.

Основной проект собирает все вместе + много закрытой части, которая доступна только core-команде разработчиков.

Среди программистов есть больше математики, чем программисты, поэтому сабмодули в основную часть и не хочу включать в основную репу. Тогда им придется при каком-то большом чендже делать несколько коммитов - один в libProject, один в subproject и один в mainProjet. Выглядит сложно, как по мне. Для разработчиков из subproject измнения в libProject как правило не требуются, у них строго ограниченная область работы.

Основной вопрос все же сводится к тому, как организовать работу в mainProject, чтобы

1) не было сложно математикам-программистам с сабмодулями

2) избежать ручной синхронизации

3) избежать дублирования libProject в случае включения в основной проект subprojectA и subprojectB. Если их добавить сабмодулями, то в основной репе будет 3 libProject

  • CMakeLists.txt
  • libProject (submodule dir)
  • libs (3rdparty libraries dir)
  • subprojectA (submodule dir)
    • CMakeLists.txt
    • libProject (submodule dir)
    • subprojectA (dir)
  • subprojectB (submodule dir)
    • CMakeLists.txt
    • libProject (submodule dir)
    • subprojectA (dir)
  • src
  • resources
ncuxer
() автор топика
Ответ на: комментарий от ncuxer

открытая часть проекта

чтобы фрилансерам

много закрытой части

А, так у вас проприетарщина? Тогда просто пожелаю мучительно страдать. Будем считать что гайд выше я написал не для вас, а для людей.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Библиотека под GPL, остальное закрыто. В планах есть и открыть весь код в будущем, но сейчас это нецелесообразно с точки зрения заказчика. Не все программы можно и нужно делать под GPL.

ncuxer
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.