2 что такое система сборки
Перейти к содержимому

2 что такое система сборки

  • автор:

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

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

Прежде чем перейти непосредственно к техническим деталям следует отметить два важных момента. Во-первых, система работает поверх разработанной нами make-утилиты linmake, об особенностях которой будет рассказано отдельно. И, во-вторых, разработка велась для решения задач производства СУБД ЛИНТЕР (www.linter.ru), что привнесло определенную специфику, но не настолько существенную, чтобы решение не могло быть адаптировано к любому проекту.

Зачем нужно было создавать новую систему сборки?

  • из-за того, что в далеком 1999 году не было приемлемого кроссплатформенного инструмента мы были вынуждены долгое время поддерживать две параллельные системы сборки: на основе wmake для windows и make для *nix;
  • разнообразие поддерживаемых UNIX-like платформ привело к увеличению (а значит и усложнению) вариантов компиляции и компоновки в модулях проекта;
  • в свою очередь, сборка windows версии усложнялась необходимостью поддержки большого количества компиляторов;
  • не существовало простого механизма описания и разрешения как внешних и внутренних зависимостей проекта.
  • система должна однообразно работать на всех поддерживаемых платформах;
  • изменение положения модуля (здесь и далее под модулем мы будем понимать функционально самодостаточную часть проекта) в рабочем дереве не должно влиять на работоспособность;
  • необходим простой механизм по добавлению новых целевых платформ, архитектур, компиляторов и их версий;
  • следует хранить как типовые конфигурации для версий и редакций продукта, так и предоставлять возможность их настройки при необходимости;
  • нужен простой способ автоматического учета внешних и внутренних зависимостей в проекте, который бы автоматически определял порядок операций;
  • система должна предоставлять возможность простой сборки части проекта со всеми ее зависимостями.

Модель сборки, общие положения

  • конфигураций/версий продуктов (CONFIGS);
  • целевых платформ (PLATFORMS);
  • целевых архитектур (ARCHS);
  • компиляторов (COMPILERS);
  • версиями компиляторов ($(CMPL)_VERS);
  • платформой сборки (HOST.PLT);
  • архитектурой платформы сборки $(HOST.ARCH).

Комбинация перечисленных параметров определяет все возможные варианты, которые предварительно фильтруется системой сборки с целью отсеять ненужные и не имеющие смысла комбинации.
В свою очередь, каждый модуль расширяет параметры «для себя» с помощью двух файлов-описателей: для модуля и для процесса сборки, которые написаны в декларативном стиле и не содержат правил (за редким исключением). Описатель модуля содержит общую информацию о модуле: наименование и версии, поддерживаемые платформы, компиляторы и архитектуры, модели потоков, цели. Все объявления (кроме имени) не являются обязательными и в случае их отсутствия используются значения по умолчанию.

Вариант описателя модуля

Описатель сборки объявляет цели, их состав, директивы, директории поиска, внешние и внутренние зависимости модуля.

Вариант описателя сборки

В bldroot структура директорий повторяет srcroot до уровня корней каждого модуля (modsrc), но уже в них, содержатся все фактические варианты, задаваемые допустимыми комбинациями общепроектных и модульных конфигураций. Под каждый из таких вариантов создается директория вида $(MODULE)/$(PLT)_$(ARCH)_$(CMPL)$(CMPLV)_$(TYPE)_$(CFG) (например example/LINUX_AMD64_GCC4_MD_R_base60), будем именовать далее эти директории как modbld.

Вариант содержимого modsrc

Вариант содержимого modbld

  • сборка всего проекта/модуля впервые;
  • обновление модуля.


Иллюстрация 1: Сборка всего проекта (1) приводит к формированию последовательности вызовов корневого make-файла (3) для всех возможных комбинаций опций сборки (2). В результате фильтрации (3) отсеиваются заведомо непригодные варианты. Файлы описатели модулей, (4) исходя из зависимостей и дополнительных параметров корректируют варианты. Описатели сборки (5) выполняют правила (6) и формируют целевые директории с результатами исполнения (7).


Иллюстрация 2: Обновление существующих модулей (1) работает по упрощенной схеме: вспомогательные правила в modbld (3) обновляют (4) свои цели без использования описателя модуля и фильтров.

Как уже упоминалось выше, все правила вынесены в отдельный модуль (unimake) на уровне проекта, который, помимо заданий самих правил, отвечает за хранение дерева зависимостей между модулями. При этом, каждый модуль из объявленных порождает отдельную цель с генерируемыми зависимыми целями.

Хранение и использование зависимостей между модулями

Благодаря встроенному парсеру файлов размещения модулей linmodules имеется возможность отслеживает текущее положение модулей в дереве исходников и использовать простое определение пути.

Чтение и регистрация модулей и путей

Реализация

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

2 что такое система сборки

Что такое «система сборки» во встроенном домене?

Я работаю в области программирования на C, и кто-то спросил меня, какова система сборки моего проекта. Я работаю в STM32CubeIDE, используя | GNU Tools для STM32 | Набор инструментов . Мне не нужно было создавать Makefile для моего проекта, так как он автоматически генерируется IDE. Так что же такое build-system? Имеется в виду, как я строю проект?

Имеет ли изображение ниже какое-либо отношение к системе сборки?

enter image description here

Любая информация будет полезна. Спасибо.

2 ответа

Он спросил вас, как вы строите свой проект. Это make, cmake, VSbuild или что-то еще.

Возможно, вы используете autotools или другую систему генерации проектов.

Поскольку он установлен на «внешний компоновщик» и инструменты GNU, то, вероятно, make — хотя и не обязательно — IDE может реализовать собственное управление, а не явно генерировать и выполнять make-файл.

Если вы используете исключительно IDE для управления и генерации сборки для вас, тогда « STM32CubeIDE with GNU Tools », вероятно, также является разумным ответом, независимо от того, как он на самом деле его реализует. Знание того, какой инструмент он использует под капотом, полезно, например, если вам приходится собирать командную строку для непрерывной интеграции или автоматического выпуска.

Системы сборки

Многие гениальные вещи создаются из лени. Системы сборки облегчают жизнь разработчика.

