Я большой поклонник подмодулей Git . Мне нравится иметь возможность отслеживать зависимость вместе с ее версией, чтобы вы могли выполнить откат к предыдущей версии вашего проекта и иметь соответствующую версию зависимости для безопасного и чистого построения. Более того, проще выпустить наши библиотеки как проекты с открытым исходным кодом, поскольку история библиотек отделена от истории приложений, которые зависят от них (и которые не будут открыты).
Я настраиваю рабочий процесс для нескольких проектов на работе, и мне было интересно, как было бы, если бы мы взяли этот подход немного в крайность вместо того, чтобы иметь один монолитный проект. Я быстро понял , что это потенциал может червей в самом деле с помощью суб-модулей.
Предположим, пара приложений: studio
и player
, и зависимые библиотеки core
, graph
и network
, где зависимости следующие:
core
автономныйgraph
зависит отcore
(подмодуль в./libs/core
)network
Зависит отcore
(подмодуль в./libs/core
)studio
зависит отgraph
иnetwork
(субмодули в./libs/graph
и./libs/network
)player
зависит отgraph
иnetwork
(субмодули в./libs/graph
и./libs/network
)
Предположим, что мы используем CMake, и у каждого из этих проектов есть модульные тесты и все работы. Каждый проект (включая studio
и player
) должен иметь возможность компилироваться отдельно для выполнения метрик кода, модульного тестирования и т. Д.
Дело в том, что рекурсивно git submodule fetch
, тогда вы получите следующую структуру каталогов:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/ (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/ (sub-module depth: 2)
studio/libs/network/libs/core/
Обратите внимание, что core
дважды клонируется в studio
проекте. Помимо этой траты дискового пространства у меня есть проблема с системой сборки, потому что я собираюсь core
дважды, и у меня потенциально могут быть две разные версии core
.
Вопрос
Как организовать подмодули так, чтобы получить версионную зависимость и автономную сборку без получения нескольких копий общих вложенных подмодулей?
Возможное решение
Если зависимость от библиотеки является чем-то вроде предположения (то есть в моде «известно, что она работает с версией X» или «официально поддерживается только версия X») и потенциальные зависимые приложения или библиотеки отвечают за сборку с любой версией, которая им нравится, тогда Я мог бы представить следующий сценарий:
- Соберите систему сборки
graph
иnetwork
скажите им, где найтиcore
(например, через компилятор включите путь). Определите две цели сборки: «автономный» и «зависимость», где «автономный» основан на «зависимости» и добавляет путь включения, указывающий на локальныйcore
подмодуль. - Ввести дополнительную зависимость:
studio
отcore
. Затем выполняетstudio
сборкуcore
, устанавливает путь включения для своей собственной копииcore
субмодуля, затем выполняет сборкуgraph
и находитсяnetwork
в режиме «зависимости».
Полученная структура папок выглядит следующим образом:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/ (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/ (empty folder, sub-modules not fetched)
Тем не менее, для этого требуется некоторое волшебство системы сборки (я уверен, что это можно сделать с помощью CMake) и небольшая ручная работа со стороны обновлений версий (обновление graph
может также потребовать обновления core
и network
получения совместимой версии core
во всех проектах) ,
Есть мысли по этому поводу?
источник
Ответы:
Я очень опаздываю на эту вечеринку, но на ваш вопрос все еще не дан полный ответ, и это довольно заметный хит от Google.
У меня точно такая же проблема с C ++ / CMake / Git / Submodules, и у меня есть аналогичная проблема с MATLAB / Git / Submodules, которая получает некоторые дополнительные странности, потому что MATLAB не компилируется. Я недавно наткнулся на это видео , которое, кажется, предлагает «решение». Мне не нравится решение, потому что оно по сути означает выбрасывание субмодулей, но оно устраняет проблему. Это так же, как @errordeveloper рекомендует. Каждый проект не имеет подмодулей. Чтобы построить проект, создайте супер-проект для его сборки и включите его в качестве родственного элемента в его зависимости.
Так что ваш проект для разработки
graph
может выглядеть так:и тогда ваш проект для студии может быть:
Суперпроекты - это просто основной
CMakeLists.txt
и куча подмодулей. Но ни в одном из проектов нет подмодулей.Единственная цена, которую я вижу в этом подходе, - это распространение тривиальных «суперпроектов», которые просто посвящены созданию ваших реальных проектов. И если кто-то завладеет одним из ваших проектов, нет простого способа узнать, не найдя и супер-проект, каковы его зависимости. Например, это может сделать его очень уродливым на Github.
источник
Я предполагаю, что когда вы интегрируете оба
graph
иnetwork
подмодули вstudio
, вы всегда должны иметь одну и ту же версиюcore
в данный момент в историиstudio
. Я бы связалstudio/libs/core
субмодуль сstudio/libs/{graph,network}/libs
.Обновить:
Я создал несколько репозиториев с указанными вами зависимостями:
v1
иv2
две разные версииcore
.graph
обрабатывает версию 2, в то время какnetwork
требует некоторой работы и застревает на версии 1. Вstudio
локальных встроенных версияхcore
обоих указываетv1
на наличие работающей программы. Теперь, кроме перспективы сборки, все хорошо работает с подмодулями.Теперь я могу удалить следующий каталог:
И замените его символической ссылкой:
Я локально фиксирую это изменение и теряю способность иметь две отдельные версии
core
внутриstudio
, но я строю толькоcore
один раз. Когдаv2
я буду готов к обновлению , я могу сделать:... внутри студии / библиотеки / сети.
источник
graph/libs/core
извне, вы не используете субмодуль. Если вы ссылаетесьstudio/libs/core
на одну из собственных библиотек субмодуля, то какую вы выбираете,graph
илиnetwork
? Кроме того, что происходит, когда его глубина составляет три или более слоев? Наконец, что, если,core
может быть диапазон изменений. Это не очевидно , что вы хотите , чтобы ссылка на любую версию ,core
чтоgraph
иnetwork
используете.core
будет подмодулем, извлеченным из исходнойcore
библиотеки, обновленным до версии, совместимой с обоимиgraph
иnetwork
(вы должны решить, какая из них хороша). Символические ссылки будут добавлены в локальныйgraph
иnetwork
субмодулей (не выбран).graph
и которыеnetwork
будут указывать за пределы своего собственного хранилища (например, где-то еще вstudio
проекте). Как они узнают, когда использовать свой собственный подмодуль, а когда использовать символическую ссылку? Возможно, вам следует добавить пример, чтобы продемонстрировать свое мышление.Я бы сгладил его, чтобы иметь глубину подмодуля всего один и иметь хранилище, в котором все модули содержались бы как подмодули, и ничего кроме README и сценариев сборки. Для каждого из пакетов, связывающих его зависимости, будет отдельный скрипт сборки. В противном случае вы можете иметь отдельный репо для пакета.
источник
Я бы не использовал подмодули.
Это заманчиво, как и в случае с svn-externals. Тем не менее, можете ли вы быть уверены, что все те проекты, на которые вы ссылаетесь, останутся на том же месте в течение года? Что насчет пяти?
Поэтому я просто копирую все необходимые зависимости в свой проект. Это означает, что пока мой репо действует, я могу проверить точное состояние.
По сути, у меня есть структура папок следующим образом:
Хотя это не очень хорошо с точки зрения дискового пространства, я ценю гарантию того, что я могу проверять каждое записанное состояние, пока репо доступно намного выше.
Кроме того, есть множество проблем с подмодулями, как описано здесь
источник
Столкнувшись с точно такой же проблемой здесь. Одним из решений может быть иметь некоторые репо ,
libs
которые будут держатьcore
,network
,graph
как подмодули и только CMakeLists , что бы сказать каждому из LIBS где найти его зависимости. Каждое приложение теперь будет иметьlibs
подмодуль и использовать только необходимые библиотеки.Тестирование каждой библиотеки может быть настроено двумя способами:
источник
graph
не нужно знать оnetwork
- не передавайтеnetwork
связанный материал вgraph
subdir