LINUX.ORG.RU

Вопрос по структуре проекта и автоматизации сборки


1

3

Выпало на мою долю намедни создать некую демо-версию embedded проекта, включающего в себя необходимость:

  • патчить и собирать U-Boot, а также загрузочные скрипты для него;
  • патчить и собирать linux kernel;
  • собирать свой модуль ядра;
  • собирать пачку своих юзер-спейс утилит для этой железки;
  • все это добро вместе со своими инит-скриптами и существующей 3rd-party фс запаковывать в рамдиск и
  • деплоить это добро на самой железке.

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

Первое, что пришло на ум - это хранить все сторонние исходники (kernel, u-boot), тулчейн и rootfs в отдельной расшаренной для всех директории. При сборке проекта - копировать, например, исходники ядра в директорию сборки, поверх него накладывать свои патчи и собирать. Артефакты в виде модулей, собранных утилит и прочих инитскриптов складывать в созданную для этой цели копию rootfs, которую потом запаковать. Так же поступать и с бутлоадером.

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

Кто имеет опыт работы в таких проектах? Как это делается по-взрослому? Может, я чего-то недопонимаю по поводу субрепозиториев? Или чего-то недопонимаю в принципе?



Последнее исправление: Corey (всего исправлений: 1)

если будут патчиться параллельно и сторонние исходники и ваши - вы потом запаритесь синхронизировать их меж собой: что с чем собирается, совместимость версий и т.д. лучше всё хранить в одном репозитории и иметь все сорцы, из которых собирается конечный продукт.
если это git, то можно попробовать submodule: https://www.kernel.org/pub/software/scm/git/docs/git-submodule.html
там есть жёсткая привязка к конкретной версии.

Iron_Bug ★★★★★
()

Я использую следующее:
contribs/ - все стороние пакеты
patches/ - мои изменения стороних пакетов
сборка осуществляется с использованием Makefile, механизм прошивки зависит от железа

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

если будут патчиться параллельно и сторонние исходники и ваши

Не, патчатся только сторонние исходники. А собираются и наши, и чужие + наши патчи. Но твоя правда, это будет неиссякаемый источник головной боли со сменой версий сторонних исходников.

Пока что это выглядело бы вот так:

.
├── contrib
│   └── kernel-source
│       ├── 3.0.35
│       └── 3.2.0
└── project
    └── src
        └── kernel
            ├── 3.0.35
            │   ├── modules
            │   └── patches
            └── 3.2.0
                ├── modules
                └── patches

Corey
() автор топика
Ответ на: комментарий от Corey

Но все это лежит в одном гит-репозитории?

Да.
Тут правда есть небольшое отступление - если часть внешних компонентов входят в состав SDK от производителя, то они там и остаются, а в документации указывается версия SDK и оно, SDK, сохраняется на внутреннем сервере.

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

У нас в качестве такого SDK выступает связка toolchain + kernel + rootfs + bootloader, поскольку все они сильно пропатчены вендором. Но нам нужно патчить их дальше под свои нужды.

Corey
() автор топика
Ответ на: комментарий от Corey

Вы не одиноки, поэтому patch-и на компоненты SDK я храню в проекте, а SDK вовне, так как оно может использоваться в нескольких проектах.

imb ★★
()

Мы делаем так

Git репозиторий со сборочными скриптами у которого субмодулями идут сторонние компоненты (ядро, rootfs, SDK и т.д.). Исходники импортированы из оригинальных тарников: git init, потом наши патчи. Таким образом крупные изменения (мажорные версии) можно в ветки выделять и история сохраняется кто что и зачем патчил. Диффы можно делать, что бывает очень полезно.

На пальцах процедура примерно такая: git init, распаковываем tar версии 1, комитим «imported foo-1.0», тегаем foo-1.0, дальше аккуратно патчим, комитим каждый по-отдельности. Вышла версия 2, возможны несовместимые изменения. Делаем бранч foo-2, откатываемся на «imported foo-1.0», удаляем все файлы (кроме .git), распаковываем foo-2.0.tar.gz, комитим «imported foo-2.0», тегаем foo-2.0, смотрим diff -t что они там понавертели, cherry-pick ещё актуальные патчи в эту ветку.

В «главном» проекте тоже можно сделать ветки, т.к. часто релизы sdk+rootfs+kernel идут вместе - чтоб удобней было переключаться.

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

Для автоматизации, вроде бы, есть специальные инструменты, всякие rootfs билдеры, в частности специально для embedded но мне лень было разбираться в своё время, использую собственные скрипты. Если кому-то надо могу почистить от проектно-специфичиеского и выложить на github, хотя там, наверное, не на что будет смотреть.

bzt
()
Ответ на: Мы делаем так от bzt

Спасибо за развернутое описание. Поковырявшись на этой неделе с системой сборки, описанной мной в первом посте, понял, что к чему-то такому и приду.

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

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

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