Время чтения: меньше 5 мин

  1. Кратко
  2. Как понять
  3. Как пользоваться
  4. На практике
    1. Игорь Камышев

    Обновлено 1 декабря 2021

    Кратко

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

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

    Как понять

    Современные проекты могут быть огромными (100 тысяч строк или даже больше), писать такие объёмы кода в одном файле совершенно невозможно. К тому же, часто нужно использовать готовые библиотеки, которые написал кто-то другой. Но, к сожалению, браузеры не очень хорошо поддерживают проекты из многих файлов. Из-за этого были придуманы системы сборки (их ещё называют бандлерами или сборщиками).

    Как пользоваться

    Большинство бандлеров распространяются через npm. Чтобы начать ими пользоваться, достаточно добавить соответствующий пакет.

    Теперь нужно создать HTML-файл, в котором описать относительные пути до JavaScript-файлов, и запустить бандлер. Он сделает всю остальную работу.

    Рядом с этим файлом следует разместить JavaScript-файл:

    Теперь можно запустить бандлер и посмотреть на результат в браузере. Для этого нужно добавить новый скрипт в package . json :

    И запустить его:

    В браузере будет виден HTML, и исполнится JS. Важно заметить, что в JS-файлах теперь можно безболезненно импортировать любые другие файлы — и локальные, и установленные через npm модули. Бандлер найдёт все нужные файлы и упакует в один большой файл, который отправится в браузер.

    На практике

    Игорь Камышев

    Обычно бандлеры, кроме сборки кода, умеют применять к нему трансформации. Например, можно писать приложение на современном JavaScript, а бандлер превратит его в понятный для старых браузеров код. Чаще всего для этой задачи используется Babel. При работе с Parcel Babel включён по умолчанию, и чтобы его настроить, достаточно создать в корне проекта файл . browserslistrc и перечислить в нем поддерживаемые браузеры:

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

    Что такое «система сборки» во встроенном домене?

    Я работаю в области встроенного программирования на C, и кто-то спросил меня, какова система сборки моего проекта. Я работаю в STM32CubeIDE, используя | Инструменты GNU для STM32 | набор инструментов. Мне не нужно было создавать Makefile для моего проекта, так как он автоматически генерируется IDE. Так что же такое система сборки? Это относится к тому, как я строю проект?

    Имеет ли изображение ниже какое-либо отношение к системе сборки?

    введите описание изображения здесь

    Любая информация будет полезна. Спасибо.

    Поскольку он настроен на «внешний строитель» и инструменты GNU, то предположительно make — хотя и не обязательно — IDE может реализовать собственное управление, а не явно генерировать и выполнять make-файл.

    Если вы используете исключительно IDE для управления и создания сборки для вас, то « STM32CubeIDE с инструментами GNU », вероятно, также является разумным ответом, независимо от того, как он фактически ее реализует. Знание того, какой инструмент он использует под капотом, полезно, если вам нужно выполнять сборки из командной строки, например, для непрерывной интеграции или автоматического выпуска.

    Системы сборки для Java

    Я не совсем понимаю как работает Intellij Idea и как она собирает мою программу. Можно краткий инструктаж в системы сборки и для чего они нужны?
    Ещё бы хорошо, если была бы инфа неустаревшая.

    Dark Casual's user avatar

    TL;DR, к сожалению, не получилось.

    Система сборки – это программное обеспечение, обеспечивающее автоматизацию сборки проекта. Основное отличие от IDE в том, что конфигурационный файл для системы сборки вы описываете в текстовом виде. Как следствие, быстрее можете начать проект, за счет того, что что все типовые задачи заключаются в копировании уже готовых сниппетов. Это гораздо быстрее, более гибко, мобильно, и, главное, читаемо, чем вводить то же самое через UI диалоги IDE.

    Как в общих чертах работает ваша IDE:

    • Когда вы создаете проект, то IDE определяет некоторые source каталоги, в которых находятся исходные файлы вашего проекта. При запуске проекта эти файлы будут скомпилированы и переместятся в целевую директорию. Все это, как правило, легко меняется. Можно назначить дополнительные source каталоги, в которых IDE будет осуществлять поиск исходных файлов или поменять целевую директорию;
    • Если ваш проект использует библиотеки, то вы скачиваете их, складываете в определенную директорию, и подключаете их как зависимости вашего проекта. Таким образом IDE оповещается о том, что при запуске проекта, эти JAR-файлы будут находиться в classpath , она сама подставит их в ключ java –cp и начнет предоставлять типы и методы этих библиотек в автодополнении, и делать другие удобные вещи, для которых и предназначены IDE;
    • Проекту назначается соответствующая JDK, компилятор которой и будет компилировать классы;
    • Могут назначаться некоторые дополнительные опции, такие как переменные окружения, аргументы JVM и прочее;
    • IDE также может выполнять определенные задачи. Например, не только положить собранный проект в каталог сборки, или запустить его, но задеплоить его на удаленный сервер;

    Настройки проекта IDE сохраняет в своем внутреннем формате, и складывает в виде файлов, иногда и дополнительных каталогов в директории проекта. Вся эта логика работает через UI диалоги, которые зачастую не очевидны и плохо описаны.

    Очевидные недостатки, которые из этого следуют:

    • если в проекте несколько участников, они все должны использовать одну и ту же IDE и синхронизировать настройки при каждом изменении;
    • тыкать мышкой в кучу разных диалогов долго и неудобно;

    Кроме того, если проект большой, его нужно каким-то образом поделить на модули, а также объявить какой модуль от какого зависит. Машина разработчика — не единственное место где нужно запускать проект — нужны конфигурации проекта для запуска в разных средах: разработка и продакшн, как минимум. Перед сборкой проекта также необходимо запустить интеграционные и юнит- тесты (иногда очень много), чтобы убедиться в отсутствии багов.

    Первым для автоматизации этих задач появился Ant. Это аналог make-файла, а по сути набор скриптов (которые называются tasks). Ant – это пример императивного стиля описания сборки проекта. Вы описываете некое действие, например, скомпилировать файлы в директории проекта:

    .. потом , скопировать их рабочую директорию

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

    Удобно в Ant то, что вы имеете полный и наглядный контроль над сборкой проекта, а неудобно что вы описываете огромное количество очевидных задач, и по прежнему управляете зависимостями проекта вручную (существует возможность подключить Ivy для управления зависимостями).

    Если вы хотите именно пошагового понимания, что делает IDE за ширмой — соберите проект с помощью Ant.

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

    На смену Ant пришел Maven, который не такой гибкий, но значительно сокращает объем рутинной работы. Основные особенности:

    • Конфигурация Maven — это один файл pom.xml ;
    • Из коробки поддерживаются различные типы сборки: JAR, WAR, EAR;
    • Введена стандартная структура каталогов для проекта. Это сделано для того, чтобы по умолчанию вам не нужно было объяснять системе сборки, где лежат исходные файлы, ресурсы и куда их нужно переместить после компиляции;
    • Цикл сборки разбит на phases (фазы). Каждая фаза включает в себя определенный стандартный сценарий, который называется goal (цель) . Упрощенно, вы указываете до какой фазы нужно выполнить проект (например, только скомпилировать), и выполняется набор сценариев связанных указанной и предыдущими фазами build lifecycle. Дополнительные сценарии реализуются через плагины к Maven;
    • Поддерживается модульная архитектура проекта. Можно объявлять зависимости между модулями;
    • Поддерживаются профили. Это возможность, которая позволяется выполнять сборку проекта для различных окружений (машин) по-разному. Например, в профиле для разработки приложения определяются настройки и плагины, которых нет в профиле для продакшена, и наоборот. Т.е. можно, например, иметь разные настройки для подключения к базе данных для рабочей машины и сервера, где будет разворачиваться приложения. Или добавить профиль для развертывания среды окружения, который содержит только плагины и скрипты, которые подготовят ваше рабочее место при переезде с места на место. Название профиля передается как опция (ключ -P ) к сборке проекта;
    • Для централизованного хранения библиотек введен центральный репозиторий. Все популярные библиотеки публикуются и периодически обновляются в центральном репозитории. Каждая библиотека уникально идентифицируется по параметрам: groupId, artifactId, version. Вам не нужно скачивать зависимости и хранить их где-то вместе с проектом, они объявляются декларативно в теге dependency и скачиваются автоматически при сборке проекта.

    Maven выполняет автоматическое разрешение зависимостей (так называются библиотеки, от которых зависит ваше приложение). Таким образом, например, если библиотека A зависит от библиотеки C, и библиотека B зависит от библиотеки C, но эти C – разных версий, Maven автоматически включит в проект только последнюю версию C (иногда это минус, но все настаивается). Также просто, например, проверить не появились ли новые версии для библиотек, входящих в состав проекта:

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

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

    Для Maven есть огромное число полезных плагинов. Основной недостаток, которым ему обычно пеняют, вытекает из его преимуществ. Декларативный стиль описания задач не позволяет так же просто “подшаманить” в определенных случаях, как это делает Ant. Но и это обычно решается через через различные плагины. Например, задачм Ant можно запускать из Maven через antrun-plugin.

    Нужно отметить, что когда вы работаете с Maven проектом в IDE, настройки извлекаются именно из Maven. Например, через compiler-plugin проекту указывается версия JDK:

    Все IDE на сегодняшний момент хорошо хорошо работают с Maven — можно использовать любую. UI диалог IDE для запуска Maven проекта — это обертка, при желании вы можете работать в ним из командной строки.

    За Gradle не скажу, потому что игрался, но вплотную не использовал.

    Резюме: если вы учитесь или делаете тестовый проект без зависимостей на час — IDE нормальный вариант — хотя сейчас все туториалы тоже пишутся под Maven или Gradle. Для остального — система сборки.

    Обновление:

    Как вам правильно указал @Arsenicum, проект можно собрать и без участия IDE и систем сборки. JDK (Java Development Kit), которое необходимо для разработки, как раз и состоит из виртуальной Java машины (JRE) — это среда исполнения или рантайм, и Development Tools — это инструменты среды разработки.

    Development Tools — это набор, в основном, консольных утилит. Они находятся в директории $JAVA_HOME/bin . Полный список тут. Умение напрямую работать с утилитами из набора Basic Tools (особенно jar, java, javac, javadoc), несомненно поможет лучше ориентироваться в вопросах запуска и сборки Java приложений.

    Системы сборки

    Многие гениальные вещи создаются из лени. Системы сборки облегчают жизнь разработчика.

    Время чтения: меньше 5 мин

    1. Кратко
    2. Как понять
    3. Как пользоваться
    4. На практике
      1. Игорь Камышев советует

      Обновлено 1 декабря 2021

      Кратко

      Скопировать ссылку «Кратко» Скопировано

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

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

      Как понять

      Скопировать ссылку «Как понять» Скопировано

      Современные проекты могут быть огромными (100 тысяч строк или даже больше), писать такие объёмы кода в одном файле совершенно невозможно. К тому же, часто нужно использовать готовые библиотеки, которые написал кто-то другой. Но, к сожалению, браузеры не очень хорошо поддерживают проекты из многих файлов. Из-за этого были придуманы системы сборки (их ещё называют бандлерами или сборщиками).

      Как пользоваться

      Скопировать ссылку «Как пользоваться» Скопировано

      Большинство бандлеров распространяются через npm. Чтобы начать ими пользоваться, достаточно добавить соответствующий пакет.

      Теперь нужно создать HTML-файл, в котором описать относительные пути до JavaScript-файлов, и запустить бандлер. Он сделает всю остальную работу.

      Рядом с этим файлом следует разместить JavaScript-файл:

      Теперь можно запустить бандлер и посмотреть на результат в браузере. Для этого нужно добавить новый скрипт в package . json :

      И запустить его:

      В браузере будет виден HTML, и исполнится JS. Важно заметить, что в JS-файлах теперь можно безболезненно импортировать любые другие файлы — и локальные, и установленные через npm модули. Бандлер найдёт все нужные файлы и упакует в один большой файл, который отправится в браузер.

      На практике

      Скопировать ссылку «На практике» Скопировано

      Игорь Камышев советует

      Скопировать ссылку «Игорь Камышев советует» Скопировано

      Обычно бандлеры, кроме сборки кода, умеют применять к нему трансформации. Например, можно писать приложение на современном JavaScript, а бандлер превратит его в понятный для старых браузеров код. Чаще всего для этой задачи используется Babel. При работе с Parcel Babel включён по умолчанию, и чтобы его настроить, достаточно создать в корне проекта файл .browserslistrc и перечислить в нем поддерживаемые браузеры:

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

      2 что такое система сборки

      Система сборки должна быть доступна для всех программистов, а не только особых специалистов. Любой разработчик должен иметь воз% можность выполнить сборку, иначе он не сможет работать. Если систе% ма слишком сложна, она практически бесполезна. Ей должны быть присущи следующие свойства:

      Это означает, что новый разработчик, присоединившийся к коман% де, должен быстро разобраться в том, как собрать пакет. Пока он не освоит процедуру сборки, от него будет мало прока. Мне прихо% дилось работать в компаниях, где только посвященным дозволя% лось изучать и осуществлять процедуру сборки. Такая позиция не только непродуктивна, но и опасна – что произойдет, если по ка% ким%то причинам уйдут те, кто действительно умеет выполнять сборку кода?

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

      Установка системы сборки предполагает следующие действия:

      • Взять чистый ПК, на котором установлен свежий экземпляр ОС.

      • Установить все необходимые программы (компиляторы, транс% ляторы, система управления версиями, инсталляторы, а также патчи и пакеты обновления).

      • Установить все необходимые библиотеки (обратив внимание на правильность версий).

      • Создать нужную среду для осуществления сборки (для этого мо% жет потребоваться организовать деревья каталогов, установить переменные окружения, получить необходимые лицензии и т. п.).

      Без четких инструкций по установке нельзя быть уверенным в ста% бильности и возобновляемости процедуры сборки.

      Лучше всего применять стандартные, хорошо знакомые инструмен% ты сборки – такие, которые привычны разработчикам и не требуют

      Глава 10. Код, который построил Джек

      значительных усилий в освоении. Сложные инструменты, в кото% рых никто толком не разбирается, вызывают беспокойство. 1

      Единообразие

      Важно, чтобы все пользовались одной и той же системой сборки. В про% тивном случае вы будете собирать разные пакеты. С виду разные меха% низмы сборки могут показаться эквивалентными ( Я работаю в своей IDE, а он пользуется make#файлами ) , но в таком случае затрудняется сопровождение и возникает опасность ошибок. Могут незаметно вкра% сться мелкие различия, например разные опции компиляторов, и ис% полняемые модули не будут одинаковыми.

      Это согласуется с требованием хранить систему сборки рядом с дере% вом исходного кода. Если система сборки физически становится ча% стью кода, то ее невозможно обойти или избежать.

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

      Кажется, все совершенно очевидно, но наделать ошибок очень легко. Даже если вы все пользуетесь одними и теми же make%файлами, вы можете не обратить внимания на другие различия – несоответствие версий библиотек, инструментов или сценариев сборки может привес% ти к тому, что в итоге будут собираться разные программы.

      Повторяемость и надежность

      Сборка должна быть детерминированной и надежной. Набор исход% ных файлов должен легко определяться перед сборкой. Две сборки, проведенные с одним и тем же набором файлов, должны дать совер% шенно одинаковые исполняемые модули – сборка должна быть повто# ряемой .

      Правильная система сборки позволяет многократно создавать физически идентичные бинарные файлы.

      Тогда вы сможете пометить этот набор исходных файлов в системе контроля версий как определенную версию своего продукта (либо сде% лать резервную копию этих файлов) и в любой момент в будущем вы% полнить идентичную сборку.

      Это очень важно: один из ваших клиентов может обнаружить сущест% венную ошибку в старой версии программы, и если вы не сможете най% ти ту версию и собрать точно такую же программу, как у клиента, то

      1 Я испытываю органическое недоверие ко всем средствам, более сложным, чем GNU Make, но это может характеризовать скорее меня, чем эти слож% ные средства. Мне вполне достаточно того, что дает GNU Make!

      Что должна уметь хорошая система сборки?

      не сможете воспроизвести аварийную ситуацию, а тем более исправить ошибку.

      Вы должны быть в состоянии достать дерево исходных файлов трехлетней давности и правильно собрать его заново.

      Если процедура сборки выдает двоичный файл, который не удается со% брать повторно, это должно насторожить. Когда результат сборки за% висит от фазы луны, есть над чем призадуматься. В этой связи необос% нованное применение __DATE__ в C или какой%то иной информации в ис% ходных файлах, подверженной изменениям, следует свести к абсолют% ному минимуму.

      Сборка всегда должна действовать идеально – она должна быть надеж# ной . Если она иногда завершается аварией или генерирует неработо% способный двоичный файл, это просто опасно. В таком случае у вас не может быть уверенности, что вы тестируете правильный исполняемый модуль и что ваша фирма выпускает работающий продукт. Проблемы сборки существенно осложняют разработку.

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

      Атомарность

      Идеальная система сборки должна принять исходные файлы без ка% кой%либо правки и скомпилировать их все без какого%либо вмешатель% ства с вашей стороны. Никаких специальных действий перед сборкой не должно быть. Недопустимо, чтобы посреди сборки вам приходилось запускать какое%то другое приложение и проталкивать файл. Сборка должна запускаться одной командой. В результате вам не придется ни% чего дополнительно держать в голове, рискуя позабыть это в один пре% красный день. Все тайны сборки должны быть сохранены в надежном месте – ее скрипте. Сборка всегда может быть повторена. Она надежна.

      Правильная сборка выглядит как одна операция. Достаточно нажать кноп& ку или набрать одну команду.

      Если такой идеал для вас недостижим (в силу веских причин), то все равно постарайтесь сократить количество ручных операций. Все руч% ные операции должны быть полностью документированными. Допус% тимо (и даже желательно) разбить процедуру на следующие этапы:

      1. Получение чистого исходного кода.

      3. Создание дистрибутива из результатов.

      Обратите внимание на разделение сборки кода и получения исходных файлов; можно сделать так, чтобы одна и та же команда сборки созда%

      Глава 10. Код, который построил Джек

      Рассказы бывалого человека

      Повторяемость сборки имеет важное значение; вы должны быть в состоянии воссоздать любую выпущенную версию вашего про% дукта. Иначе у вас могут возникнуть неприятности. Мне дове% лось работать в компании, где возникла именно такая проблема.

      Разработчики сделали изменения в коде установленной у клиен% та программы, но не перенесли их в свой экземпляр кода в систе% ме контроля версий. Таким образом, у клиента оказалась «не% официальная» версия продукта. Когда позднее клиент обнару% жил критическую ошибку, программисты не смогли воспроизве% сти ее у себя. При этом никто не мог понять причин, потому что о сделанной ранее правке экземпляра клиента к тому времени все уже позабыли.

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

      вала разные версии продукта в зависимости от того, какой исходный код будет выбран. Упаковка программы также выделена в отдельный этап; во время разработки не всегда стоит тратить время на создание полного инсталляционного пакета.

      Борьба с ошибками

      В конце разработки, когда осядет пыль вокруг готового кода, ошибок при сборке не будет . Но в процессе работы что%то будет не получаться постоянно. Система сборки должна уметь справляться с ошибками и оказывать вам помощь.

      • Если возникла ошибка, система сборки не должна продолжать ра% боту. Она должна остановиться и сообщить вам все данные о том, что сломалось и где. Если сборка будет продолжена, наверняка поя% вятся другие проблемы как следствие первой пропущенной ошиб% ки. Разобраться с ними будет очень трудно. В ваших интересах не нарушать этого правила.

      • При ошибке во время сборки система должна удалить все незавер% шенные объекты. Иначе при следующем запуске сборки она решит, что эти файлы целые, и возьмет их в работу. В результате потом мо%

      10 советов и подсказок Cmake

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

      Например, Makefile — это система сборки, которая используется в качестве инструмента командной строки make или файла проекта для интегрированной среды разработки (IDE). Чтобы избежать поддержки нескольких таких систем сборки, проект может указать свою систему сборки абстрактно, используя файлы, написанные на языке CMake.

      Этапы сборки

      Вся сборка CMake состоит из следующих этапов:

      1. Настройка: CMake выполняет сам код CMake для создания конфигурации сборки.
      2. Создание: CMake создает конкретную систему сборки (например, GNU Makefiles или решение Visual Studio с соответствующими файлами проекта) из конфигурации.
      3. Компиляция: примените сгенерированную систему сборки, чтобы окончательно скомпилировать и связать исходники. Обычно сам CMake не участвует в этом этапе, но сгенерированная система сборки проверяет, не был ли изменен какой-либо соответствующий код CMake, и при необходимости запускает другой запуск конфигурации CMake.
      СОВЕТЫ И ХИТРОСТИ
      1. add_subdirectory: Согласно документации, add_subdirectory следует использовать только для подкаталогов текущего каталога CMakeLists. Но с особыми соображениями вы можете применить его к источникам за пределами текущего каталога, см. Здесь для рассмотрения. Внимание: add_subdirectory ведет себя с точки зрения области действия точно так же, как макрос. Поэтому обратите внимание на то, какие переменные вызывающих CMakeLists могут быть изменены добавленными CMakeLists.
      2. aux_source_directory: aux_source_directory добавляет найденные исходные файлы в список в переданной переменной. Исходные файлы, уже находящиеся в списке переменных, остаются нетронутыми. Это следует учитывать, в частности, если вы добавляете еще один CMakeList с add_subdirectory, который использует ту же переменную в своих вызовах aux_source_directory. В этом случае переменная аккумулирует все исходные файлы, поскольку add_subdirectory не имеет собственной области видимости. Кроме того, обратите внимание, что aux_source_directory не добавляет файлы заголовков. Это может быть проблемой, например, если вы хотите применить qt5_wrap_cpp для вызова moc для файлов заголовков. В качестве обходного пути используйте file(GLOB_RECURSE … для прямого поиска файлов заголовков.
      3. Вызов функции или макроса с произвольным количеством аргументов: Можно вызвать функцию или макрос с произвольным количеством аргументов, которые передаются в виде списка с помощью предопределенных переменных $ или $. $ содержит все аргументы в виде списка, а $ содержит только аргументы, не назначенные именованному параметру.
      4. Выберите архитектуру (x86orx64) для сборки Visual Studio: если вы вызываете cmake без каких-либо дополнительных параметров в Windows с установленной Visual Studio 2010 (например), он создает файлы проекта для 32-разрядной сборки (x86).

      Чтобы создать 64-битные исполняемые файлы, установите соответствующую опцию -G:

      Начиная с CMake 3.13 существует альтернативный и предпочтительный вариант -A для выбора архитектуры платформы:

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

      5. Команда if не работает. Команда if для определения необходимости создания системы сборки Visual Studio (if(MSVC)) не сработала должным образом. Оказалось, что для правильной работы требуется предварительная команда проекта. Таким образом, команда проекта должна располагаться перед любыми командами включения (но после команды cmake_minimum_required).

      6. Прервите выполнение CMake из-за ошибки: CMake не поставляется с командой выхода для прекращения выполнения CMake после фатальной ошибки. Чтобы завершить сообщение вызова запуска CMake (FATAL_ERROR «…») с соответствующим сообщением. Это завершает выполнение CMake с четко выделенным сообщением в консоли.

      7. Добавьте общую опцию в CMakeGUI: Команда option позволяет добавить логическую опцию в CMake GUI, но не опцию с произвольным значением. Добавление небулевой опции выполняется с помощью команды set с ее флагом CACHE, как описано в разделе Set Cache Entry на странице set docs. Помимо общих строк, такой опцией может быть тип каталога (PATH) или файла (FILEPATH). В таких случаях графический интерфейс CMake предлагает диалоговое окно выбора каталога/файла. Также можно предложить выбор возможных строковых значений на выбор.

      8. Советы по отладке: Linux с GNU Makefiles:

      Глобальная команда очистки вызывает полную перестройку. Если вы хотите перестроить только подкаталог, перейдите в соответствующую подпапку в папке сборки и выполните там make clean или просто удалите эту подпапку папки сборки. Передача VERBOSE=1 вызову make приводит к тому, что make выводит все вызовы компилятора и компоновщика.

      9. Защита от включения: защита от включения предотвращает многократное выполнение включенного файла, если файл включен в нескольких местах. CMake 3.10 и новее предоставляют для этого команду include_guard. В случае более старого CMake помогает следующий прием. Цели определены глобально. Если включенный файл определяет цель с именем MyTarget, поместите следующий код вверху:

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

      10. CMake и VisualStudio: смотрите здесь для сопоставления терминов Visual Studio с терминами CMake.

      Использованная литература:

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

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

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

      Прежде чем перейти непосредственно к техническим деталям следует отметить два важных момента. Во-первых, система работает поверх разработанной нами make-утилиты linmake, об особенностях которой будет рассказано отдельно. И, во-вторых, разработка велась для решения задач производства СУБД ЛИНТЕР (www.linter.ru), что привнесло определенную специфику, но не настолько существенную, чтобы решение не могло быть адаптировано к любому проекту.

      Зачем нужно было создавать новую систему сборки?

      • из-за того, что в далеком 1999 году не было приемлемого кроссплатформенного инструмента мы были вынуждены долгое время поддерживать две параллельные системы сборки: на основе wmake для windows и make для *nix;
      • разнообразие поддерживаемых UNIX-like платформ привело к увеличению (а значит и усложнению) вариантов компиляции и компоновки в модулях проекта;
      • в свою очередь, сборка windows версии усложнялась необходимостью поддержки большого количества компиляторов;
      • не существовало простого механизма описания и разрешения как внешних и внутренних зависимостей проекта.
      • система должна однообразно работать на всех поддерживаемых платформах;
      • изменение положения модуля (здесь и далее под модулем мы будем понимать функционально самодостаточную часть проекта) в рабочем дереве не должно влиять на работоспособность;
      • необходим простой механизм по добавлению новых целевых платформ, архитектур, компиляторов и их версий;
      • следует хранить как типовые конфигурации для версий и редакций продукта, так и предоставлять возможность их настройки при необходимости;
      • нужен простой способ автоматического учета внешних и внутренних зависимостей в проекте, который бы автоматически определял порядок операций;
      • система должна предоставлять возможность простой сборки части проекта со всеми ее зависимостями.

      Модель сборки, общие положения

      • конфигураций/версий продуктов (CONFIGS);
      • целевых платформ (PLATFORMS);
      • целевых архитектур (ARCHS);
      • компиляторов (COMPILERS);
      • версиями компиляторов ($(CMPL)_VERS);
      • платформой сборки (HOST.PLT);
      • архитектурой платформы сборки $(HOST.ARCH).

      Комбинация перечисленных параметров определяет все возможные варианты, которые предварительно фильтруется системой сборки с целью отсеять ненужные и не имеющие смысла комбинации.
      В свою очередь, каждый модуль расширяет параметры «для себя» с помощью двух файлов-описателей: для модуля и для процесса сборки, которые написаны в декларативном стиле и не содержат правил (за редким исключением). Описатель модуля содержит общую информацию о модуле: наименование и версии, поддерживаемые платформы, компиляторы и архитектуры, модели потоков, цели. Все объявления (кроме имени) не являются обязательными и в случае их отсутствия используются значения по умолчанию.

      Вариант описателя модуля

      Описатель сборки объявляет цели, их состав, директивы, директории поиска, внешние и внутренние зависимости модуля.

      Вариант описателя сборки

      В bldroot структура директорий повторяет srcroot до уровня корней каждого модуля (modsrc), но уже в них, содержатся все фактические варианты, задаваемые допустимыми комбинациями общепроектных и модульных конфигураций. Под каждый из таких вариантов создается директория вида $(MODULE)/$(PLT)_$(ARCH)_$(CMPL)$(CMPLV)_$(TYPE)_$(CFG) (например example/LINUX_AMD64_GCC4_MD_R_base60), будем именовать далее эти директории как modbld.

      Вариант содержимого modsrc

      Вариант содержимого modbld

      • сборка всего проекта/модуля впервые;
      • обновление модуля.


      Иллюстрация 1: Сборка всего проекта (1) приводит к формированию последовательности вызовов корневого make-файла (3) для всех возможных комбинаций опций сборки (2). В результате фильтрации (3) отсеиваются заведомо непригодные варианты. Файлы описатели модулей, (4) исходя из зависимостей и дополнительных параметров корректируют варианты. Описатели сборки (5) выполняют правила (6) и формируют целевые директории с результатами исполнения (7).


      Иллюстрация 2: Обновление существующих модулей (1) работает по упрощенной схеме: вспомогательные правила в modbld (3) обновляют (4) свои цели без использования описателя модуля и фильтров.

      Как уже упоминалось выше, все правила вынесены в отдельный модуль (unimake) на уровне проекта, который, помимо заданий самих правил, отвечает за хранение дерева зависимостей между модулями. При этом, каждый модуль из объявленных порождает отдельную цель с генерируемыми зависимыми целями.

      Хранение и использование зависимостей между модулями

      Благодаря встроенному парсеру файлов размещения модулей linmodules имеется возможность отслеживает текущее положение модулей в дереве исходников и использовать простое определение пути.

      Чтение и регистрация модулей и путей

      Реализация

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

      C++
      Системы сборки

      В настоящее время нет универсальной или доминирующей системы сборки для C ++, которая является популярной и кросс-платформенной. Тем не менее, существует несколько крупных систем построения, которые привязаны к основным платформам / проектам, наиболее заметным из которых является GNU Make с операционной системой GNU / Linux и NMAKE с системой Visual C ++ / Visual Studio.

      Кроме того, некоторые интегрированные среды разработки (IDE) также включают специализированные системы сборки, которые будут использоваться специально с родной средой IDE. Некоторые генераторы системы сборки могут генерировать эти собственные форматы IDE / форматы проекта, такие как CMake для Eclipse и Microsoft Visual Studio 2012.

      Создание среды сборки с помощью CMake

      CMake создает среду сборки практически для любого компилятора или IDE из одного определения проекта. В следующих примерах показано, как добавить файл CMake в кросс-платформенный код «Hello World» C ++ .

      Файлы CMake всегда называются «CMakeLists.txt» и должны уже существовать в корневом каталоге каждого проекта (и, возможно, в подкаталогах тоже). Основной файл CMakeLists.txt выглядит так:

      Этот файл сообщает CMake имя проекта, какую версию файла ожидать и инструкции для создания исполняемого файла под названием «HelloWorld», для которого требуется main.cpp .

      Создайте среду сборки для вашего установленного компилятора / IDE из командной строки:

      Создайте приложение с помощью:

      Это создает среду сборки по умолчанию для системы, в зависимости от ОС и установленных инструментов. Держите исходный код в чистоте от любых артефактов сборки с использованием «внекорпоративных» сборников:

      CMake также может абстрагировать основные команды платформы оболочки из предыдущего примера:

      CMake включает в себя генераторы для ряда общих инструментов сборки и IDE. Чтобы создать make — nmake для nmake Visual Studio :

      Компиляция с GNU make

      Вступление

      GNU Make (стиль make ) — это программа, предназначенная для автоматизации выполнения команд оболочки. GNU Make — это одна конкретная программа, которая подпадает под семейство Make. Они остаются популярными среди Unix-подобных и POSIX-подобных операционных систем, в том числе производных от ядра Linux, Mac OS X и BSD.

      GNU Make особенно примечателен тем, что он подключен к проекту GNU, который подключен к популярной операционной системе GNU / Linux. GNU Make также имеет совместимые версии, работающие на разных вариантах Windows и Mac OS X. Это также очень стабильная версия с историческим значением, которое остается популярным. Именно по этим причинам GNU Make часто учат вместе с C и C ++.

      Основные правила

      Чтобы скомпилировать с make, создайте Makefile в каталоге проекта. Ваш Makefile может быть таким же простым, как:

      Makefile

      ПРИМЕЧАНИЕ. Убедитесь, что отступы имеют вкладку, а не четыре пробела. В противном случае вы получите сообщение об ошибке Makefile:10: *** missing separator. Stop.

      Чтобы запустить это из командной строки, выполните следующие действия:

      Инкрементальные сборки

      Когда вы начинаете иметь больше файлов, make становится более полезным. Что делать, если вы отредактировали файл a.cpp, но не b.cpp ? Перекомпиляция b.cpp займет больше времени.

      Со следующей структурой каталогов:

      Это будет хороший Makefile:

      Makefile

      Снова посмотрите вкладки. Этот новый Makefile гарантирует, что вы только перекомпилируете измененные файлы, минимизируя время компиляции.

      Документация

      Строительство с помощью SCons

      Вы можете построить кросс-платформенный код «Hello World» C ++ , используя инструмент разработки программного обеспечения Scons — A Python- language.

      Сначала создайте файл SConstruct (обратите внимание, что SCons будет искать файл с этим точным именем по умолчанию). На данный момент файл должен находиться в каталоге прямо по вашему hello.cpp . Напишите в новом файле строку

      Теперь, с терминала, запустите scons . Вы должны увидеть что-то вроде

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

      Классы Environment и Glob помогут вам настроить конфигурацию. Например, файл SConstruct

      создает исполняемый hello , используя все файлы cpp в src . Его CPPPATH — это /usr/include/boost и он указывает стандарт C ++ 11.

      Ниндзя

      Вступление

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

      Ninja в основном написан на C ++ и Python и был создан как альтернатива системе сборки SCons для проекта Chromium.

      NMAKE (Утилита технического обслуживания Microsoft)

      Вступление

      NMAKE — это утилита командной строки, разработанная Microsoft для использования в основном в сочетании с инструментами командной строки Microsoft Visual Studio и / или Visual C ++.

      NMAKE — это система сборки, которая подпадает под семейство систем сборки, но имеет определенные отличительные особенности, которые отличаются от Unix-подобных программ Make, таких как поддержка синтаксиса пути к файлу Windows (который сам по себе отличается от путей файлов в стиле Unix).

      Autotools (GNU)

      Вступление

      Autotools — это группа программ, которые создают GNU Build System для данного программного пакета. Это набор инструментов, которые работают вместе для создания различных ресурсов сборки, таких как Makefile (для использования с GNU Make). Таким образом, Autotools можно считать генератором системы де-факто.

      Некоторые известные программы Autotools включают в себя:

      • Autoconf
      • Automake (не путать с make )

      В общем, Autotools предназначен для создания Unix-совместимого скрипта и Makefile, чтобы позволить следующей команде создавать (а также устанавливать) большинство пакетов (в простом случае):

      Таким образом, Autotools также имеет отношение к определенным менеджерам пакетов, особенно к тем, которые подключены к операционным системам, которые соответствуют стандарту POSIX.

      Системы сборки

      Многие гениальные вещи создаются из лени. Системы сборки облегчают жизнь разработчика.

      Время чтения: меньше 5 мин

      1. Кратко
      2. Как понять
      3. Как пользоваться
      4. На практике
        1. Игорь Камышев советует

        Обновлено 1 декабря 2021

        Кратко

        Скопировать ссылку «Кратко» Скопировано

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

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

        Как понять

        Скопировать ссылку «Как понять» Скопировано

        Современные проекты могут быть огромными (100 тысяч строк или даже больше), писать такие объёмы кода в одном файле совершенно невозможно. К тому же, часто нужно использовать готовые библиотеки, которые написал кто-то другой. Но, к сожалению, браузеры не очень хорошо поддерживают проекты из многих файлов. Из-за этого были придуманы системы сборки (их ещё называют бандлерами или сборщиками).

        Как пользоваться

        Скопировать ссылку «Как пользоваться» Скопировано

        Большинство бандлеров распространяются через npm. Чтобы начать ими пользоваться, достаточно добавить соответствующий пакет.

        Теперь нужно создать HTML-файл, в котором описать относительные пути до JavaScript-файлов, и запустить бандлер. Он сделает всю остальную работу.

        Рядом с этим файлом следует разместить JavaScript-файл:

        Теперь можно запустить бандлер и посмотреть на результат в браузере. Для этого нужно добавить новый скрипт в package . json :

        И запустить его:

        В браузере будет виден HTML, и исполнится JS. Важно заметить, что в JS-файлах теперь можно безболезненно импортировать любые другие файлы — и локальные, и установленные через npm модули. Бандлер найдёт все нужные файлы и упакует в один большой файл, который отправится в браузер.

        На практике

        Скопировать ссылку «На практике» Скопировано

        Игорь Камышев советует

        Скопировать ссылку «Игорь Камышев советует» Скопировано

        Обычно бандлеры, кроме сборки кода, умеют применять к нему трансформации. Например, можно писать приложение на современном JavaScript, а бандлер превратит его в понятный для старых браузеров код. Чаще всего для этой задачи используется Babel. При работе с Parcel Babel включён по умолчанию, и чтобы его настроить, достаточно создать в корне проекта файл .browserslistrc и перечислить в нем поддерживаемые браузеры:

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

        Системы сборки на Java

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

        Зачем нужна система сборки

        Когда компьютеры только начинали свое существование, системы сборки не были нужны, программы писались под определенные ЭВМ. С развитием индустрии серверы для разработки отделились от промышленных(“продакшен”) серверов, на которых разработанные приложения должны были использоваться.

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

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

        Какие бывают системы сборки

        Система сборки — это скриптовый код, написанный обычно на определенном языке программирования. Следовательно, для каждого языка они разные. Большинство основаны на самом первом сборщике — Linux-утилите make. Она использует специальные make-файлы, в которых подробно расписаны зависимости файлов друг от друга и порядок их сборки. Этот подход появился еще в 1976 и использовался всеми языками программирования, в том числе Java до разработки собственного средства.

        Давайте узнаем подробнее о сборщиках Java.

        Первым из них был Apache Ant (Another neat tool). По схеме работы очень похож на утилиту make, но вместо make-файла, состоящего из команд Bash, использует файл формата XML. Вот пример build.xml файла для простого проекта “Hello World”.


        Фазы сборки называются целями (<target>). В этом файле их 4: clean, compile, jar и run. Например, при вызове


        Сначала отработает clean, который удалит каталог «classes». После этого compile заново создаст каталог, который скомпилируется в папку src, все как определил разработчик. И вообще, поскольку Ant не навязывает никаких соглашений о структуре проекта, программисты сами пишут все команды и определяют порядок сборки.

        Что не так?

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

        Что привело к появлению новой системы

        Apache Maven

        Хоть он также использует XML для построения конфигурации (файл называется POM.xml), но имеет серьезные отличия:

        1. Здесь есть четкая структура каталогов, и вы обязательно должны ей следовать. (При использовании плагинов IDE, она создается автоматически).Она выглядит вот так:


        И если вы, к примеру, поместите файл с тестами в папку с ресурсами, то ваше приложение просто не скомпилируется.

        Также у каждого проекта может быть только один файл JAR файл, тогда как при сборке Ant модификации были безграничны: вы вообще можете добавить файл в какую угодно папку, собрать 5 классов в 3 JAR-а и так далее. Все это, безусловно, ухудшало поддерживаемость кода.

        2. Автоматическое управление зависимостями

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


        3. Стандартизированные названия билдов

        Каждый билд имеет атрибуты groupId, artifactId и version. Первые два уникальны и используются для определения в репозитории. Обычно groupId — доменное имя организации, а artifactId — название текущего проекта. Поэтому эта пара и является определяющей: нет двух компаний с одинаковым доменом, как и не существует двух одинаковых проектах в одной компании.

        4. Жизненный цикл и плагины

        Жизненный цикл maven-проекта — это список фаз, определяющий порядок действий при его построении. Он содержит три независимых порядка выполнения: clean, default и site.

        Для расширения и модификации стандартных ЖЦ используются плагины. Ниже представлен пример плагина, который копирует зависимости в ваше директорию.


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

        Gradle

        Оба, и Ant, и Maven используют XML для конфигурирования сборки. Gradle — предметно-ориентированный язык на основе Groovy. И это его основное отличие от Maven. В остальном Gradle руководствуется теми же принципами. Здесь за выполнение всей работы также ответственны плагины и нет широкой свободы действий.

        Приведем пример файла build.gradle для того же проекта с HelloWorld


        Gradle распространен в мобильной Android- разработке, а Maven используется в системах управления предприятиями. Почему так? Вопрос остается открытым. Возможно, так просто сложилось. Но Maven все-таки гораздо популярнее на рынке и будет полезен Java-разработчикам в любом случае.

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

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

        Прежде чем перейти непосредственно к техническим деталям следует отметить два важных момента. Во-первых, система работает поверх разработанной нами make-утилиты linmake, об особенностях которой будет рассказано отдельно. И, во-вторых, разработка велась для решения задач производства СУБД ЛИНТЕР (www.linter.ru), что привнесло определенную специфику, но не настолько существенную, чтобы решение не могло быть адаптировано к любому проекту.

        Зачем нужно было создавать новую систему сборки?

        • из-за того, что в далеком 1999 году не было приемлемого кроссплатформенного инструмента мы были вынуждены долгое время поддерживать две параллельные системы сборки: на основе wmake для windows и make для *nix;
        • разнообразие поддерживаемых UNIX-like платформ привело к увеличению (а значит и усложнению) вариантов компиляции и компоновки в модулях проекта;
        • в свою очередь, сборка windows версии усложнялась необходимостью поддержки большого количества компиляторов;
        • не существовало простого механизма описания и разрешения как внешних и внутренних зависимостей проекта.
        • система должна однообразно работать на всех поддерживаемых платформах;
        • изменение положения модуля (здесь и далее под модулем мы будем понимать функционально самодостаточную часть проекта) в рабочем дереве не должно влиять на работоспособность;
        • необходим простой механизм по добавлению новых целевых платформ, архитектур, компиляторов и их версий;
        • следует хранить как типовые конфигурации для версий и редакций продукта, так и предоставлять возможность их настройки при необходимости;
        • нужен простой способ автоматического учета внешних и внутренних зависимостей в проекте, который бы автоматически определял порядок операций;
        • система должна предоставлять возможность простой сборки части проекта со всеми ее зависимостями.

        Модель сборки, общие положения

        • конфигураций/версий продуктов (CONFIGS);
        • целевых платформ (PLATFORMS);
        • целевых архитектур (ARCHS);
        • компиляторов (COMPILERS);
        • версиями компиляторов ($(CMPL)_VERS);
        • платформой сборки (HOST.PLT);
        • архитектурой платформы сборки $(HOST.ARCH).

        Комбинация перечисленных параметров определяет все возможные варианты, которые предварительно фильтруется системой сборки с целью отсеять ненужные и не имеющие смысла комбинации.
        В свою очередь, каждый модуль расширяет параметры «для себя» с помощью двух файлов-описателей: для модуля и для процесса сборки, которые написаны в декларативном стиле и не содержат правил (за редким исключением). Описатель модуля содержит общую информацию о модуле: наименование и версии, поддерживаемые платформы, компиляторы и архитектуры, модели потоков, цели. Все объявления (кроме имени) не являются обязательными и в случае их отсутствия используются значения по умолчанию.

        Вариант описателя модуля

        Описатель сборки объявляет цели, их состав, директивы, директории поиска, внешние и внутренние зависимости модуля.

        Вариант описателя сборки

        В bldroot структура директорий повторяет srcroot до уровня корней каждого модуля (modsrc), но уже в них, содержатся все фактические варианты, задаваемые допустимыми комбинациями общепроектных и модульных конфигураций. Под каждый из таких вариантов создается директория вида $(MODULE)/$(PLT)_$(ARCH)_$(CMPL)$(CMPLV)_$(TYPE)_$(CFG) (например example/LINUX_AMD64_GCC4_MD_R_base60), будем именовать далее эти директории как modbld.

        Вариант содержимого modsrc

        Вариант содержимого modbld

        • сборка всего проекта/модуля впервые;
        • обновление модуля.


        Иллюстрация 1: Сборка всего проекта (1) приводит к формированию последовательности вызовов корневого make-файла (3) для всех возможных комбинаций опций сборки (2). В результате фильтрации (3) отсеиваются заведомо непригодные варианты. Файлы описатели модулей, (4) исходя из зависимостей и дополнительных параметров корректируют варианты. Описатели сборки (5) выполняют правила (6) и формируют целевые директории с результатами исполнения (7).


        Иллюстрация 2: Обновление существующих модулей (1) работает по упрощенной схеме: вспомогательные правила в modbld (3) обновляют (4) свои цели без использования описателя модуля и фильтров.

        Как уже упоминалось выше, все правила вынесены в отдельный модуль (unimake) на уровне проекта, который, помимо заданий самих правил, отвечает за хранение дерева зависимостей между модулями. При этом, каждый модуль из объявленных порождает отдельную цель с генерируемыми зависимыми целями.

        Хранение и использование зависимостей между модулями

        Благодаря встроенному парсеру файлов размещения модулей linmodules имеется возможность отслеживает текущее положение модулей в дереве исходников и использовать простое определение пути.

        Чтение и регистрация модулей и путей

        Реализация

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *